From 61c5682b06fb3739a9f980700e6602ae0f39d5a2 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Wed, 18 Nov 2020 18:54:13 +0800 Subject: Lowercase package names. --- .../infinityforreddit/API/DownloadFile.java | 13 - .../infinityforreddit/API/GfycatAPI.java | 10 - .../infinityforreddit/API/ImgurAPI.java | 18 - .../infinityforreddit/API/PushshiftAPI.java | 13 - .../infinityforreddit/API/RedditAPI.java | 339 -- .../AccessTokenAuthenticator.java | 6 +- .../infinityforreddit/Account/Account.java | 76 - .../infinityforreddit/Account/AccountDao.java | 55 - .../Account/AccountRepository.java | 48 - .../Account/AccountViewModel.java | 58 - .../Activity/AccountPostsActivity.java | 314 -- .../Activity/AccountSavedThingActivity.java | 440 --- .../infinityforreddit/Activity/BaseActivity.java | 326 -- .../Activity/CommentActivity.java | 433 --- .../Activity/CreateMultiRedditActivity.java | 241 -- .../Activity/CustomThemeListingActivity.java | 331 -- .../Activity/CustomThemePreviewActivity.java | 473 --- .../Activity/CustomizeThemeActivity.java | 247 -- .../Activity/EditCommentActivity.java | 244 -- .../Activity/EditMultiRedditActivity.java | 271 -- .../Activity/EditPostActivity.java | 245 -- .../FetchRandomSubredditOrPostActivity.java | 104 - .../Activity/FilteredThingActivity.java | 461 --- .../Activity/FullMarkdownActivity.java | 266 -- .../Activity/GiveAwardActivity.java | 210 -- .../infinityforreddit/Activity/InboxActivity.java | 353 -- .../Activity/LinkResolverActivity.java | 327 -- .../infinityforreddit/Activity/LoginActivity.java | 251 -- .../infinityforreddit/Activity/MainActivity.java | 1529 -------- .../Activity/PostImageActivity.java | 678 ---- .../Activity/PostLinkActivity.java | 552 --- .../Activity/PostTextActivity.java | 569 --- .../Activity/PostVideoActivity.java | 679 ---- .../infinityforreddit/Activity/ReportActivity.java | 219 -- .../infinityforreddit/Activity/RulesActivity.java | 295 -- .../infinityforreddit/Activity/SearchActivity.java | 391 -- .../Activity/SearchResultActivity.java | 513 --- .../Activity/SearchSubredditsResultActivity.java | 205 -- .../Activity/SelectUserFlairActivity.java | 261 -- .../Activity/SelectedSubredditsActivity.java | 175 - .../Activity/SendPrivateMessageActivity.java | 210 -- .../Activity/SettingsActivity.java | 194 - .../Activity/ShareDataResolverActivity.java | 79 - .../Activity/SubmitCrosspostActivity.java | 623 ---- .../SubredditFilterPopularAndAllActivity.java | 168 - .../Activity/SubredditMultiselectionActivity.java | 266 -- .../Activity/SubredditSelectionActivity.java | 298 -- .../Activity/SubscribedThingListingActivity.java | 472 --- .../Activity/ViewImageOrGifActivity.java | 492 --- .../Activity/ViewImgurMediaActivity.java | 495 --- .../Activity/ViewMultiRedditDetailActivity.java | 364 -- .../Activity/ViewPostDetailActivity.java | 1856 ---------- .../Activity/ViewPrivateMessagesActivity.java | 331 -- .../Activity/ViewRedditGalleryActivity.java | 242 -- .../Activity/ViewSubredditDetailActivity.java | 1324 ------- .../Activity/ViewUserDetailActivity.java | 1025 ------ .../Activity/ViewVideoActivity.java | 508 --- .../AcknowledgementRecyclerViewAdapter.java | 70 - .../Adapter/AwardRecyclerViewAdapter.java | 98 - .../Adapter/CommentAndPostRecyclerViewAdapter.java | 3887 -------------------- .../CommentsListingRecyclerViewAdapter.java | 730 ---- .../CustomThemeListingRecyclerViewAdapter.java | 170 - .../Adapter/CustomizeThemeRecyclerViewAdapter.java | 178 - .../FlairBottomSheetRecyclerViewAdapter.java | 114 - .../Adapter/FollowedUsersRecyclerViewAdapter.java | 359 -- .../MarkdownBottomBarRecyclerViewAdapter.java | 260 -- .../Adapter/MessageRecyclerViewAdapter.java | 396 -- .../MultiRedditListingRecyclerViewAdapter.java | 398 -- .../NavigationDrawerRecyclerViewAdapter.java | 657 ---- .../Adapter/PostRecyclerViewAdapter.java | 3008 --------------- .../PrivateMessagesDetailRecyclerViewAdapter.java | 277 -- .../Adapter/ReportReasonRecyclerViewAdapter.java | 130 - .../Adapter/RulesRecyclerViewAdapter.java | 118 - .../Adapter/SearchActivityRecyclerViewAdapter.java | 94 - .../SelectedSubredditsRecyclerViewAdapter.java | 79 - .../SubredditFilterRecyclerViewAdapter.java | 72 - .../SubredditListingRecyclerViewAdapter.java | 260 -- ...SubredditMultiselectionRecyclerViewAdapter.java | 123 - .../SubscribedSubredditsRecyclerViewAdapter.java | 513 --- .../TranslationFragmentRecyclerViewAdapter.java | 82 - .../Adapter/UserFlairRecyclerViewAdapter.java | 88 - .../Adapter/UserListingRecyclerViewAdapter.java | 263 -- .../infinityforreddit/AppComponent.java | 146 +- .../infinityforreddit/AppModule.java | 8 +- .../AsyncTask/ChangeThemeNameAsyncTask.java | 23 - .../AsyncTask/CheckIsFollowingUserAsyncTask.java | 44 - .../CheckIsSubscribedToSubredditAsyncTask.java | 46 - .../AsyncTask/DeleteAllPostLayoutsAsyncTask.java | 57 - .../AsyncTask/DeleteAllSortTypesAsyncTask.java | 58 - .../AsyncTask/DeleteAllSubredditsAsyncTask.java | 33 - .../AsyncTask/DeleteAllThemesAsyncTask.java | 45 - .../AsyncTask/DeleteAllUsersAsyncTask.java | 33 - .../DeleteMultiredditInDatabaseAsyncTask.java | 37 - .../AsyncTask/DeleteThemeAsyncTask.java | 44 - .../AsyncTask/GetCurrentAccountAsyncTask.java | 33 - .../AsyncTask/GetCustomThemeAsyncTask.java | 60 - .../AsyncTask/InsertCustomThemeAsyncTask.java | 80 - .../AsyncTask/InsertMultiRedditAsyncTask.java | 94 - .../AsyncTask/InsertSubredditDataAsyncTask.java | 35 - .../AsyncTask/InsertSubscribedThingsAsyncTask.java | 184 - .../AsyncTask/InsertUserDataAsyncTask.java | 36 - .../AsyncTask/LoadSubredditIconAsyncTask.java | 71 - .../AsyncTask/LoadUserDataAsyncTask.java | 58 - .../ParseAndInsertNewAccountAsyncTask.java | 50 - .../AsyncTask/SaveBitmapImageToFileAsyncTask.java | 55 - .../AsyncTask/SaveGIFToFileAsyncTask.java | 59 - .../AsyncTask/SetAsWallpaperAsyncTask.java | 95 - .../AsyncTask/SwitchAccountAsyncTask.java | 36 - .../SwitchToAnonymousAccountAsyncTask.java | 37 - .../infinityforreddit/Award/Award.java | 143 - .../infinityforreddit/Award/GiveAward.java | 134 - .../CommentMoreBottomSheetFragment.java | 197 - .../CopyTextBottomSheetFragment.java | 115 - .../CreateThemeBottomSheetFragment.java | 90 - .../CustomThemeOptionsBottomSheetFragment.java | 91 - .../FABMoreOptionsBottomSheetFragment.java | 111 - .../FlairBottomSheetFragment.java | 125 - .../MultiRedditOptionsBottomSheetFragment.java | 72 - .../PostCommentSortTypeBottomSheetFragment.java | 119 - .../PostLayoutBottomSheetFragment.java | 65 - .../PostTypeBottomSheetFragment.java | 91 - .../RandomBottomSheetFragment.java | 88 - .../SearchPostSortTypeBottomSheetFragment.java | 90 - ...serAndSubredditSortTypeBottomSheetFragment.java | 76 - .../SetAsWallpaperBottomSheetFragment.java | 79 - .../ShareLinkBottomSheetFragment.java | 142 - .../SortTimeBottomSheetFragment.java | 112 - .../SortTypeBottomSheetFragment.java | 102 - .../UrlMenuBottomSheetFragment.java | 87 - .../UserThingSortTypeBottomSheetFragment.java | 86 - .../NetworkWifiStatusReceiver.java | 22 - .../infinityforreddit/Comment/Comment.java | 390 -- .../Comment/CommentDataSource.java | 271 -- .../Comment/CommentDataSourceFactory.java | 56 - .../Comment/CommentViewModel.java | 105 - .../infinityforreddit/Comment/FetchComment.java | 138 - .../Comment/FetchRemovedComment.java | 98 - .../infinityforreddit/Comment/ParseComment.java | 324 -- .../infinityforreddit/Comment/SendComment.java | 61 - .../infinityforreddit/CustomTheme/CustomTheme.java | 280 -- .../CustomTheme/CustomThemeDao.java | 57 - .../CustomTheme/CustomThemeRepository.java | 37 - .../CustomTheme/CustomThemeSettingsItem.java | 398 -- .../CustomTheme/CustomThemeViewModel.java | 55 - .../CustomTheme/CustomThemeWrapper.java | 1427 ------- .../CustomView/AspectRatioBigImageView.java | 60 - .../CustomView/AspectRatioGifImageView.java | 54 - .../AspectRatioSubsamplingScaleImageView.java | 54 - .../CustomView/ColorPickerDialog.java | 153 - .../CustomView/CustomToroContainer.java | 27 - .../CustomView/LollipopBugFixedWebView.java | 28 - .../CustomView/MarkwonLinearLayoutManager.java | 42 - .../infinityforreddit/DeleteThing.java | 4 +- .../Event/ChangeAutoplayNsfwVideosEvent.java | 9 - ...geCompactLayoutToolbarHiddenByDefaultEvent.java | 9 - .../Event/ChangeConfirmToExitEvent.java | 9 - .../Event/ChangeDataSavingModeEvent.java | 9 - .../Event/ChangeDefaultPostLayoutEvent.java | 9 - .../Event/ChangeDisableImagePreviewEvent.java | 9 - .../ChangeDisableSwipingBetweenTabsEvent.java | 9 - .../Event/ChangeEnableSwipeActionSwitchEvent.java | 9 - .../Event/ChangeLockBottomAppBarEvent.java | 9 - ...LongPressToHideToolbarInCompactLayoutEvent.java | 9 - .../Event/ChangeMuteAutoplayingVideosEvent.java | 9 - .../Event/ChangeMuteNSFWVideoEvent.java | 9 - .../Event/ChangeNSFWBlurEvent.java | 9 - .../infinityforreddit/Event/ChangeNSFWEvent.java | 9 - .../Event/ChangeNetworkStatusEvent.java | 9 - .../Event/ChangePostLayoutEvent.java | 9 - .../ChangeRequireAuthToAccountSectionEvent.java | 9 - .../ChangeSavePostFeedScrolledPositionEvent.java | 9 - .../ChangeShowAbsoluteNumberOfVotesEvent.java | 9 - .../Event/ChangeShowElapsedTimeEvent.java | 9 - .../Event/ChangeSpoilerBlurEvent.java | 9 - .../ChangeStartAutoplayVisibleAreaOffsetEvent.java | 9 - .../Event/ChangeSwipeActionEvent.java | 11 - .../Event/ChangeSwipeActionThresholdEvent.java | 9 - .../Event/ChangeTimeFormatEvent.java | 9 - .../ChangeVibrateWhenActionTriggeredEvent.java | 9 - .../Event/ChangeVideoAutoplayEvent.java | 9 - .../Event/ChangeVoteButtonsPositionEvent.java | 9 - .../Event/DownloadMediaEvent.java | 9 - .../Event/DownloadRedditVideoEvent.java | 9 - .../Event/GoBackToMainPageEvent.java | 4 - .../Event/PostUpdateEventToDetailActivity.java | 11 - .../Event/PostUpdateEventToPostList.java | 13 - .../Event/RecreateActivityEvent.java | 4 - .../Event/RefreshMultiRedditsEvent.java | 4 - .../Event/RepliedToPrivateMessageEvent.java | 13 - .../ShowDividerInCompactLayoutPreferenceEvent.java | 9 - ...howThumbnailOnTheRightInCompactLayoutEvent.java | 9 - .../Event/SubmitCrosspostEvent.java | 15 - .../Event/SubmitImagePostEvent.java | 11 - .../Event/SubmitTextOrLinkPostEvent.java | 15 - .../Event/SubmitVideoOrGifPostEvent.java | 13 - .../Event/SwitchAccountEvent.java | 12 - .../infinityforreddit/FavoriteThing.java | 10 +- .../infinityforreddit/FetchFlairs.java | 6 +- .../FetchGfycatOrRedgifsVideoLinks.java | 4 +- .../infinityforreddit/FetchMyInfo.java | 6 +- .../infinityforreddit/FetchRules.java | 6 +- .../infinityforreddit/FetchSubscribedThing.java | 10 +- .../infinityforreddit/FetchUserFlairs.java | 6 +- .../infinityforreddit/Font/ContentFontFamily.java | 36 - .../infinityforreddit/Font/ContentFontStyle.java | 27 - .../infinityforreddit/Font/FontFamily.java | 36 - .../infinityforreddit/Font/FontStyle.java | 26 - .../infinityforreddit/Font/TitleFontFamily.java | 36 - .../infinityforreddit/Font/TitleFontStyle.java | 26 - .../Fragment/ChangePullToRefreshEvent.java | 9 - .../Fragment/CommentsListingFragment.java | 416 --- .../Fragment/FollowedUsersListingFragment.java | 175 - .../infinityforreddit/Fragment/InboxFragment.java | 197 - .../Fragment/MultiRedditListingFragment.java | 181 - .../infinityforreddit/Fragment/PostFragment.java | 1457 -------- .../Fragment/SidebarFragment.java | 201 - .../Fragment/SubredditListingFragment.java | 239 -- .../SubscribedSubredditsListingFragment.java | 191 - .../Fragment/ThemePreviewCommentsFragment.java | 154 - .../Fragment/ThemePreviewPostsFragment.java | 153 - .../Fragment/UserListingFragment.java | 220 -- .../Fragment/ViewImgurImageFragment.java | 264 -- .../Fragment/ViewImgurVideoFragment.java | 289 -- .../ViewRedditGalleryImageOrGifFragment.java | 381 -- .../Fragment/ViewRedditGalleryVideoFragment.java | 293 -- .../infinityforreddit/Infinity.java | 6 +- .../infinityforreddit/Message/ComposeMessage.java | 58 - .../infinityforreddit/Message/FetchMessage.java | 53 - .../infinityforreddit/Message/Message.java | 221 -- .../Message/MessageDataSource.java | 119 - .../Message/MessageDataSourceFactory.java | 47 - .../Message/MessageViewModel.java | 97 - .../infinityforreddit/Message/ParseMessage.java | 242 -- .../infinityforreddit/Message/ReadMessage.java | 43 - .../infinityforreddit/Message/ReplyMessage.java | 58 - .../MultiReddit/CreateMultiReddit.java | 56 - .../MultiReddit/DeleteMultiReddit.java | 41 - .../MultiReddit/EditMultiReddit.java | 43 - .../MultiReddit/FavoriteMultiReddit.java | 49 - .../MultiReddit/FetchMultiRedditInfo.java | 101 - .../MultiReddit/FetchMyMultiReddits.java | 48 - .../infinityforreddit/MultiReddit/MultiReddit.java | 258 -- .../MultiReddit/MultiRedditDao.java | 33 - .../MultiReddit/MultiRedditJSONModel.java | 38 - .../MultiReddit/MultiRedditRepository.java | 26 - .../MultiReddit/MultiRedditViewModel.java | 52 - .../MultiReddit/ParseMultiReddit.java | 138 - .../MultiReddit/SubredditInMultiReddit.java | 11 - .../infinityforreddit/ParseSubscribedThing.java | 8 +- .../infinityforreddit/Post/FetchPost.java | 95 - .../infinityforreddit/Post/FetchRemovedPost.java | 159 - .../infinityforreddit/Post/HidePost.java | 63 - .../infinityforreddit/Post/ParsePost.java | 666 ---- .../infinityforreddit/Post/Post.java | 652 ---- .../infinityforreddit/Post/PostDataSource.java | 927 ----- .../Post/PostDataSourceFactory.java | 141 - .../infinityforreddit/Post/PostViewModel.java | 322 -- .../infinityforreddit/Post/SubmitPost.java | 478 --- .../infinityforreddit/PullNotificationWorker.java | 24 +- .../RecentSearchQuery/DeleteRecentSearchQuery.java | 44 - .../RecentSearchQuery/InsertRecentSearchQuery.java | 53 - .../RecentSearchQuery/RecentSearchQuery.java | 43 - .../RecentSearchQuery/RecentSearchQueryDao.java | 25 - .../RecentSearchQueryRepository.java | 19 - .../RecentSearchQueryViewModel.java | 38 - .../infinityforreddit/RedditDataRoomDatabase.java | 36 +- .../infinityforreddit/ReportThing.java | 4 +- .../infinityforreddit/SaveThing.java | 4 +- .../infinityforreddit/SelectUserFlair.java | 6 +- .../Service/DownloadMediaService.java | 470 --- .../Service/DownloadRedditVideoService.java | 662 ---- .../Service/SubmitPostService.java | 354 -- .../Settings/AboutPreferenceFragment.java | 143 - .../Settings/Acknowledgement.java | 27 - .../Settings/AcknowledgementFragment.java | 138 - .../Settings/AdvancedPreferenceFragment.java | 237 -- .../Settings/CreditsPreferenceFragment.java | 136 - .../Settings/CustomizeBottomAppBarFragment.java | 330 -- .../Settings/CustomizeMainPageTabsFragment.java | 563 --- .../Settings/DataSavingModePreferenceFragment.java | 39 - .../DownloadLocationPreferenceFragment.java | 118 - .../Settings/FilterPreferenceFragment.java | 38 - .../Settings/FontPreferenceFragment.java | 80 - .../Settings/FontPreviewFragment.java | 29 - .../GesturesAndButtonsPreferenceFragment.java | 88 - .../ImmersiveInterfacePreferenceFragment.java | 46 - .../Settings/InterfacePreferenceFragment.java | 101 - .../Settings/MainPreferenceFragment.java | 51 - .../Settings/MiscellaneousPreferenceFragment.java | 67 - .../Settings/NotificationPreferenceFragment.java | 127 - .../Settings/NsfwAndBlurringFragment.java | 112 - ...umberOfColumnsInPostFeedPreferenceFragment.java | 14 - .../Settings/SecurityPreferenceFragment.java | 77 - .../Settings/SwipeActionPreferenceFragment.java | 82 - .../Settings/ThemePreferenceFragment.java | 193 - .../Settings/TimeFormatPreferenceFragment.java | 38 - .../infinityforreddit/Settings/Translation.java | 44 - .../Settings/TranslationFragment.java | 58 - .../Settings/VideoPreferenceFragment.java | 113 - .../Subreddit/FetchSubredditData.java | 94 - .../Subreddit/ParseSubredditData.java | 173 - .../infinityforreddit/Subreddit/SubredditDao.java | 22 - .../infinityforreddit/Subreddit/SubredditData.java | 88 - .../Subreddit/SubredditListingDataSource.java | 108 - .../SubredditListingDataSourceFactory.java | 48 - .../Subreddit/SubredditListingViewModel.java | 98 - .../Subreddit/SubredditRepository.java | 40 - .../Subreddit/SubredditSubscription.java | 120 - .../Subreddit/SubredditViewModel.java | 51 - .../Subreddit/SubredditWithSelection.java | 101 - .../SubredditFilter/DeleteSubredditFilter.java | 41 - .../SubredditFilter/FetchSubredditFilters.java | 42 - .../SubredditFilter/InsertSubredditFilter.java | 41 - .../SubredditFilter/SubredditFilter.java | 68 - .../SubredditFilter/SubredditFilterDao.java | 25 - .../SubredditFilter/SubredditFilterViewModel.java | 36 - .../SubscribedSubredditDao.java | 33 - .../SubscribedSubredditData.java | 65 - .../SubscribedSubredditRepository.java | 48 - .../SubscribedSubredditViewModel.java | 56 - .../SubscribedUserDatabase/SubscribedUserDao.java | 30 - .../SubscribedUserDatabase/SubscribedUserData.java | 57 - .../SubscribedUserRepository.java | 48 - .../SubscribedUserViewModel.java | 56 - .../infinityforreddit/User/BlockUser.java | 40 - .../infinityforreddit/User/FetchUserData.java | 87 - .../infinityforreddit/User/ParseUserData.java | 156 - .../infinityforreddit/User/UserDao.java | 22 - .../infinityforreddit/User/UserData.java | 116 - .../infinityforreddit/User/UserFollowing.java | 118 - .../User/UserListingDataSource.java | 106 - .../User/UserListingDataSourceFactory.java | 46 - .../User/UserListingViewModel.java | 96 - .../infinityforreddit/User/UserRepository.java | 40 - .../infinityforreddit/User/UserViewModel.java | 50 - .../infinityforreddit/Utils/APIUtils.java | 123 - .../Utils/CustomThemeSharedPreferencesUtils.java | 173 - .../infinityforreddit/Utils/GetPathUtils.java | 238 -- .../infinityforreddit/Utils/GlideImageGetter.java | 173 - .../infinityforreddit/Utils/JSONUtils.java | 133 - .../infinityforreddit/Utils/NotificationUtils.java | 91 - .../Utils/SharedPreferencesUtils.java | 235 -- .../infinityforreddit/Utils/Utils.java | 266 -- .../infinityforreddit/VoteThing.java | 4 +- .../infinityforreddit/WallpaperSetter.java | 2 +- .../infinityforreddit/account/Account.java | 76 + .../infinityforreddit/account/AccountDao.java | 55 + .../account/AccountRepository.java | 48 + .../account/AccountViewModel.java | 58 + .../activities/AccountPostsActivity.java | 314 ++ .../activities/AccountSavedThingActivity.java | 440 +++ .../infinityforreddit/activities/BaseActivity.java | 326 ++ .../activities/CommentActivity.java | 433 +++ .../activities/CreateMultiRedditActivity.java | 241 ++ .../activities/CustomThemeListingActivity.java | 331 ++ .../activities/CustomThemePreviewActivity.java | 473 +++ .../activities/CustomizeThemeActivity.java | 247 ++ .../activities/EditCommentActivity.java | 244 ++ .../activities/EditMultiRedditActivity.java | 271 ++ .../activities/EditPostActivity.java | 245 ++ .../FetchRandomSubredditOrPostActivity.java | 104 + .../activities/FilteredThingActivity.java | 461 +++ .../activities/FullMarkdownActivity.java | 266 ++ .../activities/GiveAwardActivity.java | 210 ++ .../activities/InboxActivity.java | 353 ++ .../activities/LinkResolverActivity.java | 327 ++ .../activities/LoginActivity.java | 251 ++ .../infinityforreddit/activities/MainActivity.java | 1528 ++++++++ .../activities/PostImageActivity.java | 678 ++++ .../activities/PostLinkActivity.java | 552 +++ .../activities/PostTextActivity.java | 569 +++ .../activities/PostVideoActivity.java | 679 ++++ .../activities/ReportActivity.java | 219 ++ .../activities/RulesActivity.java | 295 ++ .../activities/SearchActivity.java | 391 ++ .../activities/SearchResultActivity.java | 513 +++ .../activities/SearchSubredditsResultActivity.java | 205 ++ .../activities/SelectUserFlairActivity.java | 261 ++ .../activities/SelectedSubredditsActivity.java | 175 + .../activities/SendPrivateMessageActivity.java | 210 ++ .../activities/SettingsActivity.java | 194 + .../activities/ShareDataResolverActivity.java | 79 + .../activities/SubmitCrosspostActivity.java | 623 ++++ .../SubredditFilterPopularAndAllActivity.java | 168 + .../SubredditMultiselectionActivity.java | 266 ++ .../activities/SubredditSelectionActivity.java | 298 ++ .../activities/SubscribedThingListingActivity.java | 472 +++ .../activities/ViewImageOrGifActivity.java | 492 +++ .../activities/ViewImgurMediaActivity.java | 495 +++ .../activities/ViewMultiRedditDetailActivity.java | 364 ++ .../activities/ViewPostDetailActivity.java | 1856 ++++++++++ .../activities/ViewPrivateMessagesActivity.java | 331 ++ .../activities/ViewRedditGalleryActivity.java | 242 ++ .../activities/ViewSubredditDetailActivity.java | 1324 +++++++ .../activities/ViewUserDetailActivity.java | 1025 ++++++ .../activities/ViewVideoActivity.java | 508 +++ .../AcknowledgementRecyclerViewAdapter.java | 70 + .../adapters/AwardRecyclerViewAdapter.java | 98 + .../CommentAndPostRecyclerViewAdapter.java | 3887 ++++++++++++++++++++ .../CommentsListingRecyclerViewAdapter.java | 730 ++++ .../CustomThemeListingRecyclerViewAdapter.java | 170 + .../CustomizeThemeRecyclerViewAdapter.java | 178 + .../FlairBottomSheetRecyclerViewAdapter.java | 114 + .../adapters/FollowedUsersRecyclerViewAdapter.java | 359 ++ .../MarkdownBottomBarRecyclerViewAdapter.java | 260 ++ .../adapters/MessageRecyclerViewAdapter.java | 396 ++ .../MultiRedditListingRecyclerViewAdapter.java | 398 ++ .../NavigationDrawerRecyclerViewAdapter.java | 657 ++++ .../adapters/PostRecyclerViewAdapter.java | 3008 +++++++++++++++ .../PrivateMessagesDetailRecyclerViewAdapter.java | 277 ++ .../adapters/ReportReasonRecyclerViewAdapter.java | 130 + .../adapters/RulesRecyclerViewAdapter.java | 118 + .../SearchActivityRecyclerViewAdapter.java | 94 + .../SelectedSubredditsRecyclerViewAdapter.java | 79 + .../SubredditFilterRecyclerViewAdapter.java | 72 + .../SubredditListingRecyclerViewAdapter.java | 260 ++ ...SubredditMultiselectionRecyclerViewAdapter.java | 123 + .../SubscribedSubredditsRecyclerViewAdapter.java | 513 +++ .../TranslationFragmentRecyclerViewAdapter.java | 82 + .../adapters/UserFlairRecyclerViewAdapter.java | 88 + .../adapters/UserListingRecyclerViewAdapter.java | 263 ++ .../infinityforreddit/apis/DownloadFile.java | 13 + .../infinityforreddit/apis/GfycatAPI.java | 10 + .../infinityforreddit/apis/ImgurAPI.java | 18 + .../infinityforreddit/apis/PushshiftAPI.java | 13 + .../infinityforreddit/apis/RedditAPI.java | 339 ++ .../asynctasks/ChangeThemeNameAsyncTask.java | 23 + .../asynctasks/CheckIsFollowingUserAsyncTask.java | 44 + .../CheckIsSubscribedToSubredditAsyncTask.java | 46 + .../asynctasks/DeleteAllPostLayoutsAsyncTask.java | 57 + .../asynctasks/DeleteAllSortTypesAsyncTask.java | 58 + .../asynctasks/DeleteAllSubredditsAsyncTask.java | 33 + .../asynctasks/DeleteAllThemesAsyncTask.java | 45 + .../asynctasks/DeleteAllUsersAsyncTask.java | 33 + .../DeleteMultiredditInDatabaseAsyncTask.java | 37 + .../asynctasks/DeleteThemeAsyncTask.java | 44 + .../asynctasks/GetCurrentAccountAsyncTask.java | 33 + .../asynctasks/GetCustomThemeAsyncTask.java | 60 + .../asynctasks/InsertCustomThemeAsyncTask.java | 80 + .../asynctasks/InsertMultiRedditAsyncTask.java | 94 + .../asynctasks/InsertSubredditDataAsyncTask.java | 35 + .../InsertSubscribedThingsAsyncTask.java | 184 + .../asynctasks/InsertUserDataAsyncTask.java | 36 + .../asynctasks/LoadSubredditIconAsyncTask.java | 71 + .../asynctasks/LoadUserDataAsyncTask.java | 58 + .../ParseAndInsertNewAccountAsyncTask.java | 50 + .../asynctasks/SaveBitmapImageToFileAsyncTask.java | 55 + .../asynctasks/SaveGIFToFileAsyncTask.java | 59 + .../asynctasks/SetAsWallpaperAsyncTask.java | 95 + .../asynctasks/SwitchAccountAsyncTask.java | 36 + .../SwitchToAnonymousAccountAsyncTask.java | 37 + .../infinityforreddit/award/Award.java | 143 + .../infinityforreddit/award/GiveAward.java | 134 + .../CommentMoreBottomSheetFragment.java | 197 + .../CopyTextBottomSheetFragment.java | 115 + .../CreateThemeBottomSheetFragment.java | 90 + .../CustomThemeOptionsBottomSheetFragment.java | 91 + .../FABMoreOptionsBottomSheetFragment.java | 111 + .../FlairBottomSheetFragment.java | 125 + .../MultiRedditOptionsBottomSheetFragment.java | 72 + .../PostCommentSortTypeBottomSheetFragment.java | 119 + .../PostLayoutBottomSheetFragment.java | 65 + .../PostTypeBottomSheetFragment.java | 91 + .../RandomBottomSheetFragment.java | 88 + .../SearchPostSortTypeBottomSheetFragment.java | 90 + ...serAndSubredditSortTypeBottomSheetFragment.java | 76 + .../SetAsWallpaperBottomSheetFragment.java | 79 + .../ShareLinkBottomSheetFragment.java | 142 + .../SortTimeBottomSheetFragment.java | 112 + .../SortTypeBottomSheetFragment.java | 102 + .../UrlMenuBottomSheetFragment.java | 87 + .../UserThingSortTypeBottomSheetFragment.java | 86 + .../NetworkWifiStatusReceiver.java | 22 + .../infinityforreddit/comment/Comment.java | 390 ++ .../comment/CommentDataSource.java | 271 ++ .../comment/CommentDataSourceFactory.java | 56 + .../comment/CommentViewModel.java | 105 + .../infinityforreddit/comment/FetchComment.java | 138 + .../comment/FetchRemovedComment.java | 97 + .../infinityforreddit/comment/ParseComment.java | 324 ++ .../infinityforreddit/comment/SendComment.java | 61 + .../infinityforreddit/customtheme/CustomTheme.java | 280 ++ .../customtheme/CustomThemeDao.java | 57 + .../customtheme/CustomThemeRepository.java | 37 + .../customtheme/CustomThemeSettingsItem.java | 398 ++ .../customtheme/CustomThemeViewModel.java | 55 + .../customtheme/CustomThemeWrapper.java | 1427 +++++++ .../customviews/AspectRatioBigImageView.java | 60 + .../customviews/AspectRatioGifImageView.java | 54 + .../AspectRatioSubsamplingScaleImageView.java | 54 + .../customviews/ColorPickerDialog.java | 153 + .../customviews/CustomToroContainer.java | 27 + .../customviews/LollipopBugFixedWebView.java | 28 + .../customviews/MarkwonLinearLayoutManager.java | 42 + .../events/ChangeAutoplayNsfwVideosEvent.java | 9 + ...geCompactLayoutToolbarHiddenByDefaultEvent.java | 9 + .../events/ChangeConfirmToExitEvent.java | 9 + .../events/ChangeDataSavingModeEvent.java | 9 + .../events/ChangeDefaultPostLayoutEvent.java | 9 + .../events/ChangeDisableImagePreviewEvent.java | 9 + .../ChangeDisableSwipingBetweenTabsEvent.java | 9 + .../events/ChangeEnableSwipeActionSwitchEvent.java | 9 + .../events/ChangeLockBottomAppBarEvent.java | 9 + ...LongPressToHideToolbarInCompactLayoutEvent.java | 9 + .../events/ChangeMuteAutoplayingVideosEvent.java | 9 + .../events/ChangeMuteNSFWVideoEvent.java | 9 + .../events/ChangeNSFWBlurEvent.java | 9 + .../infinityforreddit/events/ChangeNSFWEvent.java | 9 + .../events/ChangeNetworkStatusEvent.java | 9 + .../events/ChangePostLayoutEvent.java | 9 + .../ChangeRequireAuthToAccountSectionEvent.java | 9 + .../ChangeSavePostFeedScrolledPositionEvent.java | 9 + .../ChangeShowAbsoluteNumberOfVotesEvent.java | 9 + .../events/ChangeShowElapsedTimeEvent.java | 9 + .../events/ChangeSpoilerBlurEvent.java | 9 + .../ChangeStartAutoplayVisibleAreaOffsetEvent.java | 9 + .../events/ChangeSwipeActionEvent.java | 11 + .../events/ChangeSwipeActionThresholdEvent.java | 9 + .../events/ChangeTimeFormatEvent.java | 9 + .../ChangeVibrateWhenActionTriggeredEvent.java | 9 + .../events/ChangeVideoAutoplayEvent.java | 9 + .../events/ChangeVoteButtonsPositionEvent.java | 9 + .../events/DownloadMediaEvent.java | 9 + .../events/DownloadRedditVideoEvent.java | 9 + .../events/GoBackToMainPageEvent.java | 4 + .../events/PostUpdateEventToDetailActivity.java | 11 + .../events/PostUpdateEventToPostList.java | 13 + .../events/RecreateActivityEvent.java | 4 + .../events/RefreshMultiRedditsEvent.java | 4 + .../events/RepliedToPrivateMessageEvent.java | 13 + .../ShowDividerInCompactLayoutPreferenceEvent.java | 9 + ...howThumbnailOnTheRightInCompactLayoutEvent.java | 9 + .../events/SubmitCrosspostEvent.java | 15 + .../events/SubmitImagePostEvent.java | 11 + .../events/SubmitTextOrLinkPostEvent.java | 15 + .../events/SubmitVideoOrGifPostEvent.java | 13 + .../events/SwitchAccountEvent.java | 12 + .../infinityforreddit/font/ContentFontFamily.java | 36 + .../infinityforreddit/font/ContentFontStyle.java | 27 + .../infinityforreddit/font/FontFamily.java | 36 + .../infinityforreddit/font/FontStyle.java | 26 + .../infinityforreddit/font/TitleFontFamily.java | 36 + .../infinityforreddit/font/TitleFontStyle.java | 26 + .../fragments/ChangePullToRefreshEvent.java | 9 + .../fragments/CommentsListingFragment.java | 416 +++ .../fragments/FollowedUsersListingFragment.java | 175 + .../infinityforreddit/fragments/InboxFragment.java | 197 + .../fragments/MultiRedditListingFragment.java | 181 + .../infinityforreddit/fragments/PostFragment.java | 1457 ++++++++ .../fragments/SidebarFragment.java | 201 + .../fragments/SubredditListingFragment.java | 239 ++ .../SubscribedSubredditsListingFragment.java | 191 + .../fragments/ThemePreviewCommentsFragment.java | 154 + .../fragments/ThemePreviewPostsFragment.java | 153 + .../fragments/UserListingFragment.java | 220 ++ .../fragments/ViewImgurImageFragment.java | 264 ++ .../fragments/ViewImgurVideoFragment.java | 289 ++ .../ViewRedditGalleryImageOrGifFragment.java | 381 ++ .../fragments/ViewRedditGalleryVideoFragment.java | 293 ++ .../infinityforreddit/message/ComposeMessage.java | 58 + .../infinityforreddit/message/FetchMessage.java | 53 + .../infinityforreddit/message/Message.java | 221 ++ .../message/MessageDataSource.java | 119 + .../message/MessageDataSourceFactory.java | 47 + .../message/MessageViewModel.java | 97 + .../infinityforreddit/message/ParseMessage.java | 242 ++ .../infinityforreddit/message/ReadMessage.java | 43 + .../infinityforreddit/message/ReplyMessage.java | 58 + .../multireddit/CreateMultiReddit.java | 56 + .../multireddit/DeleteMultiReddit.java | 41 + .../multireddit/EditMultiReddit.java | 43 + .../multireddit/FavoriteMultiReddit.java | 49 + .../multireddit/FetchMultiRedditInfo.java | 101 + .../multireddit/FetchMyMultiReddits.java | 48 + .../infinityforreddit/multireddit/MultiReddit.java | 258 ++ .../multireddit/MultiRedditDao.java | 33 + .../multireddit/MultiRedditJSONModel.java | 38 + .../multireddit/MultiRedditRepository.java | 26 + .../multireddit/MultiRedditViewModel.java | 52 + .../multireddit/ParseMultiReddit.java | 138 + .../multireddit/SubredditInMultiReddit.java | 11 + .../infinityforreddit/post/FetchPost.java | 95 + .../infinityforreddit/post/FetchRemovedPost.java | 159 + .../infinityforreddit/post/HidePost.java | 63 + .../infinityforreddit/post/ParsePost.java | 666 ++++ .../infinityforreddit/post/Post.java | 652 ++++ .../infinityforreddit/post/PostDataSource.java | 927 +++++ .../post/PostDataSourceFactory.java | 141 + .../infinityforreddit/post/PostViewModel.java | 322 ++ .../infinityforreddit/post/SubmitPost.java | 478 +++ .../recentsearchquery/DeleteRecentSearchQuery.java | 44 + .../recentsearchquery/InsertRecentSearchQuery.java | 53 + .../recentsearchquery/RecentSearchQuery.java | 43 + .../recentsearchquery/RecentSearchQueryDao.java | 25 + .../RecentSearchQueryRepository.java | 19 + .../RecentSearchQueryViewModel.java | 38 + .../services/DownloadMediaService.java | 470 +++ .../services/DownloadRedditVideoService.java | 662 ++++ .../services/SubmitPostService.java | 354 ++ .../settings/AboutPreferenceFragment.java | 143 + .../settings/Acknowledgement.java | 27 + .../settings/AcknowledgementFragment.java | 138 + .../settings/AdvancedPreferenceFragment.java | 237 ++ .../settings/CreditsPreferenceFragment.java | 136 + .../settings/CustomizeBottomAppBarFragment.java | 330 ++ .../settings/CustomizeMainPageTabsFragment.java | 563 +++ .../settings/DataSavingModePreferenceFragment.java | 39 + .../DownloadLocationPreferenceFragment.java | 118 + .../settings/FilterPreferenceFragment.java | 38 + .../settings/FontPreferenceFragment.java | 80 + .../settings/FontPreviewFragment.java | 29 + .../GesturesAndButtonsPreferenceFragment.java | 88 + .../ImmersiveInterfacePreferenceFragment.java | 46 + .../settings/InterfacePreferenceFragment.java | 101 + .../settings/MainPreferenceFragment.java | 51 + .../settings/MiscellaneousPreferenceFragment.java | 67 + .../settings/NotificationPreferenceFragment.java | 127 + .../settings/NsfwAndBlurringFragment.java | 112 + ...umberOfColumnsInPostFeedPreferenceFragment.java | 14 + .../settings/SecurityPreferenceFragment.java | 77 + .../settings/SwipeActionPreferenceFragment.java | 82 + .../settings/ThemePreferenceFragment.java | 193 + .../settings/TimeFormatPreferenceFragment.java | 38 + .../infinityforreddit/settings/Translation.java | 44 + .../settings/TranslationFragment.java | 58 + .../settings/VideoPreferenceFragment.java | 113 + .../subreddit/FetchSubredditData.java | 94 + .../subreddit/ParseSubredditData.java | 173 + .../infinityforreddit/subreddit/SubredditDao.java | 22 + .../infinityforreddit/subreddit/SubredditData.java | 88 + .../subreddit/SubredditListingDataSource.java | 108 + .../SubredditListingDataSourceFactory.java | 48 + .../subreddit/SubredditListingViewModel.java | 98 + .../subreddit/SubredditRepository.java | 40 + .../subreddit/SubredditSubscription.java | 120 + .../subreddit/SubredditViewModel.java | 51 + .../subreddit/SubredditWithSelection.java | 101 + .../subredditfilter/DeleteSubredditFilter.java | 41 + .../subredditfilter/FetchSubredditFilters.java | 42 + .../subredditfilter/InsertSubredditFilter.java | 41 + .../subredditfilter/SubredditFilter.java | 68 + .../subredditfilter/SubredditFilterDao.java | 25 + .../subredditfilter/SubredditFilterViewModel.java | 36 + .../SubscribedSubredditDao.java | 33 + .../SubscribedSubredditData.java | 65 + .../SubscribedSubredditRepository.java | 48 + .../SubscribedSubredditViewModel.java | 56 + .../subscribeduser/SubscribedUserDao.java | 30 + .../subscribeduser/SubscribedUserData.java | 57 + .../subscribeduser/SubscribedUserRepository.java | 48 + .../subscribeduser/SubscribedUserViewModel.java | 56 + .../infinityforreddit/user/BlockUser.java | 40 + .../infinityforreddit/user/FetchUserData.java | 87 + .../infinityforreddit/user/ParseUserData.java | 156 + .../infinityforreddit/user/UserDao.java | 22 + .../infinityforreddit/user/UserData.java | 116 + .../infinityforreddit/user/UserFollowing.java | 118 + .../user/UserListingDataSource.java | 106 + .../user/UserListingDataSourceFactory.java | 46 + .../user/UserListingViewModel.java | 96 + .../infinityforreddit/user/UserRepository.java | 40 + .../infinityforreddit/user/UserViewModel.java | 50 + .../infinityforreddit/utils/APIUtils.java | 123 + .../utils/CustomThemeSharedPreferencesUtils.java | 173 + .../infinityforreddit/utils/GetPathUtils.java | 238 ++ .../infinityforreddit/utils/GlideImageGetter.java | 173 + .../infinityforreddit/utils/JSONUtils.java | 133 + .../infinityforreddit/utils/NotificationUtils.java | 91 + .../utils/SharedPreferencesUtils.java | 235 ++ .../infinityforreddit/utils/Utils.java | 266 ++ 670 files changed, 60952 insertions(+), 60954 deletions(-) delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/API/DownloadFile.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/API/GfycatAPI.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/API/ImgurAPI.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/API/PushshiftAPI.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Account/Account.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountPostsActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountSavedThingActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CommentActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CreateMultiRedditActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemeListingActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemePreviewActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditCommentActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditMultiRedditActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditPostActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FetchRandomSubredditOrPostActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FilteredThingActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FullMarkdownActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/GiveAwardActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/InboxActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LinkResolverActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostImageActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostLinkActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostTextActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostVideoActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchResultActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchSubredditsResultActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectedSubredditsActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SendPrivateMessageActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SettingsActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ShareDataResolverActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubmitCrosspostActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditFilterPopularAndAllActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditMultiselectionActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditSelectionActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubscribedThingListingActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageOrGifActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewMultiRedditDetailActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewRedditGalleryActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewUserDetailActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewVideoActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AcknowledgementRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AwardRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentsListingRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomThemeListingRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FlairBottomSheetRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FollowedUsersRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MarkdownBottomBarRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MultiRedditListingRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/RulesRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SearchActivityRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SelectedSubredditsRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditFilterRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditListingRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditMultiselectionRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubscribedSubredditsRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/TranslationFragmentRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserListingRecyclerViewAdapter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ChangeThemeNameAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsFollowingUserAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsSubscribedToSubredditAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllPostLayoutsAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSortTypesAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSubredditsAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllThemesAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllUsersAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteMultiredditInDatabaseAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteThemeAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCurrentAccountAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCustomThemeAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertCustomThemeAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertMultiRedditAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubredditDataAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubscribedThingsAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertUserDataAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadSubredditIconAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadUserDataAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ParseAndInsertNewAccountAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveBitmapImageToFileAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SetAsWallpaperAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchAccountAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchToAnonymousAccountAsyncTask.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Award/Award.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Award/GiveAward.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CommentMoreBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CopyTextBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CreateThemeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CustomThemeOptionsBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FABMoreOptionsBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FlairBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/MultiRedditOptionsBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostCommentSortTypeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostLayoutBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostTypeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/RandomBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchPostSortTypeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchUserAndSubredditSortTypeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SetAsWallpaperBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/ShareLinkBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTimeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTypeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UrlMenuBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UserThingSortTypeBottomSheetFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/BroadcastReceiver/NetworkWifiStatusReceiver.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/Comment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSource.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSourceFactory.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchComment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchRemovedComment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/ParseComment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Comment/SendComment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomTheme.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeSettingsItem.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeWrapper.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioBigImageView.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioGifImageView.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioSubsamplingScaleImageView.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/CustomToroContainer.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/MarkwonLinearLayoutManager.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeAutoplayNsfwVideosEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeConfirmToExitEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDataSavingModeEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDefaultPostLayoutEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableImagePreviewEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableSwipingBetweenTabsEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeEnableSwipeActionSwitchEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLockBottomAppBarEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLongPressToHideToolbarInCompactLayoutEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteAutoplayingVideosEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteNSFWVideoEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWBlurEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNetworkStatusEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangePostLayoutEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeRequireAuthToAccountSectionEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSavePostFeedScrolledPositionEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowAbsoluteNumberOfVotesEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowElapsedTimeEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSpoilerBlurEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeStartAutoplayVisibleAreaOffsetEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionThresholdEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeTimeFormatEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVibrateWhenActionTriggeredEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVideoAutoplayEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVoteButtonsPositionEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadMediaEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadRedditVideoEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/GoBackToMainPageEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToDetailActivity.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToPostList.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/RecreateActivityEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/RefreshMultiRedditsEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/RepliedToPrivateMessageEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowDividerInCompactLayoutPreferenceEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowThumbnailOnTheRightInCompactLayoutEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitCrosspostEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitImagePostEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitTextOrLinkPostEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitVideoOrGifPostEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Event/SwitchAccountEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontFamily.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontStyle.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontFamily.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontStyle.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontFamily.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontStyle.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ChangePullToRefreshEvent.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/CommentsListingFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/FollowedUsersListingFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/InboxFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/MultiRedditListingFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SidebarFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubredditListingFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubscribedSubredditsListingFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewCommentsFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewPostsFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/UserListingFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryImageOrGifFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryVideoFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/ComposeMessage.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/FetchMessage.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/Message.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSource.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSourceFactory.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/ParseMessage.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReadMessage.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReplyMessage.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/CreateMultiReddit.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/DeleteMultiReddit.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/EditMultiReddit.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FavoriteMultiReddit.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMultiRedditInfo.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMyMultiReddits.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiReddit.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditJSONModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/ParseMultiReddit.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/SubredditInMultiReddit.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchRemovedPost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/DeleteRecentSearchQuery.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/InsertRecentSearchQuery.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQuery.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadMediaService.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadRedditVideoService.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AboutPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Acknowledgement.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AcknowledgementFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AdvancedPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CreditsPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeBottomAppBarFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeMainPageTabsFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DataSavingModePreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DownloadLocationPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FilterPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreviewFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/GesturesAndButtonsPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ImmersiveInterfacePreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/InterfacePreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MainPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MiscellaneousPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NotificationPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NsfwAndBlurringFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NumberOfColumnsInPostFeedPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SecurityPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SwipeActionPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ThemePreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TimeFormatPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Translation.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TranslationFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Settings/VideoPreferenceFragment.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/FetchSubredditData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/ParseSubredditData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSource.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSourceFactory.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditSubscription.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditWithSelection.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/DeleteSubredditFilter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/FetchSubredditFilters.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/InsertSubredditFilter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/BlockUser.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/FetchUserData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/ParseUserData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserDao.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserData.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserFollowing.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSource.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSourceFactory.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserRepository.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/User/UserViewModel.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/APIUtils.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/CustomThemeSharedPreferencesUtils.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GetPathUtils.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GlideImageGetter.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/NotificationUtils.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Utils/Utils.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountPostsActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/BaseActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/CreateMultiRedditActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditMultiRedditActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredThingActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchSubredditsResultActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SendPrivateMessageActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SettingsActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ShareDataResolverActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditFilterPopularAndAllActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditSelectionActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AcknowledgementRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AwardRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomThemeListingRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomizeThemeRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FollowedUsersRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MultiRedditListingRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/ReportReasonRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SearchActivityRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SelectedSubredditsRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditFilterRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditMultiselectionRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubscribedSubredditsRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/TranslationFragmentRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserFlairRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserListingRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/apis/DownloadFile.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/apis/GfycatAPI.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/apis/ImgurAPI.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/apis/PushshiftAPI.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ChangeThemeNameAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsFollowingUserAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubredditAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllPostLayoutsAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSortTypesAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSubredditsAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllThemesAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllUsersAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteMultiredditInDatabaseAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteThemeAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCurrentAccountAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCustomThemeAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertCustomThemeAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertMultiRedditAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubredditDataAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubscribedThingsAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertUserDataAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadSubredditIconAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadUserDataAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ParseAndInsertNewAccountAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveBitmapImageToFileAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveGIFToFileAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SetAsWallpaperAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchAccountAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchToAnonymousAccountAsyncTask.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/award/Award.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/award/GiveAward.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CommentMoreBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CreateThemeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CustomThemeOptionsBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FABMoreOptionsBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/MultiRedditOptionsBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostCommentSortTypeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostLayoutBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/RandomBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchPostSortTypeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchUserAndSubredditSortTypeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SetAsWallpaperBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/ShareLinkBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTimeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTypeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UserThingSortTypeBottomSheetFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/NetworkWifiStatusReceiver.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSourceFactory.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchRemovedComment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeSettingsItem.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioBigImageView.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioGifImageView.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioSubsamplingScaleImageView.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ColorPickerDialog.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CustomToroContainer.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LollipopBugFixedWebView.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeAutoplayNsfwVideosEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeConfirmToExitEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDataSavingModeEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDefaultPostLayoutEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableImagePreviewEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableSwipingBetweenTabsEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeEnableSwipeActionSwitchEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLockBottomAppBarEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLongPressToHideToolbarInCompactLayoutEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteAutoplayingVideosEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteNSFWVideoEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWBlurEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNetworkStatusEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangePostLayoutEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeRequireAuthToAccountSectionEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSavePostFeedScrolledPositionEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowAbsoluteNumberOfVotesEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowElapsedTimeEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSpoilerBlurEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeStartAutoplayVisibleAreaOffsetEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionThresholdEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeTimeFormatEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVibrateWhenActionTriggeredEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVideoAutoplayEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVoteButtonsPositionEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadMediaEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadRedditVideoEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/GoBackToMainPageEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToDetailActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToPostList.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/RecreateActivityEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/RefreshMultiRedditsEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/RepliedToPrivateMessageEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowDividerInCompactLayoutPreferenceEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowThumbnailOnTheRightInCompactLayoutEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitCrosspostEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitImagePostEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitTextOrLinkPostEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitVideoOrGifPostEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/events/SwitchAccountEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontStyle.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/font/FontStyle.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontStyle.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ChangePullToRefreshEvent.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewCommentsFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewPostsFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/ComposeMessage.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/FetchMessage.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/Message.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSource.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSourceFactory.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/ParseMessage.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/ReadMessage.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/message/ReplyMessage.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/CreateMultiReddit.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/DeleteMultiReddit.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/EditMultiReddit.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FavoriteMultiReddit.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMultiRedditInfo.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMyMultiReddits.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiReddit.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditJSONModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/ParseMultiReddit.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/SubredditInMultiReddit.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchRemovedPost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/HidePost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/DeleteRecentSearchQuery.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/InsertRecentSearchQuery.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQuery.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/AboutPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/Acknowledgement.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/CreditsPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeBottomAppBarFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/DataSavingModePreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/DownloadLocationPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/FilterPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreviewFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/ImmersiveInterfacePreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/InterfacePreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/MainPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/MiscellaneousPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/NsfwAndBlurringFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/NumberOfColumnsInPostFeedPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/SwipeActionPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/TimeFormatPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/FetchSubredditData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSource.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSourceFactory.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditWithSelection.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/DeleteSubredditFilter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/FetchSubredditFilters.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/InsertSubredditFilter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/BlockUser.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/FetchUserData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/ParseUserData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserDao.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserData.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserFollowing.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSource.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSourceFactory.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserRepository.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/user/UserViewModel.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/CustomThemeSharedPreferencesUtils.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/GetPathUtils.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/GlideImageGetter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java (limited to 'app/src/main/java/ml') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/API/DownloadFile.java b/app/src/main/java/ml/docilealligator/infinityforreddit/API/DownloadFile.java deleted file mode 100644 index 10a8dda4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/API/DownloadFile.java +++ /dev/null @@ -1,13 +0,0 @@ -package ml.docilealligator.infinityforreddit.API; - -import okhttp3.ResponseBody; -import retrofit2.Call; -import retrofit2.http.GET; -import retrofit2.http.Streaming; -import retrofit2.http.Url; - -public interface DownloadFile { - @Streaming - @GET() - Call downloadFile(@Url String fileUrl); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/API/GfycatAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/API/GfycatAPI.java deleted file mode 100644 index 161659b7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/API/GfycatAPI.java +++ /dev/null @@ -1,10 +0,0 @@ -package ml.docilealligator.infinityforreddit.API; - -import retrofit2.Call; -import retrofit2.http.GET; -import retrofit2.http.Path; - -public interface GfycatAPI { - @GET("{gfyid}") - Call getGfycatData(@Path("gfyid") String gfyId); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/API/ImgurAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/API/ImgurAPI.java deleted file mode 100644 index 66058a36..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/API/ImgurAPI.java +++ /dev/null @@ -1,18 +0,0 @@ -package ml.docilealligator.infinityforreddit.API; - -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.http.GET; -import retrofit2.http.Header; -import retrofit2.http.Path; - -public interface ImgurAPI { - @GET("gallery/{id}") - Call getGalleryImages(@Header(APIUtils.AUTHORIZATION_KEY) String clientId, @Path("id") String id); - - @GET("album/{id}") - Call getAlbumImages(@Header(APIUtils.AUTHORIZATION_KEY) String clientId, @Path("id") String id); - - @GET("image/{id}") - Call getImage(@Header(APIUtils.AUTHORIZATION_KEY) String clientId, @Path("id") String id); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/API/PushshiftAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/API/PushshiftAPI.java deleted file mode 100644 index 1dc7b411..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/API/PushshiftAPI.java +++ /dev/null @@ -1,13 +0,0 @@ -package ml.docilealligator.infinityforreddit.API; - -import retrofit2.Call; -import retrofit2.http.GET; -import retrofit2.http.Query; - -public interface PushshiftAPI { - @GET("reddit/comment/search/") - Call getRemovedComment(@Query("ids") String commentId); - - @GET("reddit/submission/search/") - Call getRemovedPost(@Query("ids") String postId); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java deleted file mode 100644 index 2a9a4711..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java +++ /dev/null @@ -1,339 +0,0 @@ -package ml.docilealligator.infinityforreddit.API; - -import java.util.Map; - -import okhttp3.MultipartBody; -import okhttp3.RequestBody; -import retrofit2.Call; -import retrofit2.http.DELETE; -import retrofit2.http.FieldMap; -import retrofit2.http.FormUrlEncoded; -import retrofit2.http.GET; -import retrofit2.http.HeaderMap; -import retrofit2.http.Multipart; -import retrofit2.http.POST; -import retrofit2.http.PUT; -import retrofit2.http.Part; -import retrofit2.http.PartMap; -import retrofit2.http.Path; -import retrofit2.http.Query; - -public interface RedditAPI { - @FormUrlEncoded - @POST("api/v1/access_token") - Call getAccessToken(@HeaderMap Map headers, @FieldMap Map params); - - @GET("r/{subredditName}/about.json?raw_json=1") - Call getSubredditData(@Path("subredditName") String subredditName); - - @GET("subreddits/mine/subscriber?raw_json=1") - Call getSubscribedThing(@Query("after") String lastItem, @HeaderMap Map headers); - - @GET("api/v1/me?raw_json=1") - Call getMyInfo(@HeaderMap Map headers); - - @FormUrlEncoded - @POST("api/vote") - Call voteThing(@HeaderMap Map headers, @FieldMap Map params); - - @GET("comments/{id}.json?raw_json=1") - Call getPostOauth(@Path("id") String id, @HeaderMap Map headers); - - @GET("comments/{id}.json?raw_json=1") - Call getPost(@Path("id") String id); - - @GET("{sortType}?raw_json=1") - Call getBestPosts(@Path("sortType") String sortType, @Query("after") String lastItem, @HeaderMap Map headers); - - @GET("{sortType}?raw_json=1") - Call getBestPosts(@Path("sortType") String sortType, @Query("t") String sortTime, - @Query("after") String lastItem, @HeaderMap Map headers); - - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") - Call getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType, - @Query("after") String lastItem, @HeaderMap Map headers); - - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") - Call getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType, - @Query("t") String sortTime, @Query("after") String lastItem, - @HeaderMap Map headers); - - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") - Call getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") String sortType, - @Query("after") String lastItem); - - @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") - Call getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") String sortType, - @Query("t") String sortTime, @Query("after") String lastItem); - - @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") - Call getUserPostsOauth(@Path("username") String username, @Path("where") String where, - @Query("after") String lastItem, @Query("sort") String sortType, @HeaderMap Map headers); - - @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") - Call getUserPostsOauth(@Path("username") String username, @Path("where") String where, - @Query("after") String lastItem, @Query("sort") String sortType, - @Query("t") String sortTime, @HeaderMap Map headers); - - @GET("user/{username}/submitted.json?raw_json=1&limit=25") - Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, - @Query("sort") String sortType); - - @GET("user/{username}/submitted.json?raw_json=1&limit=25") - Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, - @Query("sort") String sortType, @Query("t") String sortTime); - - @GET("user/{username}/about.json?raw_json=1") - Call getUserData(@Path("username") String username); - - @GET("user/{username}/comments.json?raw_json=1") - Call getUserComments(@Path("username") String username, @Query("after") String after, - @Query("sort") String sortType); - - @GET("user/{username}/comments.json?raw_json=1") - Call getUserComments(@Path("username") String username, @Query("after") String after, - @Query("sort") String sortType, @Query("t") String sortTime); - - @GET("user/{username}/comments.json?raw_json=1") - Call getUserCommentsOauth(@HeaderMap Map headers, @Path("username") String username, - @Query("after") String after, @Query("sort") String sortType); - - @GET("user/{username}/comments.json?raw_json=1") - Call getUserCommentsOauth(@HeaderMap Map headers, @Path("username") String username, - @Query("after") String after, @Query("sort") String sortType, - @Query("t") String sortTime); - - @GET("user/{username}/{where}.json?&type=comments&raw_json=1&limit=25") - Call getUserSavedCommentsOauth(@Path("username") String username, @Path("where") String where, - @Query("after") String lastItem, @Query("sort") String sortType, - @HeaderMap Map headers); - - @GET("user/{username}/{where}.json?&type=comments&raw_json=1&limit=25") - Call getUserSavedCommentsOauth(@Path("username") String username, @Path("where") String where, - @Query("after") String lastItem, @Query("sort") String sortType, - @Query("t") String sortTime, @HeaderMap Map headers); - - @FormUrlEncoded - @POST("api/subscribe") - Call subredditSubscription(@HeaderMap Map headers, @FieldMap Map params); - - @GET("/api/info.json?raw_json=1") - Call getInfo(@Query("id") String id); - - @GET("/api/info.json?raw_json=1") - Call getInfoOauth(@Query("id") String id, @HeaderMap Map headers); - - @GET("subreddits/search.json?raw_json=1") - Call searchSubreddits(@Query("q") String subredditName, @Query("after") String after, - @Query("sort") String sort, @Query("include_over_18") int nsfw, - @HeaderMap Map headers); - - @GET("search.json?raw_json=1&type=user") - Call searchUsers(@Query("q") String profileName, @Query("after") String after, - @Query("sort") String sort, @Query("include_over_18") int nsfw); - - @GET("search.json?include_over_18=1&raw_json=1&type=link") - Call searchPostsOauth(@Query("q") String query, @Query("after") String after, - @Query("sort") String sort, - @HeaderMap Map headers); - - @GET("search.json?include_over_18=1&raw_json=1&type=link") - Call searchPostsOauth(@Query("q") String query, @Query("after") String after, - @Query("sort") String sort, @Query("t") String sortTime, - @HeaderMap Map headers); - - @GET("search.json?include_over_18=1&raw_json=1&type=link") - Call searchPosts(@Query("q") String query, @Query("after") String after, - @Query("sort") String sort); - - @GET("search.json?include_over_18=1&raw_json=1&type=link") - Call searchPosts(@Query("q") String query, @Query("after") String after, - @Query("sort") String sort, @Query("t") String sortTime); - - @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") - Call searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, - @Query("q") String query, @Query("sort") String sort, - @Query("after") String after, - @HeaderMap Map headers); - - @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") - Call searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, - @Query("q") String query, @Query("sort") String sort, - @Query("t") String 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") - Call searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName, - @Query("q") String query, @Query("sort") String sort, - @Query("after") String after); - - @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") - Call searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName, - @Query("q") String query, @Query("sort") String sort, - @Query("t") String sortTime, @Query("after") String after); - - @FormUrlEncoded - @POST("api/comment") - Call sendCommentOrReplyToMessage(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("api/del") - Call delete(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("api/submit") - Call submit(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("api/media/asset.json?raw_json=1&gilding_detail=1") - Call uploadImage(@HeaderMap Map headers, @FieldMap Map params); - - @GET("r/{subredditName}/api/link_flair.json?raw_json=1") - Call getFlairs(@HeaderMap Map headers, @Path("subredditName") String subredditName); - - @GET("/r/{subredditName}/about/rules.json?raw_json=1") - Call getRules(@Path("subredditName") String subredditName); - - @GET("/comments/{id}/placeholder/{singleCommentId}.json?context=8&raw_json=1") - Call getPostAndCommentsSingleThreadByIdOauth(@Path("id") String id, @Path("singleCommentId") String singleCommentId, - @Query("sort") String sortType, - @HeaderMap Map headers); - - @GET("/comments/{id}.json?raw_json=1") - Call getPostAndCommentsByIdOauth(@Path("id") String id, @Query("sort") String sortType, - @HeaderMap Map headers); - - @GET("/comments/{id}/placeholder/{singleCommentId}.json?context=8&raw_json=1") - Call getPostAndCommentsSingleThreadById(@Path("id") String id, @Path("singleCommentId") String singleCommentId, - @Query("sort") String sortType); - - @GET("/comments/{id}.json?raw_json=1") - Call getPostAndCommentsById(@Path("id") String id, @Query("sort") String sortType); - - @Multipart - @POST(".") - Call uploadMediaToAWS(@PartMap() Map params, @Part() MultipartBody.Part file); - - @FormUrlEncoded - @POST("/api/editusertext") - Call editPostOrComment(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/marknsfw") - Call markNSFW(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/unmarknsfw") - Call unmarkNSFW(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/spoiler") - Call markSpoiler(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/unspoiler") - Call unmarkSpoiler(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("{subredditNamePrefixed}/api/selectflair") - Call selectFlair(@Path("subredditNamePrefixed") String subredditName, @HeaderMap Map headers, @FieldMap Map params); - - @GET("/message/{where}.json?raw_json=1") - Call getMessages(@HeaderMap Map headers, @Path("where") String where, @Query("after") String after); - - @FormUrlEncoded - @POST("/api/read_message") - Call readMessage(@HeaderMap Map headers, @FieldMap Map ids); - - @FormUrlEncoded - @POST("/api/save") - Call save(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/unsave") - Call unsave(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/hide") - Call hide(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/unhide") - Call unhide(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/favorite") - Call favoriteThing(@HeaderMap Map headers, @FieldMap Map params); - - @GET("/api/multi/mine") - Call getMyMultiReddits(@HeaderMap Map headers); - - @FormUrlEncoded - @POST("/api/multi/favorite?raw_json=1&gilding_detail=1") - Call favoriteMultiReddit(@HeaderMap Map headers, @FieldMap Map params); - - @GET("/api/multi/user/{username}") - Call getUserMultiReddits(@Path("username") String username); - - @GET("{multipath}?raw_json=1") - Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after); - - @GET("{multipath}?raw_json=1") - Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after, @Query("t") String sortTime); - - @GET("{multipath}.json?raw_json=1") - Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after, @Query("t") String sortTime, - @HeaderMap Map headers); - - @GET("{multipath}.json?raw_json=1") - Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, - @Query("after") String after, @HeaderMap Map headers); - - @FormUrlEncoded - @POST("/api/multi/multipath") - Call createMultiReddit(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @PUT("/api/multi/multipath") - Call updateMultiReddit(@HeaderMap Map headers, @FieldMap Map params); - - @DELETE("/api/multi/multipath") - Call deleteMultiReddit(@HeaderMap Map headers, @Query("multipath") String multipath); - - @GET("/api/multi/multipath/") - Call getMultiRedditInfo(@HeaderMap Map headers, @Query("multipath") String multipath); - - @FormUrlEncoded - @POST("/api/report") - Call report(@HeaderMap Map headers, @FieldMap Map params); - - @FormUrlEncoded - @POST("/api/compose") - Call composePrivateMessage(@HeaderMap Map headers, @FieldMap Map params); - - - @FormUrlEncoded - @POST("api/block_user") - Call blockUser(@HeaderMap Map headers, @FieldMap Map params); - - @GET("r/{subredditName}/api/user_flair_v2.json?raw_json=1") - Call getUserFlairs(@HeaderMap Map headers, @Path("subredditName") String subredditName); - - @FormUrlEncoded - @POST("/r/{subredditName}/api/selectflair?raw_json=1") - Call selectUserFlair(@HeaderMap Map headers, @FieldMap Map params, - @Path("subredditName") String subredditName); - - @FormUrlEncoded - @POST("api/v2/gold/gild") - Call awardThing(@HeaderMap Map headers, @FieldMap Map params); - - @GET("/r/random/comments.json?limit=1&raw_json=1") - Call getRandomPost(); - - @GET("/r/randnsfw/new.json?sort=new&t=all&limit=1&raw_json=1") - Call getRandomNSFWPost(); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java index 408d180d..19407839 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AccessTokenAuthenticator.java @@ -10,9 +10,9 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Account.Account; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import okhttp3.Authenticator; import okhttp3.Headers; import okhttp3.Request; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/Account.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Account/Account.java deleted file mode 100644 index 4cb202b5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/Account.java +++ /dev/null @@ -1,76 +0,0 @@ -package ml.docilealligator.infinityforreddit.Account; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.PrimaryKey; - -@Entity(tableName = "accounts") -public class Account { - @PrimaryKey - @NonNull - @ColumnInfo(name = "username") - private String username; - @ColumnInfo(name = "profile_image_url") - private String profileImageUrl; - @ColumnInfo(name = "banner_image_url") - private String bannerImageUrl; - @ColumnInfo(name = "karma") - private int karma; - @ColumnInfo(name = "access_token") - private String accessToken; - @ColumnInfo(name = "refresh_token") - private String refreshToken; - @ColumnInfo(name = "code") - private String code; - @ColumnInfo(name = "is_current_user") - private boolean isCurrentUser; - - public Account(@NonNull String username, String accessToken, String refreshToken, String code, - String profileImageUrl, String bannerImageUrl, int karma, boolean isCurrentUser) { - this.username = username; - this.accessToken = accessToken; - this.refreshToken = refreshToken; - this.code = code; - this.profileImageUrl = profileImageUrl; - this.bannerImageUrl = bannerImageUrl; - this.karma = karma; - this.isCurrentUser = isCurrentUser; - } - - public String getUsername() { - return username; - } - - public String getProfileImageUrl() { - return profileImageUrl; - } - - public String getBannerImageUrl() { - return bannerImageUrl; - } - - public int getKarma() { - return karma; - } - - public String getAccessToken() { - return accessToken; - } - - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - - public String getRefreshToken() { - return refreshToken; - } - - public String getCode() { - return code; - } - - public boolean isCurrentUser() { - return isCurrentUser; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountDao.java deleted file mode 100644 index be3dcd9d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountDao.java +++ /dev/null @@ -1,55 +0,0 @@ -package ml.docilealligator.infinityforreddit.Account; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -import java.util.List; - -@Dao -public interface AccountDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(Account account); - - @Query("SELECT * FROM accounts") - List getAllAccounts(); - - @Query("SELECT * FROM accounts WHERE is_current_user = 0") - List getAllNonCurrentAccounts(); - - @Query("UPDATE accounts SET is_current_user = 0 WHERE is_current_user = 1") - void markAllAccountsNonCurrent(); - - @Query("DELETE FROM accounts WHERE is_current_user = 1") - void deleteCurrentAccount(); - - @Query("DELETE FROM accounts") - void deleteAllAccounts(); - - @Query("SELECT * FROM accounts WHERE username = :username COLLATE NOCASE LIMIT 1") - LiveData getAccountLiveData(String username); - - @Query("SELECT * FROM accounts WHERE username = :username COLLATE NOCASE LIMIT 1") - Account getAccountData(String username); - - @Query("SELECT * FROM accounts WHERE is_current_user = 1 LIMIT 1") - Account getCurrentAccount(); - - @Query("SELECT * FROM accounts WHERE is_current_user = 1 LIMIT 1") - LiveData getCurrentAccountLiveData(); - - @Query("UPDATE accounts SET profile_image_url = :profileImageUrl, banner_image_url = :bannerImageUrl, " + - "karma = :karma WHERE username = :username") - void updateAccountInfo(String username, String profileImageUrl, String bannerImageUrl, int karma); - - @Query("SELECT * FROM accounts WHERE is_current_user = 0 ORDER BY username COLLATE NOCASE ASC") - LiveData> getAccountsExceptCurrentAccountLiveData(); - - @Query("UPDATE accounts SET is_current_user = 1 WHERE username = :username") - void markAccountCurrent(String username); - - @Query("UPDATE accounts SET access_token = :accessToken WHERE username = :username") - void changeAccessToken(String username, String accessToken); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountRepository.java deleted file mode 100644 index 70fccd02..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountRepository.java +++ /dev/null @@ -1,48 +0,0 @@ -package ml.docilealligator.infinityforreddit.Account; - -import android.os.AsyncTask; - -import androidx.lifecycle.LiveData; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class AccountRepository { - private AccountDao mAccountDao; - private LiveData> mAccountsExceptCurrentAccountLiveData; - private LiveData mCurrentAccountLiveData; - - AccountRepository(RedditDataRoomDatabase redditDataRoomDatabase, String username) { - mAccountDao = redditDataRoomDatabase.accountDao(); - mAccountsExceptCurrentAccountLiveData = mAccountDao.getAccountsExceptCurrentAccountLiveData(); - mCurrentAccountLiveData = mAccountDao.getCurrentAccountLiveData(); - } - - public LiveData> getAccountsExceptCurrentAccountLiveData() { - return mAccountsExceptCurrentAccountLiveData; - } - - public LiveData getCurrentAccountLiveData() { - return mCurrentAccountLiveData; - } - - public void insert(Account Account) { - new InsertAsyncTask(mAccountDao).execute(Account); - } - - private static class InsertAsyncTask extends AsyncTask { - - private AccountDao mAsyncTaskDao; - - InsertAsyncTask(AccountDao dao) { - mAsyncTaskDao = dao; - } - - @Override - protected Void doInBackground(final Account... params) { - mAsyncTaskDao.insert(params[0]); - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountViewModel.java deleted file mode 100644 index 0eab1570..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Account/AccountViewModel.java +++ /dev/null @@ -1,58 +0,0 @@ -package ml.docilealligator.infinityforreddit.Account; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class AccountViewModel extends AndroidViewModel { - private AccountRepository mAccountRepository; - private LiveData> mAccountsExceptCurrentAccountLiveData; - private LiveData mCurrentAccountLiveData; - - public AccountViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String id) { - super(application); - mAccountRepository = new AccountRepository(redditDataRoomDatabase, id); - mAccountsExceptCurrentAccountLiveData = mAccountRepository.getAccountsExceptCurrentAccountLiveData(); - mCurrentAccountLiveData = mAccountRepository.getCurrentAccountLiveData(); - } - - public LiveData> getAccountsExceptCurrentAccountLiveData() { - return mAccountsExceptCurrentAccountLiveData; - } - - public LiveData getCurrentAccountLiveData() { - return mCurrentAccountLiveData; - } - - public void insert(Account userData) { - mAccountRepository.insert(userData); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - - @NonNull - private final Application mApplication; - private final RedditDataRoomDatabase mRedditDataRoomDatabase; - private final String mUsername; - - public Factory(@NonNull Application application, RedditDataRoomDatabase redditDataRoomDatabase, String username) { - mApplication = application; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mUsername = username; - } - - @Override - public T create(Class modelClass) { - //noinspection unchecked - return (T) new AccountViewModel(mApplication, mRedditDataRoomDatabase, mUsername); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountPostsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountPostsActivity.java deleted file mode 100644 index aa8cff71..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountPostsActivity.java +++ /dev/null @@ -1,314 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -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.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class AccountPostsActivity extends BaseActivity implements SortTypeSelectionCallback, - PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { - - static final String EXTRA_USER_WHERE = "EUW"; - - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String FRAGMENT_OUT_STATE = "FOS"; - - @BindView(R.id.coordinator_layout_account_posts_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.collapsing_toolbar_layout_account_posts_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.appbar_layout_account_posts_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_account_posts_activity) - Toolbar toolbar; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean isInLazyMode = false; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String mUserWhere; - private Fragment mFragment; - private Menu mMenu; - private AppBarLayout.LayoutParams params; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_account_posts); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - } - } - - mUserWhere = getIntent().getExtras().getString(EXTRA_USER_WHERE); - if (mUserWhere.equals(PostDataSource.USER_WHERE_UPVOTED)) { - toolbar.setTitle(R.string.upvoted); - } else if (mUserWhere.equals(PostDataSource.USER_WHERE_DOWNVOTED)) { - toolbar.setTitle(R.string.downvoted); - } else if (mUserWhere.equals(PostDataSource.USER_WHERE_HIDDEN)) { - toolbar.setTitle(R.string.hidden); - } else if (mUserWhere.equals(PostDataSource.USER_WHERE_GILDED)) { - toolbar.setTitle(R.string.gilded); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_account_posts_activity, mFragment).commit(); - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndInitializeFragment(); - } - } else { - getCurrentAccountAndInitializeFragment(); - } - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mFragment != null) { - return ((FragmentCommunicator) mFragment).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()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - private void getCurrentAccountAndInitializeFragment() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - initializeFragment(); - }).execute(); - } - - private void initializeFragment() { - mFragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); - bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountName); - bundle.putString(PostFragment.EXTRA_USER_WHERE, mUserWhere); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - mFragment.setArguments(bundle); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_account_posts_activity, mFragment).commit(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.account_posts_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_posts_activity); - if (isInLazyMode) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } else { - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_refresh_account_posts_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_account_posts_activity).setTitle(R.string.action_start_lazy_mode); - } - if (mFragment != null) { - ((PostFragment) mFragment).refresh(); - } - return true; - case R.id.action_lazy_mode_account_posts_activity: - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_posts_activity); - if (isInLazyMode) { - ((FragmentCommunicator) mFragment).stopLazyMode(); - isInLazyMode = false; - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } else { - if (((FragmentCommunicator) mFragment).startLazyMode()) { - isInLazyMode = true; - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } - } - return true; - case R.id.action_change_post_layout_account_posts_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - case android.R.id.home: - finish(); - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Override - public void sortTypeSelected(SortType sortType) { - if (mFragment != null) { - ((PostFragment) mFragment).changeSortType(sortType); - } - } - - @Override - public void sortTypeSelected(String sortType) { - - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Subscribe - public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { - ((FragmentCommunicator) mFragment).changeNSFW(changeNSFWEvent.nsfw); - } - - @Override - public void postLayoutSelected(int postLayout) { - if (mFragment != null) { - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + mAccountName, postLayout).apply(); - ((FragmentCommunicator) mFragment).changePostLayout(postLayout); - } - } - - @Override - public void onLongPress() { - if (mFragment != null) { - ((PostFragment) mFragment).goBackToTop(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountSavedThingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountSavedThingActivity.java deleted file mode 100644 index d278848c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/AccountSavedThingActivity.java +++ /dev/null @@ -1,440 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -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.FragmentManager; -import androidx.lifecycle.Lifecycle; -import androidx.viewpager2.adapter.FragmentStateAdapter; -import androidx.viewpager2.widget.ViewPager2; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.CommentsListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class AccountSavedThingActivity extends BaseActivity implements ActivityToolbarInterface, - PostLayoutBottomSheetFragment.PostLayoutSelectionCallback { - - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - - @BindView(R.id.coordinator_layout_account_saved_thing_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.collapsing_toolbar_layout_account_saved_thing_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.appbar_layout_account_saved_thing_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_account_saved_thing_activity) - Toolbar toolbar; - @BindView(R.id.tab_layout_tab_layout_account_saved_thing_activity_activity) - TabLayout tabLayout; - @BindView(R.id.view_pager_account_saved_thing_activity) - ViewPager2 viewPager2; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private FragmentManager fragmentManager; - private SectionsPagerAdapter sectionsPagerAdapter; - private SlidrInterface mSlidrInterface; - private Menu mMenu; - private AppBarLayout.LayoutParams params; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private boolean isInLazyMode = false; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_account_saved_thing); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - } - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - - fragmentManager = getSupportFragmentManager(); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndInitializeViewPager(); - } else { - initializeViewPager(); - } - } else { - getCurrentAccountAndInitializeViewPager(); - } - } - - @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()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - applyTabLayoutTheme(tabLayout); - } - - private void getCurrentAccountAndInitializeViewPager() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - initializeViewPager(); - }).execute(); - } - - private void initializeViewPager() { - sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); - viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(2); - viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); - new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { - switch (position) { - case 0: - tab.setText(R.string.posts); - break; - case 1: - tab.setText(R.string.comments); - 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.account_saved_thing_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity); - if (isInLazyMode) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } else { - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_refresh_account_saved_thing_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity).setTitle(R.string.action_start_lazy_mode); - } - sectionsPagerAdapter.refresh(); - return true; - case R.id.action_lazy_mode_account_saved_thing_activity: - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity); - if (isInLazyMode) { - isInLazyMode = false; - sectionsPagerAdapter.stopLazyMode(); - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = true; - if (sectionsPagerAdapter.startLazyMode()) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - appBarLayout.setExpanded(false); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = false; - } - } - return true; - case R.id.action_change_post_layout_account_saved_thing_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - } - - @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(); - } - } - - private void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - private void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } - - @Override - public void postLayoutSelected(int postLayout) { - if (sectionsPagerAdapter != null) { - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + mAccountName, postLayout).apply(); - sectionsPagerAdapter.changePostLayout(postLayout); - } - } - - private class SectionsPagerAdapter extends FragmentStateAdapter { - - SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { - super(fm, lifecycle); - } - - @NonNull - @Override - public Fragment createFragment(int position) { - if (position == 0) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); - bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountName); - bundle.putString(PostFragment.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SAVED); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } - CommentsListingFragment fragment = new CommentsListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(CommentsListingFragment.EXTRA_USERNAME, mAccountName); - bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, true); - 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(); - } - } - - boolean startLazyMode() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof FragmentCommunicator) { - return ((FragmentCommunicator) fragment).startLazyMode(); - } - return false; - } - - void stopLazyMode() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof FragmentCommunicator) { - ((FragmentCommunicator) fragment).stopLazyMode(); - } - } - - public void changeNSFW(boolean nsfw) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeNSFW(nsfw); - } - } - - public void changePostLayout(int postLayout) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changePostLayout(postLayout); - } - } - - - public void goBackToTop() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).goBackToTop(); - } else if (fragment instanceof CommentsListingFragment) { - ((CommentsListingFragment) fragment).goBackToTop(); - } - } - - @Override - public int getItemCount() { - return 2; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java deleted file mode 100644 index 2d9c17d9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/BaseActivity.java +++ /dev/null @@ -1,326 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.annotation.SuppressLint; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Color; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; - -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.appcompat.view.menu.MenuItemImpl; -import androidx.appcompat.widget.Toolbar; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.recyclerview.widget.RecyclerView; -import androidx.viewpager2.widget.ViewPager2; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.tabs.TabLayout; - -import java.lang.reflect.Field; - -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Font.ContentFontFamily; -import ml.docilealligator.infinityforreddit.Font.ContentFontStyle; -import ml.docilealligator.infinityforreddit.Font.FontFamily; -import ml.docilealligator.infinityforreddit.Font.FontStyle; -import ml.docilealligator.infinityforreddit.Font.TitleFontFamily; -import ml.docilealligator.infinityforreddit.Font.TitleFontStyle; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; - -public abstract class BaseActivity extends AppCompatActivity { - private boolean immersiveInterface; - private boolean changeStatusBarIconColor; - private boolean transparentStatusBarAfterToolbarCollapsed; - private boolean hasDrawerLayout = false; - private boolean isImmersiveInterfaceApplicable = true; - private int systemVisibilityToolbarExpanded = 0; - private int systemVisibilityToolbarCollapsed = 0; - private CustomThemeWrapper customThemeWrapper; - - @Override - protected void onCreate(@Nullable Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - customThemeWrapper = getCustomThemeWrapper(); - - SharedPreferences mSharedPreferences = getDefaultSharedPreferences(); - boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; - int systemThemeType = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.THEME_KEY, "2")); - immersiveInterface = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true); - switch (systemThemeType) { - case 0: - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); - getTheme().applyStyle(R.style.Theme_Normal, true); - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); - break; - case 1: - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); - if(mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { - getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); - } else { - getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); - } - break; - case 2: - if (systemDefault) { - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM); - } else { - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_AUTO_BATTERY); - } - if((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) { - getTheme().applyStyle(R.style.Theme_Normal, true); - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); - } else { - if(mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { - getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); - } else { - getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); - } - } - } - - boolean userDefinedChangeSatusBarIconColorInImmersiveInterface = - customThemeWrapper.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface(); - if (immersiveInterface && isImmersiveInterfaceApplicable) { - changeStatusBarIconColor = userDefinedChangeSatusBarIconColorInImmersiveInterface; - } else { - changeStatusBarIconColor = false; - } - - getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(TitleFontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); - - Window window = getWindow(); - View decorView = window.getDecorView(); - boolean isLightStatusbar = customThemeWrapper.isLightStatusBar(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - boolean isLightNavBar = customThemeWrapper.isLightNavBar(); - if (isLightStatusbar) { - if (isLightNavBar) { - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - if (changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } else { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } - } else { - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - if (!changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - } - } else { - if (isLightNavBar) { - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - if (changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } - } else { - if (changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - } - } - decorView.setSystemUiVisibility(systemVisibilityToolbarExpanded); - if (!(immersiveInterface && isImmersiveInterfaceApplicable)) { - window.setNavigationBarColor(customThemeWrapper.getNavBarColor()); - if (!hasDrawerLayout) { - window.setStatusBarColor(customThemeWrapper.getColorPrimaryDark()); - } - } else { - window.setNavigationBarColor(Color.TRANSPARENT); - window.setStatusBarColor(Color.TRANSPARENT); - } - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (isLightStatusbar) { - decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - if (!changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - } else if (changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - } - } - - protected abstract SharedPreferences getDefaultSharedPreferences(); - - protected abstract CustomThemeWrapper getCustomThemeWrapper(); - - protected abstract void applyCustomTheme(); - - protected boolean isChangeStatusBarIconColor() { - return changeStatusBarIconColor; - } - - protected int getSystemVisibilityToolbarExpanded() { - return systemVisibilityToolbarExpanded; - } - - protected int getSystemVisibilityToolbarCollapsed() { - return systemVisibilityToolbarCollapsed; - } - - public boolean isImmersiveInterface() { - return immersiveInterface; - } - - protected void setToolbarGoToTop(Toolbar toolbar) { - toolbar.setOnLongClickListener(view -> { - if (BaseActivity.this instanceof ActivityToolbarInterface) { - ((ActivityToolbarInterface) BaseActivity.this).onLongPress(); - } - return true; - }); - } - - protected void adjustToolbar(Toolbar toolbar) { - int statusBarResourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); - if (statusBarResourceId > 0) { - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); - params.topMargin = getResources().getDimensionPixelSize(statusBarResourceId); - toolbar.setLayoutParams(params); - } - } - - protected void addOnOffsetChangedListener(AppBarLayout appBarLayout) { - View decorView = getWindow().getDecorView(); - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { - if (state == State.COLLAPSED) { - decorView.setSystemUiVisibility(getSystemVisibilityToolbarCollapsed()); - } else if (state == State.EXPANDED) { - decorView.setSystemUiVisibility(getSystemVisibilityToolbarExpanded()); - } - } - }); - } - - public int getNavBarHeight() { - if (isImmersiveInterfaceApplicable && immersiveInterface && getDefaultSharedPreferences().getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_IGNORE_NAV_BAR_KEY, false)) { - return 0; - } - - Resources resources = getResources(); - int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); - if (navBarResourceId > 0) { - return resources.getDimensionPixelSize(navBarResourceId); - } - return 0; - } - - protected void setTransparentStatusBarAfterToolbarCollapsed() { - this.transparentStatusBarAfterToolbarCollapsed = true; - } - - protected void setHasDrawerLayout() { - hasDrawerLayout = true; - } - - public void setImmersiveModeNotApplicable() { - isImmersiveInterfaceApplicable = false; - } - - protected void applyAppBarLayoutAndToolbarTheme(AppBarLayout appBarLayout, Toolbar toolbar) { - appBarLayout.setBackgroundColor(customThemeWrapper.getColorPrimary()); - toolbar.setTitleTextColor(customThemeWrapper.getToolbarPrimaryTextAndIconColor()); - toolbar.setSubtitleTextColor(customThemeWrapper.getToolbarSecondaryTextColor()); - if (toolbar.getNavigationIcon() != null) { - toolbar.getNavigationIcon().setColorFilter(customThemeWrapper.getToolbarPrimaryTextAndIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); - } - if (toolbar.getOverflowIcon() != null) { - toolbar.getOverflowIcon().setColorFilter(customThemeWrapper.getToolbarPrimaryTextAndIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); - } - } - - @SuppressLint("RestrictedApi") - protected boolean applyMenuItemTheme(Menu menu) { - if (customThemeWrapper != null) { - int size = Math.min(menu.size(), 2); - for (int i = 0; i < size; i++) { - MenuItem item = menu.getItem(i); - if (((MenuItemImpl) item).requestsActionButton()) { - Drawable drawable = item.getIcon(); - if (drawable != null) { - DrawableCompat.setTint(drawable, customThemeWrapper.getToolbarPrimaryTextAndIconColor()); - item.setIcon(drawable); - } - } - } - } - return true; - } - - protected void applyTabLayoutTheme(TabLayout tabLayout) { - int toolbarAndTabBackgroundColor = customThemeWrapper.getColorPrimary(); - tabLayout.setBackgroundColor(toolbarAndTabBackgroundColor); - tabLayout.setSelectedTabIndicatorColor(customThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabIndicator()); - tabLayout.setTabTextColors(customThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor(), - customThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor()); - } - - protected void applyFABTheme(FloatingActionButton fab) { - fab.setBackgroundTintList(ColorStateList.valueOf(customThemeWrapper.getColorPrimaryLightTheme())); - fab.setImageTintList(ColorStateList.valueOf(customThemeWrapper.getFABIconColor())); - } - - protected void fixViewPager2Sensitivity(ViewPager2 viewPager2) { - try { - Field recyclerViewField = ViewPager2.class.getDeclaredField("mRecyclerView"); - recyclerViewField.setAccessible(true); - - RecyclerView recyclerView = (RecyclerView) recyclerViewField.get(viewPager2); - - Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop"); - touchSlopField.setAccessible(true); - - Object touchSlopBox = touchSlopField.get(recyclerView); - if (touchSlopBox != null) { - int touchSlop = (int) touchSlopBox; - touchSlopField.set(recyclerView, touchSlop * 4); - } - } catch (NoSuchFieldException | IllegalAccessException ignore) {} - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CommentActivity.java deleted file mode 100644 index 31e0a35f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CommentActivity.java +++ /dev/null @@ -1,433 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.text.Spanned; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; - -import org.commonmark.ext.gfm.tables.TableBlock; -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 io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.recycler.MarkwonAdapter; -import io.noties.markwon.recycler.table.TableEntry; -import io.noties.markwon.recycler.table.TableEntryPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import ml.docilealligator.infinityforreddit.Adapter.MarkdownBottomBarRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.CopyTextBottomSheetFragment; -import ml.docilealligator.infinityforreddit.Comment.Comment; -import ml.docilealligator.infinityforreddit.Comment.SendComment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Retrofit; - -public class CommentActivity extends BaseActivity { - - public static final String EXTRA_COMMENT_PARENT_TEXT_KEY = "ECPTK"; - public static final String EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY = "ECPTMK"; - public static final String EXTRA_COMMENT_PARENT_BODY_KEY = "ECPBK"; - public static final String EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY = "ECPBMK"; - public static final String EXTRA_PARENT_FULLNAME_KEY = "EPFK"; - public static final String EXTRA_PARENT_DEPTH_KEY = "EPDK"; - public static final String EXTRA_PARENT_POSITION_KEY = "EPPK"; - public static final String EXTRA_IS_REPLYING_KEY = "EIRK"; - public static final String RETURN_EXTRA_COMMENT_DATA_KEY = "RECDK"; - public static final int WRITE_COMMENT_REQUEST_CODE = 1; - - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - - @BindView(R.id.coordinator_layout_comment_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_comment_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_comment_activity) - Toolbar toolbar; - @BindView(R.id.comment_parent_markwon_view_comment_activity) - TextView commentParentMarkwonView; - @BindView(R.id.divider_comment_activity) - View divider; - @BindView(R.id.content_markdown_view_comment_activity) - RecyclerView contentMarkdownRecyclerView; - @BindView(R.id.comment_edit_text_comment_activity) - EditText commentEditText; - @BindView(R.id.markdown_bottom_bar_recycler_view_comment_activity) - RecyclerView markdownBottomBarRecyclerView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String parentFullname; - private int parentDepth; - private int parentPosition; - private boolean isSubmitting = false; - private boolean isReplying; - private int markdownColor; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_comment); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (savedInstanceState == null) { - getCurrentAccount(); - } else { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - } - - Intent intent = getIntent(); - String parentTextMarkdown = intent.getStringExtra(EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY); - String parentText = intent.getStringExtra(EXTRA_COMMENT_PARENT_TEXT_KEY); - CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); - - int linkColor = mCustomThemeWrapper.getLinkColor(); - Markwon markwon = Markwon.builder(this) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(CommentActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .build(); - if (parentTextMarkdown != null) { - commentParentMarkwonView.setOnLongClickListener(view -> { - Utils.hideKeyboard(CommentActivity.this); - Bundle bundle = new Bundle(); - if (parentText == null) { - bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, parentTextMarkdown); - } else { - bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, parentText); - bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, parentTextMarkdown); - } - copyTextBottomSheetFragment.setArguments(bundle); - copyTextBottomSheetFragment.show(getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); - return true; - }); - markwon.setMarkdown(commentParentMarkwonView, parentTextMarkdown); - } - String parentBodyMarkdown = intent.getStringExtra(EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY); - String parentBody = intent.getStringExtra(EXTRA_COMMENT_PARENT_BODY_KEY); - if (parentBodyMarkdown != null && !parentBodyMarkdown.equals("")) { - contentMarkdownRecyclerView.setVisibility(View.VISIBLE); - contentMarkdownRecyclerView.setNestedScrollingEnabled(false); - Markwon postBodyMarkwon = Markwon.builder(this) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - textView.setTextColor(markdownColor); - textView.setOnLongClickListener(view -> { - Utils.hideKeyboard(CommentActivity.this); - Bundle bundle = new Bundle(); - bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, parentBody); - bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, parentBodyMarkdown); - copyTextBottomSheetFragment.setArguments(bundle); - copyTextBottomSheetFragment.show(getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); - return true; - }); - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(CommentActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .usePlugin(TableEntryPlugin.create(this)) - .build(); - MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); - contentMarkdownRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - contentMarkdownRecyclerView.setAdapter(markwonAdapter); - markwonAdapter.setMarkdown(postBodyMarkwon, parentBodyMarkdown); - markwonAdapter.notifyDataSetChanged(); - } - parentFullname = intent.getStringExtra(EXTRA_PARENT_FULLNAME_KEY); - parentDepth = intent.getExtras().getInt(EXTRA_PARENT_DEPTH_KEY); - parentPosition = intent.getExtras().getInt(EXTRA_PARENT_POSITION_KEY); - isReplying = intent.getExtras().getBoolean(EXTRA_IS_REPLYING_KEY); - if (isReplying) { - toolbar.setTitle(getString(R.string.comment_activity_label_is_replying)); - } - - setSupportActionBar(toolbar); - - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, commentEditText, item); - }); - - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, - LinearLayoutManager.HORIZONTAL, false)); - markdownBottomBarRecyclerView.setAdapter(adapter); - - commentEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - commentParentMarkwonView.setTextColor(mCustomThemeWrapper.getCommentColor()); - divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); - commentEditText.setTextColor(mCustomThemeWrapper.getCommentColor()); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - commentEditText.setHintTextColor(secondaryTextColor); - markdownColor = secondaryTextColor; - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - }).execute(); - } - - @Override - protected void onPause() { - super.onPause(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.hideSoftInputFromWindow(commentEditText.getWindowToken(), 0); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.comment_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - int itemId = item.getItemId(); - if (itemId == android.R.id.home) { - onBackPressed(); - return true; - } else if (itemId == R.id.action_preview_comment_activity) { - Intent intent = new Intent(this, FullMarkdownActivity.class); - intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, commentEditText.getText().toString()); - startActivity(intent); - } else if (itemId == R.id.action_send_comment_activity) { - if (!isSubmitting) { - isSubmitting = true; - if (commentEditText.getText() == null || commentEditText.getText().toString().equals("")) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.comment_content_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - item.setEnabled(false); - item.getIcon().setAlpha(130); - Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_comment, Snackbar.LENGTH_INDEFINITE); - sendingSnackbar.show(); - - SendComment.sendComment(commentEditText.getText().toString(), parentFullname, parentDepth, - getResources().getConfiguration().locale, mOauthRetrofit, - mAccessToken, - new SendComment.SendCommentListener() { - @Override - public void sendCommentSuccess(Comment comment) { - isSubmitting = false; - item.setEnabled(true); - item.getIcon().setAlpha(255); - Toast.makeText(CommentActivity.this, R.string.send_comment_success, Toast.LENGTH_SHORT).show(); - Intent returnIntent = new Intent(); - returnIntent.putExtra(RETURN_EXTRA_COMMENT_DATA_KEY, comment); - returnIntent.putExtra(EXTRA_PARENT_FULLNAME_KEY, parentFullname); - if (isReplying) { - returnIntent.putExtra(EXTRA_PARENT_POSITION_KEY, parentPosition); - } - setResult(RESULT_OK, returnIntent); - finish(); - } - - @Override - public void sendCommentFailed(@Nullable String errorMessage) { - isSubmitting = false; - sendingSnackbar.dismiss(); - item.setEnabled(true); - item.getIcon().setAlpha(255); - - if (errorMessage == null || !errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.send_comment_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); - } - } - }); - } - return true; - } - - return false; - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - } - - @Override - public void onBackPressed() { - if (isSubmitting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_comment_detail); - } else { - if (commentEditText.getText().toString().equals("")) { - finish(); - } else { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CreateMultiRedditActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CreateMultiRedditActivity.java deleted file mode 100644 index 3fff7dae..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CreateMultiRedditActivity.java +++ /dev/null @@ -1,241 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.Switch; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.snackbar.Snackbar; -import com.r0adkll.slidr.Slidr; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.MultiReddit.CreateMultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiRedditJSONModel; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class CreateMultiRedditActivity extends BaseActivity { - - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 1; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String SELECTED_SUBREDDITS_STATE = "SSS"; - @BindView(R.id.coordinator_layout_create_multi_reddit_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_create_multi_reddit_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_create_multi_reddit_activity) - Toolbar toolbar; - @BindView(R.id.multi_reddit_name_edit_text_create_multi_reddit_activity) - EditText nameEditText; - @BindView(R.id.divider_1_create_multi_reddit_activity) - View divider1; - @BindView(R.id.description_edit_text_create_multi_reddit_activity) - EditText descriptionEditText; - @BindView(R.id.divider_2_create_multi_reddit_activity) - View divider2; - @BindView(R.id.visibility_wrapper_linear_layout_create_multi_reddit_activity) - LinearLayout visibilityLinearLayout; - @BindView(R.id.visibility_text_view_create_multi_reddit_activity) - TextView visibilityTextView; - @BindView(R.id.visibility_switch_create_multi_reddit_activity) - Switch visibilitySwitch; - @BindView(R.id.select_subreddit_text_view_create_multi_reddit_activity) - TextView selectSubredditTextView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private ArrayList mSubreddits; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_create_multi_reddit); - - ButterKnife.bind(this); - - 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); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - mSubreddits = savedInstanceState.getStringArrayList(SELECTED_SUBREDDITS_STATE); - - if (!mNullAccessToken && mAccountName == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - } else { - mSubreddits = new ArrayList<>(); - getCurrentAccountAndBindView(); - } - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - Toast.makeText(this, R.string.logged_out, Toast.LENGTH_SHORT).show(); - finish(); - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - bindView(); - } - }).execute(); - } - - private void bindView() { - selectSubredditTextView.setOnClickListener(view -> { - Intent intent = new Intent(CreateMultiRedditActivity.this, SelectedSubredditsActivity.class); - intent.putStringArrayListExtra(SelectedSubredditsActivity.EXTRA_SELECTED_SUBREDDITS, mSubreddits); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.create_multi_reddit_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_save_create_multi_reddit_activity: - if (mAccountName == null || mAccessToken == null) { - Snackbar.make(coordinatorLayout, R.string.something_went_wrong, Snackbar.LENGTH_SHORT).show(); - return true; - } - if (nameEditText.getText() == null || nameEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.no_multi_reddit_name, Snackbar.LENGTH_SHORT).show(); - return true; - } - - String jsonModel = new MultiRedditJSONModel(nameEditText.getText().toString(), descriptionEditText.getText().toString(), - visibilitySwitch.isChecked(), mSubreddits).createJSONModel(); - CreateMultiReddit.createMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, - "/user/" + mAccountName + "/m/" + nameEditText.getText().toString(), - jsonModel, new CreateMultiReddit.CreateMultiRedditListener() { - @Override - public void success() { - finish(); - } - - @Override - public void failed(int errorCode) { - if (errorCode == 409) { - Snackbar.make(coordinatorLayout, R.string.duplicate_multi_reddit, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, R.string.create_multi_reddit_failed, Snackbar.LENGTH_SHORT).show(); - } - } - }); - } - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE && resultCode == RESULT_OK) { - if (data != null) { - mSubreddits = data.getStringArrayListExtra( - SubredditMultiselectionActivity.EXTRA_RETURN_SELECTED_SUBREDDITS); - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putStringArrayList(SELECTED_SUBREDDITS_STATE, mSubreddits); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - nameEditText.setTextColor(primaryTextColor); - nameEditText.setHintTextColor(secondaryTextColor); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - descriptionEditText.setTextColor(primaryTextColor); - descriptionEditText.setHintTextColor(secondaryTextColor); - visibilityTextView.setTextColor(primaryTextColor); - selectSubredditTextView.setTextColor(primaryTextColor); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemeListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemeListingActivity.java deleted file mode 100644 index 4b7fc12c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemeListingActivity.java +++ /dev/null @@ -1,331 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; -import com.google.gson.Gson; -import com.google.gson.JsonSyntaxException; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.CustomThemeListingRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.ChangeThemeNameAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.DeleteThemeAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCustomThemeAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertCustomThemeAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.CreateThemeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.CustomThemeOptionsBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeViewModel; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; - -import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN; - -public class CustomThemeListingActivity extends BaseActivity implements - CustomThemeOptionsBottomSheetFragment.CustomThemeOptionsBottomSheetFragmentListener, - CreateThemeBottomSheetFragment.SelectBaseThemeBottomSheetFragmentListener { - - @BindView(R.id.coordinator_layout_custom_theme_listing_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_customize_theme_listing_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_customize_theme_listing_activity) - Toolbar toolbar; - @BindView(R.id.recycler_view_customize_theme_listing_activity) - RecyclerView recyclerView; - @BindView(R.id.fab_custom_theme_listing_activity) - FloatingActionButton fab; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - @Inject - RedditDataRoomDatabase redditDataRoomDatabase; - @Inject - CustomThemeWrapper customThemeWrapper; - @Inject - @Named("light_theme") - SharedPreferences lightThemeSharedPreferences; - @Inject - @Named("dark_theme") - SharedPreferences darkThemeSharedPreferences; - @Inject - @Named("amoled_theme") - SharedPreferences amoledThemeSharedPreferences; - public CustomThemeViewModel customThemeViewModel; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_custom_theme_listing); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - CustomThemeListingRecyclerViewAdapter adapter = new CustomThemeListingRecyclerViewAdapter(this, - CustomThemeWrapper.getPredefinedThemes(this)); - recyclerView.setAdapter(adapter); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (dy > 0) { - fab.hide(); - } else if (dy < 0) { - fab.show(); - } - } - }); - - customThemeViewModel = new ViewModelProvider(this, - new CustomThemeViewModel.Factory(redditDataRoomDatabase)) - .get(CustomThemeViewModel.class); - customThemeViewModel.getAllCustomThemes().observe(this, adapter::setUserThemes); - - fab.setOnClickListener(view -> { - CreateThemeBottomSheetFragment createThemeBottomSheetFragment = new CreateThemeBottomSheetFragment(); - createThemeBottomSheetFragment.show(getSupportFragmentManager(), createThemeBottomSheetFragment.getTag()); - }); - } - - @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() { - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - @Override - public void changeName(String oldThemeName) { - View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); - EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); - themeNameEditText.setText(oldThemeName); - themeNameEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.edit_theme_name) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); - } - new ChangeThemeNameAsyncTask(redditDataRoomDatabase, oldThemeName, themeNameEditText.getText().toString()).execute(); - }) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); - } - }) - .show(); - } - - @Override - public void shareTheme(String themeName) { - new GetCustomThemeAsyncTask(redditDataRoomDatabase, themeName, customTheme -> { - if (customTheme != null) { - String jsonModel = customTheme.getJSONModel(); - ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard != null) { - ClipData clip = ClipData.newPlainText("simple text", jsonModel); - clipboard.setPrimaryClip(clip); - Snackbar.make(coordinatorLayout, R.string.theme_copied, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, R.string.copy_theme_faied, Snackbar.LENGTH_SHORT).show(); - } - } else { - Snackbar.make(coordinatorLayout, R.string.cannot_find_theme, Snackbar.LENGTH_SHORT).show(); - } - }).execute(); - } - - @Override - public void delete(String themeName) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.delete_theme) - .setMessage(getString(R.string.delete_theme_dialog_message, themeName)) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> new DeleteThemeAsyncTask(redditDataRoomDatabase, themeName, (isLightTheme, isDarkTheme, isAmoledTheme) -> { - if (isLightTheme) { - CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences( - CustomThemeWrapper.getIndigo(CustomThemeListingActivity.this), lightThemeSharedPreferences); - } - if (isDarkTheme) { - CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences( - CustomThemeWrapper.getIndigoDark(CustomThemeListingActivity.this), darkThemeSharedPreferences); - } - if (isAmoledTheme) { - CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences( - CustomThemeWrapper.getIndigoAmoled(CustomThemeListingActivity.this), amoledThemeSharedPreferences); - } - EventBus.getDefault().post(new RecreateActivityEvent()); - }).execute()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - public void shareTheme(CustomTheme customTheme) { - if (customTheme != null) { - String jsonModel = customTheme.getJSONModel(); - ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard != null) { - ClipData clip = ClipData.newPlainText("simple text", jsonModel); - clipboard.setPrimaryClip(clip); - Snackbar.make(coordinatorLayout, R.string.theme_copied, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, R.string.copy_theme_faied, Snackbar.LENGTH_SHORT).show(); - } - } else { - Snackbar.make(coordinatorLayout, R.string.cannot_find_theme, Snackbar.LENGTH_SHORT).show(); - } - } - - @Subscribe - public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { - recreate(); - } - - @Override - public void importTheme() { - ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard != null) { - // If it does contain data, decide if you can handle the data. - if (!clipboard.hasPrimaryClip()) { - Snackbar.make(coordinatorLayout, R.string.no_data_in_clipboard, Snackbar.LENGTH_SHORT).show(); - } else if (clipboard.getPrimaryClipDescription() != null && - !clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) { - // since the clipboard has data but it is not plain text - Snackbar.make(coordinatorLayout, R.string.no_data_in_clipboard, Snackbar.LENGTH_SHORT).show(); - } else if (clipboard.getPrimaryClip() != null) { - ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0); - String json = item.getText().toString(); - try { - CustomTheme customTheme = new Gson().fromJson(json, CustomTheme.class); - checkDuplicateAndImportTheme(customTheme, true); - } catch (JsonSyntaxException e) { - Snackbar.make(coordinatorLayout, R.string.parse_theme_failed, Snackbar.LENGTH_SHORT).show(); - } - } - } - } - - private void checkDuplicateAndImportTheme(CustomTheme customTheme, boolean checkDuplicate) { - new InsertCustomThemeAsyncTask(redditDataRoomDatabase, lightThemeSharedPreferences, - darkThemeSharedPreferences, amoledThemeSharedPreferences, customTheme, checkDuplicate, - new InsertCustomThemeAsyncTask.InsertCustomThemeAsyncTaskListener() { - @Override - public void success() { - Toast.makeText(CustomThemeListingActivity.this, R.string.import_theme_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new RecreateActivityEvent()); - } - - @Override - public void duplicate() { - new MaterialAlertDialogBuilder(CustomThemeListingActivity.this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.duplicate_theme_name_dialog_title) - .setMessage(getString(R.string.duplicate_theme_name_dialog_message, customTheme.name)) - .setPositiveButton(R.string.rename, (dialogInterface, i) - -> { - View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); - EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); - themeNameEditText.setText(customTheme.name); - themeNameEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(CustomThemeListingActivity.this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.edit_theme_name) - .setView(dialogView) - .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); - } - if (!themeNameEditText.getText().toString().equals("")) { - customTheme.name = themeNameEditText.getText().toString(); - } - checkDuplicateAndImportTheme(customTheme, true); - }) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(editTextDialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); - } - }) - .show(); - }) - .setNegativeButton(R.string.override, (dialogInterface, i) -> { - checkDuplicateAndImportTheme(customTheme, false); - }) - .show(); - } - }).execute(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemePreviewActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemePreviewActivity.java deleted file mode 100644 index dd873679..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomThemePreviewActivity.java +++ /dev/null @@ -1,473 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.os.Build; -import android.os.Bundle; -import android.util.TypedValue; -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 androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentPagerAdapter; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.bottomappbar.BottomAppBar; -import com.google.android.material.chip.Chip; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.tabs.TabLayout; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeSettingsItem; -import ml.docilealligator.infinityforreddit.Font.ContentFontStyle; -import ml.docilealligator.infinityforreddit.Font.FontStyle; -import ml.docilealligator.infinityforreddit.Font.TitleFontStyle; -import ml.docilealligator.infinityforreddit.Fragment.ThemePreviewCommentsFragment; -import ml.docilealligator.infinityforreddit.Fragment.ThemePreviewPostsFragment; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; - -public class CustomThemePreviewActivity extends AppCompatActivity { - - public static final String EXTRA_CUSTOM_THEME_SETTINGS_ITEMS = "ECTSI"; - - @BindView(R.id.coordinator_layout_theme_preview_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.view_pager_theme_preview_activity) - ViewPager viewPager; - @BindView(R.id.appbar_layout_theme_preview_activity) - AppBarLayout appBarLayout; - @BindView(R.id.collapsing_toolbar_layout_theme_preview_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.toolbar_linear_layout_theme_preview_activity) - LinearLayout linearLayout; - @BindView(R.id.subreddit_name_text_view_theme_preview_activity) - TextView subredditNameTextView; - @BindView(R.id.user_name_text_view_theme_preview_activity) - TextView usernameTextView; - @BindView(R.id.subscribe_subreddit_chip_theme_preview_activity) - Chip subscribeSubredditChip; - @BindView(R.id.primary_text_text_view_theme_preview_activity) - TextView primaryTextView; - @BindView(R.id.secondary_text_text_view_theme_preview_activity) - TextView secondaryTextView; - @BindView(R.id.toolbar) - Toolbar toolbar; - @BindView(R.id.tab_layout_theme_preview_activity) - TabLayout tabLayout; - @BindView(R.id.bottom_navigation_theme_preview_activity) - BottomAppBar bottomNavigationView; - @BindView(R.id.linear_layout_bottom_app_bar_theme_preview_activity) - LinearLayout linearLayoutBottomAppBar; - @BindView(R.id.subscriptions_bottom_app_bar_theme_preview_activity) - ImageView subscriptionsBottomAppBar; - @BindView(R.id.multi_reddit_bottom_app_bar_theme_preview_activity) - ImageView multiRedditBottomAppBar; - @BindView(R.id.message_bottom_app_bar_theme_preview_activity) - ImageView messageBottomAppBar; - @BindView(R.id.profile_bottom_app_bar_theme_preview_activity) - ImageView profileBottomAppBar; - @BindView(R.id.fab_theme_preview_activity) - FloatingActionButton fab; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - private ArrayList customThemeSettingsItems; - private CustomTheme customTheme; - private int expandedTabTextColor; - private int expandedTabBackgroundColor; - private int expandedTabIndicatorColor; - private int collapsedTabTextColor; - private int collapsedTabBackgroundColor; - private int collapsedTabIndicatorColor; - private int unsubscribedColor; - private int subscribedColor; - private int systemVisibilityToolbarExpanded = 0; - private int systemVisibilityToolbarCollapsed = 0; - private SlidrInterface mSlidrInterface; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - ((Infinity) getApplication()).getAppComponent().inject(this); - - customThemeSettingsItems = getIntent().getParcelableArrayListExtra(EXTRA_CUSTOM_THEME_SETTINGS_ITEMS); - customTheme = CustomTheme.convertSettingsItemsToCustomTheme(customThemeSettingsItems, "ThemePreview"); - - boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; - int systemThemeType = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.THEME_KEY, "2")); - switch (systemThemeType) { - case 0: - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); - getTheme().applyStyle(R.style.Theme_Normal, true); - break; - case 1: - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { - getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); - } else { - getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); - } - break; - case 2: - if (systemDefault) { - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM); - } else { - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_AUTO_BATTERY); - } - if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) { - getTheme().applyStyle(R.style.Theme_Normal, true); - } else { - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { - getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); - } else { - getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); - } - } - } - - boolean immersiveInterface = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && - mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true); - boolean changeStatusBarIconColor = false; - if (immersiveInterface) { - changeStatusBarIconColor = customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface; - } - boolean isLightStatusbar = customTheme.isLightStatusBar; - Window window = getWindow(); - View decorView = window.getDecorView(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - boolean isLightNavBar = customTheme.isLightNavBar; - if (isLightStatusbar) { - if (isLightNavBar) { - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - if (changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } else { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } - } else { - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - if (!changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - } - } else { - if (isLightNavBar) { - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - if (changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; - } - } else { - if (changeStatusBarIconColor) { - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - } - } - decorView.setSystemUiVisibility(systemVisibilityToolbarExpanded); - window.setNavigationBarColor(customTheme.navBarColor); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (isLightStatusbar) { - decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); - systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; - } - } - - getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); - - setContentView(R.layout.activity_theme_preview); - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (immersiveInterface) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - - Resources resources = getResources(); - int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); - if (navBarResourceId > 0) { - int navBarHeight = resources.getDimensionPixelSize(navBarResourceId); - if (navBarHeight > 0) { - CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); - params.bottomMargin = navBarHeight; - fab.setLayoutParams(params); - linearLayoutBottomAppBar.setPadding(0, - (int) (6 * getResources().getDisplayMetrics().density), 0, navBarHeight); - } - } - } - - if (changeStatusBarIconColor) { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { - if (state == State.COLLAPSED) { - decorView.setSystemUiVisibility(systemVisibilityToolbarCollapsed); - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } else if (state == State.EXPANDED) { - decorView.setSystemUiVisibility(systemVisibilityToolbarExpanded); - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } - } - }); - } else { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { - if (state == State.COLLAPSED) { - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } else if (state == State.EXPANDED) { - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } - } - }); - } - } else { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, State state) { - if (state == State.EXPANDED) { - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } else if (state == State.COLLAPSED) { - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } - } - }); - } - - adjustToolbar(toolbar); - setSupportActionBar(toolbar); - - subscribeSubredditChip.setOnClickListener(view -> { - if (subscribeSubredditChip.getText().equals(getResources().getString(R.string.subscribe))) { - subscribeSubredditChip.setText(R.string.unsubscribe); - subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); - } else { - subscribeSubredditChip.setText(R.string.subscribe); - subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); - } - }); - - SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.setAdapter(sectionsPagerAdapter); - viewPager.setOffscreenPageLimit(2); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - if (position == 0) { - unlockSwipeRightToGoBack(); - } else { - lockSwipeRightToGoBack(); - } - } - }); - tabLayout.setupWithViewPager(viewPager); - } - - private void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(customTheme.backgroundColor); - collapsingToolbarLayout.setContentScrimColor(customTheme.colorPrimary); - subscribeSubredditChip.setTextColor(customTheme.chipTextColor); - subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(customTheme.unsubscribed)); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - expandedTabTextColor = customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor; - expandedTabIndicatorColor = customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator; - expandedTabBackgroundColor = customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground; - collapsedTabTextColor = customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor; - collapsedTabIndicatorColor = customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator; - collapsedTabBackgroundColor = customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground; - linearLayout.setBackgroundColor(customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground); - subredditNameTextView.setTextColor(customTheme.subreddit); - usernameTextView.setTextColor(customTheme.username); - subscribeSubredditChip.setTextColor(customTheme.chipTextColor); - primaryTextView.setTextColor(customTheme.primaryTextColor); - secondaryTextView.setTextColor(customTheme.secondaryTextColor); - bottomNavigationView.setBackgroundTint(ColorStateList.valueOf(customTheme.bottomAppBarBackgroundColor)); - int bottomAppBarIconColor = customTheme.bottomAppBarIconColor; - subscriptionsBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - multiRedditBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - messageBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - profileBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - applyTabLayoutTheme(tabLayout); - applyFABTheme(fab); - unsubscribedColor = customTheme.unsubscribed; - subscribedColor = customTheme.subscribed; - } - - protected void applyAppBarLayoutAndToolbarTheme(AppBarLayout appBarLayout, Toolbar toolbar) { - appBarLayout.setBackgroundColor(customTheme.colorPrimary); - toolbar.setTitleTextColor(customTheme.toolbarPrimaryTextAndIconColor); - toolbar.setSubtitleTextColor(customTheme.toolbarSecondaryTextColor); - if (toolbar.getNavigationIcon() != null) { - toolbar.getNavigationIcon().setColorFilter(customTheme.toolbarPrimaryTextAndIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - if (toolbar.getOverflowIcon() != null) { - toolbar.getOverflowIcon().setColorFilter(customTheme.toolbarPrimaryTextAndIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - } - - private void adjustToolbar(Toolbar toolbar) { - int statusBarResourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); - if (statusBarResourceId > 0) { - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); - int statusBarHeight = getResources().getDimensionPixelSize(statusBarResourceId); - params.topMargin = statusBarHeight; - toolbar.setLayoutParams(params); - TypedValue tv = new TypedValue(); - if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { - ((ViewGroup.MarginLayoutParams) linearLayout.getLayoutParams()).setMargins(0, - TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()) + statusBarHeight, 0, 0); - } - } - } - - protected void applyTabLayoutTheme(TabLayout tabLayout) { - int toolbarAndTabBackgroundColor = customTheme.colorPrimary; - tabLayout.setBackgroundColor(toolbarAndTabBackgroundColor); - tabLayout.setSelectedTabIndicatorColor(customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator); - tabLayout.setTabTextColors(customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor, - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor); - } - - protected void applyFABTheme(FloatingActionButton fab) { - fab.setBackgroundTintList(ColorStateList.valueOf(customTheme.colorPrimaryLightTheme)); - fab.setImageTintList(ColorStateList.valueOf(customTheme.fabIconColor)); - } - - public CustomTheme getCustomTheme() { - return customTheme; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return false; - } - - private void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - private void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } - - private class SectionsPagerAdapter extends FragmentPagerAdapter { - private ThemePreviewPostsFragment themePreviewPostsFragment; - private ThemePreviewCommentsFragment themePreviewCommentsFragment; - - SectionsPagerAdapter(FragmentManager fm) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - } - - @NonNull - @Override - public Fragment getItem(int position) { - if (position == 0) { - return new ThemePreviewPostsFragment(); - } - return new ThemePreviewCommentsFragment(); - } - - @Override - public int getCount() { - return 2; - } - - @Override - public CharSequence getPageTitle(int position) { - switch (position) { - case 0: - return "Posts"; - case 1: - return "Comments"; - } - return null; - } - - @NonNull - @Override - public Object instantiateItem(@NonNull ViewGroup container, int position) { - Fragment fragment = (Fragment) super.instantiateItem(container, position); - switch (position) { - case 0: - themePreviewPostsFragment = (ThemePreviewPostsFragment) fragment; - break; - case 1: - themePreviewCommentsFragment = (ThemePreviewCommentsFragment) fragment; - } - return fragment; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java deleted file mode 100644 index 0d206237..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/CustomizeThemeActivity.java +++ /dev/null @@ -1,247 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.snackbar.Snackbar; - -import org.greenrobot.eventbus.EventBus; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.CustomizeThemeRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCustomThemeAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertCustomThemeAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeSettingsItem; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; - -public class CustomizeThemeActivity extends BaseActivity { - - public static final String EXTRA_THEME_TYPE = "ETT"; - public static final int EXTRA_LIGHT_THEME = CustomThemeSharedPreferencesUtils.LIGHT; - public static final int EXTRA_DARK_THEME = CustomThemeSharedPreferencesUtils.DARK; - public static final int EXTRA_AMOLED_THEME = CustomThemeSharedPreferencesUtils.AMOLED; - public static final String EXTRA_THEME_NAME = "ETN"; - public static final String EXTRA_IS_PREDEFIINED_THEME = "EIPT"; - public static final String EXTRA_CREATE_THEME = "ECT"; - private static final String CUSTOM_THEME_SETTINGS_ITEMS_STATE = "CTSIS"; - private static final String THEME_NAME_STATE = "TNS"; - - @BindView(R.id.coordinator_customize_theme_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_customize_theme_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_customize_theme_activity) - Toolbar toolbar; - @BindView(R.id.recycler_view_customize_theme_activity) - RecyclerView recyclerView; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - @Inject - @Named("light_theme") - SharedPreferences lightThemeSharedPreferences; - @Inject - @Named("dark_theme") - SharedPreferences darkThemeSharedPreferences; - @Inject - @Named("amoled_theme") - SharedPreferences amoledThemeSharedPreferences; - @Inject - RedditDataRoomDatabase redditDataRoomDatabase; - @Inject - CustomThemeWrapper customThemeWrapper; - - private String themeName; - private boolean isPredefinedTheme; - private ArrayList customThemeSettingsItems; - private CustomizeThemeRecyclerViewAdapter adapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_customize_theme); - - ButterKnife.bind(this); - - applyCustomTheme(); - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - if (getIntent().getBooleanExtra(EXTRA_CREATE_THEME, false)) { - setTitle(R.string.customize_theme_activity_create_theme_label); - } - - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - - if (savedInstanceState != null) { - customThemeSettingsItems = savedInstanceState.getParcelableArrayList(CUSTOM_THEME_SETTINGS_ITEMS_STATE); - themeName = savedInstanceState.getString(THEME_NAME_STATE); - } - - int androidVersion = Build.VERSION.SDK_INT; - - if (customThemeSettingsItems == null) { - if (getIntent().hasExtra(EXTRA_THEME_TYPE)) { - int themeType = getIntent().getIntExtra(EXTRA_THEME_TYPE, EXTRA_LIGHT_THEME); - - new GetCustomThemeAsyncTask(redditDataRoomDatabase, themeType, customTheme -> { - if (customTheme == null) { - isPredefinedTheme = true; - switch (themeType) { - case EXTRA_DARK_THEME: - customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( - CustomizeThemeActivity.this, - CustomThemeWrapper.getIndigoDark(CustomizeThemeActivity.this), - androidVersion); - themeName = getString(R.string.theme_name_indigo_dark); - break; - case EXTRA_AMOLED_THEME: - customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( - CustomizeThemeActivity.this, - CustomThemeWrapper.getIndigoAmoled(CustomizeThemeActivity.this), - androidVersion); - themeName = getString(R.string.theme_name_indigo_amoled); - break; - default: - customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( - CustomizeThemeActivity.this, - CustomThemeWrapper.getIndigo(CustomizeThemeActivity.this), - androidVersion); - themeName = getString(R.string.theme_name_indigo); - } - } else { - customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( - CustomizeThemeActivity.this, customTheme, androidVersion); - themeName = customTheme.name; - } - - adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); - recyclerView.setAdapter(adapter); - adapter.setCustomThemeSettingsItem(customThemeSettingsItems); - }).execute(); - } else { - isPredefinedTheme = getIntent().getBooleanExtra(EXTRA_IS_PREDEFIINED_THEME, false); - themeName = getIntent().getStringExtra(EXTRA_THEME_NAME); - adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); - recyclerView.setAdapter(adapter); - if (isPredefinedTheme) { - customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( - CustomizeThemeActivity.this, - CustomThemeWrapper.getPredefinedCustomTheme(this, themeName), - androidVersion); - - adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); - recyclerView.setAdapter(adapter); - adapter.setCustomThemeSettingsItem(customThemeSettingsItems); - } else { - new GetCustomThemeAsyncTask(redditDataRoomDatabase, themeName, - customTheme -> { - customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( - CustomizeThemeActivity.this, customTheme, androidVersion); - - adapter.setCustomThemeSettingsItem(customThemeSettingsItems); - }).execute(); - } - } - } else { - adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); - recyclerView.setAdapter(adapter); - adapter.setCustomThemeSettingsItem(customThemeSettingsItems); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.customize_theme_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_preview_customize_theme_activity: - Intent intent = new Intent(this, CustomThemePreviewActivity.class); - intent.putParcelableArrayListExtra(CustomThemePreviewActivity.EXTRA_CUSTOM_THEME_SETTINGS_ITEMS, customThemeSettingsItems); - startActivity(intent); - - return true; - case R.id.action_save_customize_theme_activity: - if (adapter != null) { - themeName = adapter.getThemeName(); - if (themeName.equals("")) { - Snackbar.make(coordinatorLayout, R.string.no_theme_name, Snackbar.LENGTH_SHORT).show(); - return true; - } - CustomTheme customTheme = CustomTheme.convertSettingsItemsToCustomTheme(customThemeSettingsItems, themeName); - new InsertCustomThemeAsyncTask(redditDataRoomDatabase, lightThemeSharedPreferences, - darkThemeSharedPreferences, amoledThemeSharedPreferences, customTheme, - false, () -> { - Toast.makeText(CustomizeThemeActivity.this, R.string.saved, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new RecreateActivityEvent()); - finish(); - }).execute(); - } - - return true; - } - - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - if (adapter != null) { - outState.putParcelableArrayList(CUSTOM_THEME_SETTINGS_ITEMS_STATE, customThemeSettingsItems); - outState.putString(THEME_NAME_STATE, adapter.getThemeName()); - } - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return sharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return customThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditCommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditCommentActivity.java deleted file mode 100644 index 14c875be..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditCommentActivity.java +++ /dev/null @@ -1,244 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.util.HashMap; -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Adapter.MarkdownBottomBarRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class EditCommentActivity extends BaseActivity { - - public static final String EXTRA_CONTENT = "EC"; - public static final String EXTRA_FULLNAME = "EF"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_POSITION = "EP"; - - static final String EXTRA_EDITED_COMMENT_CONTENT = "EECC"; - static final String EXTRA_EDITED_COMMENT_POSITION = "EECP"; - - @BindView(R.id.coordinator_layout_edit_comment_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_edit_comment_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_edit_comment_activity) - Toolbar toolbar; - @BindView(R.id.comment_edit_text_edit_comment_activity) - EditText contentEditText; - @BindView(R.id.markdown_bottom_bar_recycler_view_edit_comment_activity) - RecyclerView markdownBottomBarRecyclerView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String mFullName; - private String mAccessToken; - private String mCommentContent; - private boolean isSubmitting = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_edit_comment); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); - mAccessToken = getIntent().getStringExtra(EXTRA_ACCESS_TOKEN); - mCommentContent = getIntent().getStringExtra(EXTRA_CONTENT); - contentEditText.setText(mCommentContent); - - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); - }); - - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, - LinearLayoutManager.HORIZONTAL, false)); - markdownBottomBarRecyclerView.setAdapter(adapter); - - contentEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - contentEditText.setTextColor(mCustomThemeWrapper.getCommentColor()); - } - - @Override - protected void onPause() { - super.onPause(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.hideSoftInputFromWindow(contentEditText.getWindowToken(), 0); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.edit_comment_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_preview_edit_comment_activity) { - Intent intent = new Intent(this, FullMarkdownActivity.class); - intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); - startActivity(intent); - } else if (item.getItemId() == R.id.action_send_edit_comment_activity) { - if (!isSubmitting) { - isSubmitting = true; - - Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); - - String content = contentEditText.getText().toString(); - - Map params = new HashMap<>(); - params.put(APIUtils.THING_ID_KEY, mFullName); - params.put(APIUtils.TEXT_KEY, content); - - mOauthRetrofit.create(RedditAPI.class) - .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - isSubmitting = false; - if (response.isSuccessful()) { - Toast.makeText(EditCommentActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); - - Intent returnIntent = new Intent(); - returnIntent.putExtra(EXTRA_EDITED_COMMENT_CONTENT, Utils.modifyMarkdown(content)); - returnIntent.putExtra(EXTRA_EDITED_COMMENT_POSITION, getIntent().getExtras().getInt(EXTRA_POSITION)); - setResult(RESULT_OK, returnIntent); - - finish(); - } else { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } - }); - - } - return true; - } else if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } - return false; - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - public void onBackPressed() { - if (isSubmitting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_comment_detail); - } else { - if (contentEditText.getText().toString().equals(mCommentContent)) { - finish(); - } else { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditMultiRedditActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditMultiRedditActivity.java deleted file mode 100644 index 421b495d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditMultiRedditActivity.java +++ /dev/null @@ -1,271 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.Switch; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.snackbar.Snackbar; -import com.r0adkll.slidr.Slidr; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.MultiReddit.EditMultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.FetchMultiRedditInfo; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiRedditJSONModel; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class EditMultiRedditActivity extends BaseActivity { - public static final String EXTRA_MULTI_PATH = "EMP"; - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 1; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String MULTI_REDDIT_STATE = "MRS"; - private static final String MULTI_PATH_STATE = "MPS"; - @BindView(R.id.coordinator_layout_edit_multi_reddit_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_edit_multi_reddit_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_edit_multi_reddit_activity) - Toolbar toolbar; - @BindView(R.id.progress_bar_edit_multi_reddit_activity) - ProgressBar progressBar; - @BindView(R.id.linear_layout_edit_multi_reddit_activity) - LinearLayout linearLayout; - @BindView(R.id.multi_reddit_name_edit_text_edit_multi_reddit_activity) - EditText nameEditText; - @BindView(R.id.divider_1_edit_multi_reddit_activity) - View divider1; - @BindView(R.id.description_edit_text_edit_multi_reddit_activity) - EditText descriptionEditText; - @BindView(R.id.divider_2_edit_multi_reddit_activity) - View divider2; - @BindView(R.id.visibility_wrapper_linear_layout_edit_multi_reddit_activity) - LinearLayout visibilityLinearLayout; - @BindView(R.id.visibility_text_view_edit_multi_reddit_activity) - TextView visibilityTextView; - @BindView(R.id.visibility_switch_edit_multi_reddit_activity) - Switch visibilitySwitch; - @BindView(R.id.select_subreddit_text_view_edit_multi_reddit_activity) - TextView selectSubredditTextView; - @Inject - @Named("oauth") - Retrofit mRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private MultiReddit multiReddit; - private String multipath; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_edit_multi_reddit); - - ButterKnife.bind(this); - - 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); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - multiReddit = savedInstanceState.getParcelable(MULTI_REDDIT_STATE); - multipath = savedInstanceState.getString(MULTI_PATH_STATE); - - if (!mNullAccessToken && mAccountName == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - } else { - multipath = getIntent().getStringExtra(EXTRA_MULTI_PATH); - getCurrentAccountAndBindView(); - } - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - Toast.makeText(this, R.string.logged_out, Toast.LENGTH_SHORT).show(); - finish(); - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - bindView(); - } - }).execute(); - } - - private void bindView() { - if (multiReddit == null) { - FetchMultiRedditInfo.fetchMultiRedditInfo(mRetrofit, mAccessToken, multipath, new FetchMultiRedditInfo.FetchMultiRedditInfoListener() { - @Override - public void success(MultiReddit multiReddit) { - EditMultiRedditActivity.this.multiReddit = multiReddit; - progressBar.setVisibility(View.GONE); - linearLayout.setVisibility(View.VISIBLE); - nameEditText.setText(multiReddit.getDisplayName()); - descriptionEditText.setText(multiReddit.getDescription()); - visibilitySwitch.setChecked(!multiReddit.getVisibility().equals("public")); - } - - @Override - public void failed() { - Snackbar.make(coordinatorLayout, R.string.cannot_fetch_multireddit, Snackbar.LENGTH_SHORT).show(); - } - }); - } else { - progressBar.setVisibility(View.GONE); - linearLayout.setVisibility(View.VISIBLE); - nameEditText.setText(multiReddit.getDisplayName()); - descriptionEditText.setText(multiReddit.getDescription()); - visibilitySwitch.setChecked(!multiReddit.getVisibility().equals("public")); - } - - selectSubredditTextView.setOnClickListener(view -> { - Intent intent = new Intent(EditMultiRedditActivity.this, SelectedSubredditsActivity.class); - if (multiReddit.getSubreddits() != null) { - intent.putStringArrayListExtra(SelectedSubredditsActivity.EXTRA_SELECTED_SUBREDDITS, multiReddit.getSubreddits()); - } - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.edit_multi_reddit_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_save_edit_multi_reddit_activity: - if (mAccountName == null || mAccessToken == null) { - Snackbar.make(coordinatorLayout, R.string.something_went_wrong, Snackbar.LENGTH_SHORT).show(); - return true; - } - if (nameEditText.getText() == null || nameEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.no_multi_reddit_name, Snackbar.LENGTH_SHORT).show(); - return true; - } - - String jsonModel = new MultiRedditJSONModel(nameEditText.getText().toString(), descriptionEditText.getText().toString(), - visibilitySwitch.isChecked(), multiReddit.getSubreddits()).createJSONModel(); - EditMultiReddit.editMultiReddit(mRetrofit, mAccessToken, multiReddit.getPath(), - jsonModel, new EditMultiReddit.EditMultiRedditListener() { - @Override - public void success() { - finish(); - } - - @Override - public void failed() { - Snackbar.make(coordinatorLayout, R.string.edit_multi_reddit_failed, Snackbar.LENGTH_SHORT).show(); - } - }); - } - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE && resultCode == RESULT_OK) { - if (data != null) { - multiReddit.setSubreddits(data.getStringArrayListExtra( - SelectedSubredditsActivity.EXTRA_RETURN_SELECTED_SUBREDDITS)); - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putParcelable(MULTI_REDDIT_STATE, multiReddit); - outState.putString(MULTI_PATH_STATE, multipath); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorAccent())); - int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - nameEditText.setTextColor(primaryTextColor); - nameEditText.setHintTextColor(secondaryTextColor); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - descriptionEditText.setTextColor(primaryTextColor); - descriptionEditText.setHintTextColor(secondaryTextColor); - visibilityTextView.setTextColor(primaryTextColor); - selectSubredditTextView.setTextColor(primaryTextColor); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditPostActivity.java deleted file mode 100644 index a773a386..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/EditPostActivity.java +++ /dev/null @@ -1,245 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.util.HashMap; -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Adapter.MarkdownBottomBarRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class EditPostActivity extends BaseActivity { - - static final String EXTRA_TITLE = "ET"; - static final String EXTRA_CONTENT = "EC"; - static final String EXTRA_FULLNAME = "EF"; - static final String EXTRA_ACCESS_TOKEN = "EAT"; - - @BindView(R.id.coordinator_layout_edit_post_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_edit_post_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_edit_post_activity) - Toolbar toolbar; - @BindView(R.id.post_title_text_view_edit_post_activity) - TextView titleTextView; - @BindView(R.id.divider_edit_post_activity) - View divider; - @BindView(R.id.post_text_content_edit_text_edit_post_activity) - EditText contentEditText; - @BindView(R.id.markdown_bottom_bar_recycler_view_edit_post_activity) - RecyclerView markdownBottomBarRecyclerView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String mFullName; - private String mAccessToken; - private String mPostContent; - private boolean isSubmitting = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_edit_post); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - 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); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); - mAccessToken = getIntent().getStringExtra(EXTRA_ACCESS_TOKEN); - titleTextView.setText(getIntent().getStringExtra(EXTRA_TITLE)); - mPostContent = getIntent().getStringExtra(EXTRA_CONTENT); - contentEditText.setText(mPostContent); - - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); - }); - - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, - LinearLayoutManager.HORIZONTAL, false)); - markdownBottomBarRecyclerView.setAdapter(adapter); - - contentEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - titleTextView.setTextColor(mCustomThemeWrapper.getPostTitleColor()); - divider.setBackgroundColor(mCustomThemeWrapper.getPostTitleColor()); - contentEditText.setTextColor(mCustomThemeWrapper.getPostContentColor()); - } - - @Override - protected void onPause() { - super.onPause(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.hideSoftInputFromWindow(contentEditText.getWindowToken(), 0); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.edit_post_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_preview_edit_post_activity) { - Intent intent = new Intent(this, FullMarkdownActivity.class); - intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); - startActivity(intent); - } else if (item.getItemId() == R.id.action_send_edit_post_activity) { - if (!isSubmitting) { - isSubmitting = true; - - Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); - - Map params = new HashMap<>(); - params.put(APIUtils.THING_ID_KEY, mFullName); - params.put(APIUtils.TEXT_KEY, contentEditText.getText().toString()); - - mOauthRetrofit.create(RedditAPI.class) - .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - isSubmitting = false; - Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); - Intent returnIntent = new Intent(); - setResult(RESULT_OK, returnIntent); - finish(); - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } - }); - - } - return true; - } else if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } - return false; - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - public void onBackPressed() { - if (isSubmitting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_post_detail); - } else { - if (contentEditText.getText().toString().equals(mPostContent)) { - finish(); - } else { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } - } - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FetchRandomSubredditOrPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FetchRandomSubredditOrPostActivity.java deleted file mode 100644 index ebc87764..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FetchRandomSubredditOrPostActivity.java +++ /dev/null @@ -1,104 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.widget.RelativeLayout; -import android.widget.Toast; - -import com.airbnb.lottie.LottieAnimationView; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.RandomBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.FetchPost; -import ml.docilealligator.infinityforreddit.R; -import retrofit2.Retrofit; - -public class FetchRandomSubredditOrPostActivity extends BaseActivity { - - public static final String EXTRA_RANDOM_OPTION = "ERO"; - - @BindView(R.id.relative_layout_fetch_random_subreddit_or_post_activity) - RelativeLayout relativeLayout; - @BindView(R.id.lottie_animation_view_fetch_random_subreddit_or_post_activity) - LottieAnimationView lottieAnimationView; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean isCanceled = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplicationContext()).getAppComponent().inject(this); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_fetch_random_subreddit_or_post); - - ButterKnife.bind(this); - - int option = getIntent().getIntExtra(EXTRA_RANDOM_OPTION, RandomBottomSheetFragment.RANDOM_SUBREDDIT); - - FetchPost.fetchRandomPost(mRetrofit, option == RandomBottomSheetFragment.RANDOM_NSFW_SUBREDDIT - || option == RandomBottomSheetFragment.RANDOM_NSFW_POST, new FetchPost.FetchRandomPostListener() { - @Override - public void fetchRandomPostSuccess(String postId, String subredditName) { - if (!isCanceled) { - switch (option) { - case RandomBottomSheetFragment.RANDOM_SUBREDDIT: - case RandomBottomSheetFragment.RANDOM_NSFW_SUBREDDIT: { - Intent intent = new Intent(FetchRandomSubredditOrPostActivity.this, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); - startActivity(intent); - } - break; - case RandomBottomSheetFragment.RANDOM_POST: - case RandomBottomSheetFragment.RANDOM_NSFW_POST: - Intent intent = new Intent(FetchRandomSubredditOrPostActivity.this, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, postId); - startActivity(intent); - break; - } - - finish(); - } - } - - @Override - public void fetchRandomPostFailed() { - Toast.makeText(FetchRandomSubredditOrPostActivity.this, R.string.fetch_random_thing_failed, Toast.LENGTH_SHORT).show(); - finish(); - } - }); - } - - @Override - public void onBackPressed() { - super.onBackPressed(); - isCanceled = true; - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - relativeLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FilteredThingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FilteredThingActivity.java deleted file mode 100644 index 02f900f5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FilteredThingActivity.java +++ /dev/null @@ -1,461 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -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.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SearchPostSortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTimeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.UserThingSortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class FilteredThingActivity extends BaseActivity implements SortTypeSelectionCallback, - PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { - - public static final String EXTRA_NAME = "ESN"; - public static final String EXTRA_QUERY = "EQ"; - public static final String EXTRA_FILTER = "EF"; - public static final String EXTRA_POST_TYPE = "EPT"; - public static final String EXTRA_USER_WHERE = "EUW"; - - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String FRAGMENT_OUT_STATE = "FOS"; - - @BindView(R.id.coordinator_layout_filtered_thing_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_filtered_posts_activity) - AppBarLayout appBarLayout; - @BindView(R.id.collapsing_toolbar_layout_filtered_posts_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.toolbar_filtered_posts_activity) - Toolbar toolbar; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean isInLazyMode = false; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String name; - private String userWhere; - private int postType; - private Fragment mFragment; - private Menu mMenu; - private AppBarLayout.LayoutParams params; - private SortTypeBottomSheetFragment bestSortTypeBottomSheetFragment; - private SortTypeBottomSheetFragment popularAndAllSortTypeBottomSheetFragment; - private SortTypeBottomSheetFragment subredditSortTypeBottomSheetFragment; - private SortTypeBottomSheetFragment multiRedditSortTypeBottomSheetFragment; - private UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment; - private SearchPostSortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment; - private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_filtered_thing); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - } - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - - name = getIntent().getStringExtra(EXTRA_NAME); - postType = getIntent().getIntExtra(EXTRA_POST_TYPE, PostDataSource.TYPE_FRONT_PAGE); - int filter = getIntent().getIntExtra(EXTRA_FILTER, Post.TEXT_TYPE); - - if (postType == PostDataSource.TYPE_USER) { - userWhere = getIntent().getStringExtra(EXTRA_USER_WHERE); - if (userWhere != null && !PostDataSource.USER_WHERE_SUBMITTED.equals(userWhere) && mMenu != null) { - mMenu.findItem(R.id.action_sort_filtered_thing_activity).setVisible(false); - } - } - - if (savedInstanceState != null) { - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - - mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_filtered_posts_activity, mFragment).commit(); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(filter); - } else { - bindView(filter, false); - } - } else { - getCurrentAccountAndBindView(filter); - } - - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mFragment != null) { - return ((FragmentCommunicator) mFragment).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()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - private void getCurrentAccountAndBindView(int filter) { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - bindView(filter, true); - }).execute(); - } - - private void bindView(int filter, boolean initializeFragment) { - switch (postType) { - case PostDataSource.TYPE_FRONT_PAGE: - getSupportActionBar().setTitle(name); - - bestSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle bestBundle = new Bundle(); - bestBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, false); - bestSortTypeBottomSheetFragment.setArguments(bestBundle); - break; - case PostDataSource.TYPE_SEARCH: - getSupportActionBar().setTitle(R.string.search); - - searchPostSortTypeBottomSheetFragment = new SearchPostSortTypeBottomSheetFragment(); - Bundle searchBundle = new Bundle(); - searchPostSortTypeBottomSheetFragment.setArguments(searchBundle); - break; - case PostDataSource.TYPE_SUBREDDIT: - if (name.equals("popular") || name.equals("all")) { - getSupportActionBar().setTitle(name.substring(0, 1).toUpperCase() + name.substring(1)); - - popularAndAllSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle popularBundle = new Bundle(); - popularBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - popularAndAllSortTypeBottomSheetFragment.setArguments(popularBundle); - } else { - String subredditNamePrefixed = "r/" + name; - getSupportActionBar().setTitle(subredditNamePrefixed); - - subredditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle subredditSheetBundle = new Bundle(); - subredditSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - subredditSortTypeBottomSheetFragment.setArguments(subredditSheetBundle); - } - break; - case PostDataSource.TYPE_MULTI_REDDIT: - String multiRedditName; - if (name.endsWith("/")) { - multiRedditName = name.substring(0, name.length() - 1); - multiRedditName = multiRedditName.substring(multiRedditName.lastIndexOf("/") + 1); - } else { - multiRedditName = name.substring(name.lastIndexOf("/") + 1); - } - getSupportActionBar().setTitle(multiRedditName); - - multiRedditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle multiRedditBundle = new Bundle(); - multiRedditBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - multiRedditSortTypeBottomSheetFragment.setArguments(multiRedditBundle); - break; - case PostDataSource.TYPE_USER: - String usernamePrefixed = "u/" + name; - getSupportActionBar().setTitle(usernamePrefixed); - - userThingSortTypeBottomSheetFragment = new UserThingSortTypeBottomSheetFragment(); - break; - } - - sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); - - switch (filter) { - case Post.NSFW_TYPE: - toolbar.setSubtitle(R.string.nsfw); - break; - case Post.TEXT_TYPE: - toolbar.setSubtitle(R.string.text); - break; - case Post.LINK_TYPE: - case Post.NO_PREVIEW_LINK_TYPE: - toolbar.setSubtitle(R.string.link); - break; - case Post.IMAGE_TYPE: - toolbar.setSubtitle(R.string.image); - break; - case Post.VIDEO_TYPE: - toolbar.setSubtitle(R.string.video); - break; - case Post.GIF_TYPE: - toolbar.setSubtitle(R.string.gif); - break; - case Post.GALLERY_TYPE: - toolbar.setSubtitle(R.string.gallery); - } - - if (initializeFragment) { - mFragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, postType); - bundle.putInt(PostFragment.EXTRA_FILTER, filter); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - if (postType == PostDataSource.TYPE_USER) { - bundle.putString(PostFragment.EXTRA_USER_NAME, name); - bundle.putString(PostFragment.EXTRA_USER_WHERE, userWhere); - } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { - bundle.putString(PostFragment.EXTRA_NAME, name); - } else if (postType == PostDataSource.TYPE_SEARCH) { - bundle.putString(PostFragment.EXTRA_NAME, name); - bundle.putString(PostFragment.EXTRA_QUERY, getIntent().getStringExtra(EXTRA_QUERY)); - } - mFragment.setArguments(bundle); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_filtered_posts_activity, mFragment).commit(); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.filtered_posts_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity); - if (isInLazyMode) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } else { - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } - - if (userWhere != null && !PostDataSource.USER_WHERE_SUBMITTED.equals(userWhere)) { - mMenu.findItem(R.id.action_sort_filtered_thing_activity).setVisible(false); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_sort_filtered_thing_activity: - switch (postType) { - case PostDataSource.TYPE_FRONT_PAGE: - bestSortTypeBottomSheetFragment.show(getSupportFragmentManager(), bestSortTypeBottomSheetFragment.getTag()); - break; - case PostDataSource.TYPE_SEARCH: - searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag()); - break; - case PostDataSource.TYPE_SUBREDDIT: - if (name.equals("popular") || name.equals("all")) { - popularAndAllSortTypeBottomSheetFragment.show(getSupportFragmentManager(), popularAndAllSortTypeBottomSheetFragment.getTag()); - } else { - subredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), subredditSortTypeBottomSheetFragment.getTag()); - } - break; - case PostDataSource.TYPE_MULTI_REDDIT: - multiRedditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), multiRedditSortTypeBottomSheetFragment.getTag()); - break; - case PostDataSource.TYPE_USER: - userThingSortTypeBottomSheetFragment.show(getSupportFragmentManager(), userThingSortTypeBottomSheetFragment.getTag()); - } - return true; - case R.id.action_refresh_filtered_thing_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity).setTitle(R.string.action_start_lazy_mode); - } - if (mFragment instanceof FragmentCommunicator) { - ((FragmentCommunicator) mFragment).refresh(); - } - return true; - case R.id.action_lazy_mode_filtered_thing_activity: - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity); - if (isInLazyMode) { - ((FragmentCommunicator) mFragment).stopLazyMode(); - isInLazyMode = false; - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } else { - if (((FragmentCommunicator) mFragment).startLazyMode()) { - isInLazyMode = true; - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } - } - return true; - case R.id.action_change_post_layout_filtered_post_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Override - public void sortTypeSelected(SortType sortType) { - ((PostFragment) mFragment).changeSortType(sortType); - } - - @Override - public void postLayoutSelected(int postLayout) { - if (mFragment != null) { - switch (postType) { - case PostDataSource.TYPE_FRONT_PAGE: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, postLayout).apply(); - break; - case PostDataSource.TYPE_SUBREDDIT: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + name, postLayout).apply(); - break; - case PostDataSource.TYPE_USER: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + name, postLayout).apply(); - break; - case PostDataSource.TYPE_SEARCH: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST, postLayout).apply(); - } - ((FragmentCommunicator) mFragment).changePostLayout(postLayout); - } - } - - @Override - public void sortTypeSelected(String sortType) { - Bundle bundle = new Bundle(); - bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); - sortTimeBottomSheetFragment.setArguments(bundle); - sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Override - public void onLongPress() { - if (mFragment != null) { - ((PostFragment) mFragment).goBackToTop(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FullMarkdownActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FullMarkdownActivity.java deleted file mode 100644 index 5b262503..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/FullMarkdownActivity.java +++ /dev/null @@ -1,266 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.TextPaint; -import android.text.style.ClickableSpan; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -import android.view.MenuItem; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import org.commonmark.ext.gfm.tables.TableBlock; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.recycler.MarkwonAdapter; -import io.noties.markwon.recycler.table.TableEntry; -import io.noties.markwon.recycler.table.TableEntryPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.CustomView.MarkwonLinearLayoutManager; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class FullMarkdownActivity extends BaseActivity { - - public static final String EXTRA_COMMENT_MARKDOWN = "ECM"; - public static final String EXTRA_IS_NSFW = "EIN"; - - @BindView(R.id.coordinator_layout_comment_full_markdown_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_comment_full_markdown_activity) - AppBarLayout appBarLayout; - @BindView(R.id.collapsing_toolbar_layout_comment_full_markdown_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.toolbar_comment_full_markdown_activity) - Toolbar toolbar; - @BindView(R.id.content_markdown_view_comment_full_markdown_activity) - RecyclerView markdownRecyclerView; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private SlidrInterface mSlidrInterface; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_comment_full_markdown); - - ButterKnife.bind(this); - - applyCustomTheme(); - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - setTitle(" "); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - markdownRecyclerView.setPadding(0, 0, 0, getNavBarHeight()); - } - } - - String commentMarkdown = getIntent().getStringExtra(EXTRA_COMMENT_MARKDOWN); - boolean isNsfw = getIntent().getBooleanExtra(EXTRA_IS_NSFW, false); - int markdownColor = mCustomThemeWrapper.getCommentColor(); - int spoilerBackgroundColor = markdownColor | 0xFF000000; - int linkColor = mCustomThemeWrapper.getLinkColor(); - Markwon markwon = Markwon.builder(this) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - while (matcher.find()) { - markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); - } - - @Override - public void afterSetText(@NonNull TextView textView) { - textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(markdownColor); - } else { - ds.bgColor = spoilerBackgroundColor; - ds.setColor(markdownColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - textView.setTextColor(markdownColor); - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(FullMarkdownActivity.this, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, isNsfw); - startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .usePlugin(TableEntryPlugin.create(this)) - .build(); - - MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); - LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { - @Override - public void onScrolledLeft() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - @Override - public void onScrolledRight() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } - }); - markdownRecyclerView.setLayoutManager(linearLayoutManager); - markdownRecyclerView.setAdapter(markwonAdapter); - markwonAdapter.setMarkdown(markwon, commentMarkdown); - markwonAdapter.notifyDataSetChanged(); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/GiveAwardActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/GiveAwardActivity.java deleted file mode 100644 index 9b8fec82..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/GiveAwardActivity.java +++ /dev/null @@ -1,210 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.MenuItem; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.switchmaterial.SwitchMaterial; -import com.r0adkll.slidr.Slidr; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.AwardRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.Award.GiveAward; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class GiveAwardActivity extends BaseActivity { - - public static final String EXTRA_THING_FULLNAME = "ETF"; - public static final String EXTRA_ITEM_POSITION = "EIP"; - public static final String EXTRA_RETURN_ITEM_POSITION = "ERIP"; - public static final String EXTRA_RETURN_NEW_AWARDS = "ERNA"; - public static final String EXTRA_RETURN_NEW_AWARDS_COUNT = "ERNAC"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - - @BindView(R.id.coordinator_layout_give_award_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_give_award_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_give_award_activity) - Toolbar toolbar; - @BindView(R.id.recycler_view_give_award_activity) - RecyclerView recyclerView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String thingFullname; - private int itemPosition; - private boolean mNullAccessToken = false; - private String mAccessToken; - private AwardRecyclerViewAdapter adapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_give_award); - - ButterKnife.bind(this); - - applyCustomTheme(); - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - } - - thingFullname = getIntent().getStringExtra(EXTRA_THING_FULLNAME); - itemPosition = getIntent().getIntExtra(EXTRA_ITEM_POSITION, 0); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - } else { - getCurrentAccountAndBindView(); - } - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - bindView(); - }).execute(); - } - - private void bindView() { - adapter = new AwardRecyclerViewAdapter(Glide.with(this), mCustomThemeWrapper, award -> { - LayoutInflater inflater = getLayoutInflater(); - View layout = inflater.inflate(R.layout.dialog_give_award, null); - SwitchMaterial switchMaterial = layout.findViewById(R.id.switch_material_give_award_dialog); - new MaterialAlertDialogBuilder(this) - .setTitle(R.string.give_award_dialog_title) - .setView(layout) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> { - boolean isAnonymous = switchMaterial.isChecked(); - - GiveAward.giveAwardV2(mOauthRetrofit, mAccessToken, thingFullname, award.getId(), - isAnonymous, new GiveAward.GiveAwardListener() { - @Override - public void success(String awardsHTML, int awardCount) { - Intent data = new Intent(); - data.putExtra(EXTRA_RETURN_ITEM_POSITION, itemPosition); - data.putExtra(EXTRA_RETURN_NEW_AWARDS, awardsHTML); - data.putExtra(EXTRA_RETURN_NEW_AWARDS_COUNT, awardCount); - setResult(RESULT_OK, data); - finish(); - } - - @Override - public void failed(int code, String message) { - View layout = inflater.inflate(R.layout.copy_text_material_dialog, null); - TextView textView = layout.findViewById(R.id.text_view_copy_text_material_dialog); - String text = getString(R.string.give_award_error_message, code, message == null ? "" : message); - textView.setText(text); - new MaterialAlertDialogBuilder(GiveAwardActivity.this, R.style.CopyTextMaterialAlertDialogTheme) - .setTitle(R.string.give_award_failed) - .setView(layout) - .setPositiveButton(R.string.copy_all, (dialogInterface, i) -> { - ClipboardManager clipboard = (ClipboardManager) GiveAwardActivity.this.getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard != null) { - ClipData clip = ClipData.newPlainText("simple text", text); - clipboard.setPrimaryClip(clip); - Toast.makeText(GiveAwardActivity.this, R.string.copy_success, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(GiveAwardActivity.this, R.string.copy_failed, Toast.LENGTH_SHORT).show(); - } - }) - .setNegativeButton(R.string.cancel, null) - .show(); - } - }); - }) - .setNegativeButton(R.string.no, null) - .show(); - }); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - recyclerView.setAdapter(adapter); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/InboxActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/InboxActivity.java deleted file mode 100644 index dfd2af52..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/InboxActivity.java +++ /dev/null @@ -1,353 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; -import android.widget.Toast; - -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.FragmentManager; -import androidx.fragment.app.FragmentPagerAdapter; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.tabs.TabLayout; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SwitchAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.InboxFragment; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.FetchMessage; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class InboxActivity extends BaseActivity implements ActivityToolbarInterface { - - public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; - public static final String EXTRA_VIEW_MESSAGE = "EVM"; - - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; - - @BindView(R.id.coordinator_layout_inbox_activity) - CoordinatorLayout mCoordinatorLayout; - @BindView(R.id.collapsing_toolbar_layout_inbox_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.appbar_layout_inbox_activity) - AppBarLayout mAppBarLayout; - @BindView(R.id.toolbar_inbox_activity) - Toolbar mToolbar; - @BindView(R.id.tab_layout_inbox_activity) - TabLayout tabLayout; - @BindView(R.id.view_pager_inbox_activity) - ViewPager viewPager; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private SlidrInterface mSlidrInterface; - private SectionsPagerAdapter sectionsPagerAdapter; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mNewAccountName; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_inbox); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(mAppBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - mCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(mToolbar); - } - } - - mToolbar.setTitle(R.string.inbox); - setSupportActionBar(mToolbar); - setToolbarGoToTop(mToolbar); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndFetchMessage(savedInstanceState); - } else { - bindView(savedInstanceState); - } - } else { - mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); - getCurrentAccountAndFetchMessage(savedInstanceState); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); - applyTabLayoutTheme(tabLayout); - } - - private void getCurrentAccountAndFetchMessage(Bundle savedInstanceState) { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (mNewAccountName != null) { - if (account == null || !account.getUsername().equals(mNewAccountName)) { - new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { - EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); - Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); - - mNewAccountName = null; - if (newAccount == null) { - mNullAccessToken = true; - } else { - mAccessToken = newAccount.getAccessToken(); - } - - bindView(savedInstanceState); - }).execute(); - } else { - mAccessToken = account.getAccessToken(); - bindView(savedInstanceState); - } - } else { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - - bindView(savedInstanceState); - } - }).execute(); - } - - private void bindView(Bundle savedInstanceState) { - sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - if (position == 0) { - unlockSwipeRightToGoBack(); - } else { - lockSwipeRightToGoBack(); - } - } - }); - viewPager.setAdapter(sectionsPagerAdapter); - viewPager.setOffscreenPageLimit(2); - tabLayout.setupWithViewPager(viewPager); - if (savedInstanceState == null && getIntent().getBooleanExtra(EXTRA_VIEW_MESSAGE, false)) { - viewPager.setCurrentItem(1); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.inbox_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_refresh_inbox_activity) { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.refresh(); - } - return true; - } else if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - if (!getClass().getName().equals(event.excludeActivityClassName)) { - finish(); - } - } - - @Override - public void onLongPress() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.goBackToTop(); - } - } - - private void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - private void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } - - private class SectionsPagerAdapter extends FragmentPagerAdapter { - private InboxFragment tab1; - private InboxFragment tab2; - - public SectionsPagerAdapter(@NonNull FragmentManager fm) { - super(fm, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - } - - @NonNull - @Override - public Fragment getItem(int position) { - if (position == 0) { - InboxFragment fragment = new InboxFragment(); - Bundle bundle = new Bundle(); - bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); - fragment.setArguments(bundle); - return fragment; - } else { - InboxFragment fragment = new InboxFragment(); - Bundle bundle = new Bundle(); - bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MESSAGES); - fragment.setArguments(bundle); - return fragment; - } - } - - @Override - public int getCount() { - return 2; - } - - @Nullable - @Override - public CharSequence getPageTitle(int position) { - if (position == 0) { - return getString(R.string.notifications); - } - - return getString(R.string.messages); - } - - @NonNull - @Override - public Object instantiateItem(@NonNull ViewGroup container, int position) { - Fragment fragment = (Fragment) super.instantiateItem(container, position); - if (position == 0) { - tab1 = (InboxFragment) fragment; - } else if (position == 1) { - tab2 = (InboxFragment) fragment; - } - - return fragment; - } - - void refresh() { - if (viewPager.getCurrentItem() == 0) { - if (tab1 != null) { - tab1.refresh(); - } - } else if (viewPager.getCurrentItem() == 1 && tab2 != null) { - tab2.refresh(); - } - } - - void goBackToTop() { - if (viewPager.getCurrentItem() == 0) { - if (tab1 != null) { - tab1.goBackToTop(); - } - } else if (viewPager.getCurrentItem() == 1) { - if (tab2 != null) { - tab2.goBackToTop(); - } - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LinkResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LinkResolverActivity.java deleted file mode 100644 index 9706d015..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LinkResolverActivity.java +++ /dev/null @@ -1,327 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.ActivityNotFoundException; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.net.Uri; -import android.os.Bundle; -import android.widget.Toast; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.browser.customtabs.CustomTabsIntent; - -import java.util.ArrayList; -import java.util.List; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -import static androidx.browser.customtabs.CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION; - -public class LinkResolverActivity extends AppCompatActivity { - - public static final String EXTRA_MESSAGE_FULLNAME = "ENF"; - public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; - public static final String EXTRA_IS_NSFW = "EIN"; - - private static final String POST_PATTERN = "/r/\\w+/comments/\\w+/?\\w+/?"; - private static final String COMMENT_PATTERN = "/(r|u|U|user)/\\w+/comments/\\w+/?\\w+/\\w+/?"; - private static final String SUBREDDIT_PATTERN = "/[rR]/[\\w-]+/?"; - private static final String USER_PATTERN = "/(u|U|user)/[\\w-]+/?"; - private static final String SIDEBAR_PATTERN = "/[rR]/\\w+/about/sidebar"; - private static final String MULTIREDDIT_PATTERN = "/user/\\w+/m/\\w+/?"; - private static final String MULTIREDDIT_PATTERN_2 = "/[rR]/(\\w+\\+?)+/?"; - private static final String REDD_IT_POST_PATTERN = "/\\w+/?"; - private static final String GFYCAT_PATTERN = "(/ifr)?/[\\w-]+$"; - private static final String REDGIFS_PATTERN = "/watch/[\\w-]+$"; - private static final String IMGUR_GALLERY_PATTERN = "/gallery/\\w+/?"; - private static final String IMGUR_ALBUM_PATTERN = "/(album|a)/\\w+/?"; - private static final String IMGUR_IMAGE_PATTERN = "/\\w+/?"; - - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - - public static Uri getRedditUriByPath(String path) { - return Uri.parse("https://www.reddit.com" + path); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - ((Infinity) getApplication()).getAppComponent().inject(this); - - Uri uri = getIntent().getData(); - handleUri(uri); - } - - private void handleUri(Uri uri) { - if (uri == null) { - Toast.makeText(this, R.string.no_link_available, Toast.LENGTH_SHORT).show(); - finish(); - } else { - String path = uri.getPath(); - if (path == null) { - deepLinkError(uri); - } else { - if (path.endsWith("/")) { - path = path.substring(0, path.length() - 1); - } - - if (path.endsWith("jpg") || path.endsWith("png")) { - Intent intent = new Intent(this, ViewImageOrGifActivity.class); - String url = uri.toString(); - String fileName = url.substring(url.lastIndexOf('/') + 1); - intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, url); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, fileName); - intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, fileName); - startActivity(intent); - } else if (path.endsWith("gif")) { - Intent intent = new Intent(this, ViewImageOrGifActivity.class); - String url = uri.toString(); - String fileName = url.substring(url.lastIndexOf('/') + 1); - intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, url); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, fileName); - intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, fileName); - startActivity(intent); - } else if (path.endsWith("mp4")) { - Intent intent = new Intent(this, ViewVideoActivity.class); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_DIRECT); - intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, getIntent().getBooleanExtra(EXTRA_IS_NSFW, false)); - intent.setData(uri); - startActivity(intent); - } else { - String messageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); - String newAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); - - String authority = uri.getAuthority(); - List segments = uri.getPathSegments(); - - if (authority != null) { - if (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app")) { - if (authority.equals("reddit.app.link") && path.isEmpty()) { - String redirect = uri.getQueryParameter("$og_redirect"); - handleUri(Uri.parse(redirect)); - } else if (path.isEmpty()) { - Intent intent = new Intent(this, MainActivity.class); - startActivity(intent); - } else if (path.matches(POST_PATTERN)) { - int commentsIndex = segments.lastIndexOf("comments"); - if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) { - Intent intent = new Intent(this, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); - intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); - intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); - startActivity(intent); - } else { - deepLinkError(uri); - } - } else if (path.matches(COMMENT_PATTERN)) { - int commentsIndex = segments.lastIndexOf("comments"); - if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) { - Intent intent = new Intent(this, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); - intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, segments.get(segments.size() - 1)); - intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); - intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); - startActivity(intent); - } else { - deepLinkError(uri); - } - } else if (path.matches(SUBREDDIT_PATTERN)) { - String subredditName = path.substring(3); - if (subredditName.equals("popular") || subredditName.equals("all")) { - Intent intent = new Intent(this, MainActivity.class); - intent.putExtra(MainActivity.EXTRA_POST_TYPE, subredditName); - intent.putExtra(MainActivity.EXTRA_MESSSAGE_FULLNAME, messageFullname); - intent.putExtra(MainActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); - startActivity(intent); - } else { - Intent intent = new Intent(this, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3)); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); - startActivity(intent); - } - } else if (path.matches(USER_PATTERN)) { - Intent intent = new Intent(this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, segments.get(1)); - intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); - intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); - startActivity(intent); - } else if (path.matches(SIDEBAR_PATTERN)) { - Intent intent = new Intent(this, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3, path.length() - 14)); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_VIEW_SIDEBAR, true); - startActivity(intent); - } else if (path.matches(MULTIREDDIT_PATTERN)) { - Intent intent = new Intent(this, ViewMultiRedditDetailActivity.class); - intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_PATH, path); - startActivity(intent); - } else if (path.matches(MULTIREDDIT_PATTERN_2)) { - String subredditName = path.substring(3); - Intent intent = new Intent(this, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); - startActivity(intent); - } else if (authority.equals("redd.it") && path.matches(REDD_IT_POST_PATTERN)) { - Intent intent = new Intent(this, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1)); - startActivity(intent); - } else { - deepLinkError(uri); - } - } else if (authority.contains("gfycat.com")) { - if (path.matches(GFYCAT_PATTERN)) { - Intent intent = new Intent(this, ViewVideoActivity.class); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, path.substring(path.lastIndexOf("/") + 1)); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); - intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, getIntent().getBooleanExtra(EXTRA_IS_NSFW, false)); - startActivity(intent); - } else { - deepLinkError(uri); - } - } else if (authority.contains("redgifs.com")) { - if (path.matches(REDGIFS_PATTERN)) { - Intent intent = new Intent(this, ViewVideoActivity.class); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, path.substring(path.lastIndexOf("/") + 1)); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); - intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, true); - startActivity(intent); - } else { - deepLinkError(uri); - } - } else if (authority.contains("imgur.com")) { - if (path.matches(IMGUR_GALLERY_PATTERN)) { - Intent intent = new Intent(this, ViewImgurMediaActivity.class); - intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_TYPE, ViewImgurMediaActivity.IMGUR_TYPE_GALLERY); - intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_ID, segments.get(1)); - startActivity(intent); - } else if (path.matches(IMGUR_ALBUM_PATTERN)) { - Intent intent = new Intent(this, ViewImgurMediaActivity.class); - intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_TYPE, ViewImgurMediaActivity.IMGUR_TYPE_ALBUM); - intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_ID, segments.get(1)); - startActivity(intent); - } else if (path.matches(IMGUR_IMAGE_PATTERN)) { - Intent intent = new Intent(this, ViewImgurMediaActivity.class); - intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_TYPE, ViewImgurMediaActivity.IMGUR_TYPE_IMAGE); - intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_ID, path.substring(1)); - startActivity(intent); - } else if (path.endsWith("gifv")) { - String url = uri.toString(); - url = url.substring(0, url.length() - 5) + ".mp4"; - Intent intent = new Intent(this, ViewVideoActivity.class); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_DIRECT); - intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, getIntent().getBooleanExtra(EXTRA_IS_NSFW, false)); - intent.setData(Uri.parse(url)); - startActivity(intent); - } else { - deepLinkError(uri); - } - } else { - deepLinkError(uri); - } - } else { - deepLinkError(uri); - } - } - } - - finish(); - } - } - - private void deepLinkError(Uri uri) { - PackageManager pm = getPackageManager(); - - String authority = uri.getAuthority(); - if(authority != null && (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app.link"))) { - openInCustomTabs(uri, pm, false); - return; - } - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.OPEN_LINK_IN_APP, false)) { - openInCustomTabs(uri, pm, true); - } else { - openInBrowser(uri, pm, true); - } - } - - private void openInBrowser(Uri uri, PackageManager pm, boolean handleError) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(uri); - - try { - startActivity(intent); - } catch (ActivityNotFoundException e) { - if (handleError) { - openInCustomTabs(uri, pm, false); - } else { - Toast.makeText(this, R.string.no_browser_found, Toast.LENGTH_SHORT).show(); - } - } - } - - private ArrayList getCustomTabsPackages(PackageManager pm) { - // Get default VIEW intent handler. - Intent activityIntent = new Intent() - .setAction(Intent.ACTION_VIEW) - .addCategory(Intent.CATEGORY_BROWSABLE) - .setData(Uri.fromParts("http", "", null)); - - // Get all apps that can handle VIEW intents. - List resolvedActivityList = pm.queryIntentActivities(activityIntent, 0); - ArrayList packagesSupportingCustomTabs = new ArrayList<>(); - for (ResolveInfo info : resolvedActivityList) { - Intent serviceIntent = new Intent(); - serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION); - serviceIntent.setPackage(info.activityInfo.packageName); - // Check if this package also resolves the Custom Tabs service. - if (pm.resolveService(serviceIntent, 0) != null) { - packagesSupportingCustomTabs.add(info); - } - } - return packagesSupportingCustomTabs; - } - - private void openInCustomTabs(Uri uri, PackageManager pm, boolean handleError) { - ArrayList resolveInfos = getCustomTabsPackages(pm); - if (!resolveInfos.isEmpty()) { - CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); - // add share action to menu list - builder.addDefaultShareMenuItem(); - builder.setToolbarColor(mCustomThemeWrapper.getColorPrimary()); - CustomTabsIntent customTabsIntent = builder.build(); - customTabsIntent.intent.setPackage(resolveInfos.get(0).activityInfo.packageName); - if (uri.getScheme() == null) { - uri = Uri.parse("http://" + uri.toString()); - } - try { - customTabsIntent.launchUrl(this, uri); - } catch (ActivityNotFoundException e) { - if (handleError) { - openInBrowser(uri, pm, false); - } else { - Toast.makeText(this, R.string.no_browser_found, Toast.LENGTH_SHORT).show(); - } - } - } else { - if (handleError) { - openInBrowser(uri, pm, false); - } else { - Toast.makeText(this, R.string.no_browser_found, Toast.LENGTH_SHORT).show(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java deleted file mode 100644 index 1c634dcd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/LoginActivity.java +++ /dev/null @@ -1,251 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.app.Activity; -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.util.Log; -import android.view.InflateException; -import android.view.MenuItem; -import android.webkit.CookieManager; -import android.webkit.WebView; -import android.webkit.WebViewClient; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -import com.google.android.material.appbar.AppBarLayout; -import com.r0adkll.slidr.Slidr; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; -import java.util.Map; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.AsyncTask.ParseAndInsertNewAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FetchMyInfo; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class LoginActivity extends BaseActivity { - - @BindView(R.id.coordinator_layout_login_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_login_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_login_activity) - Toolbar toolbar; - @BindView(R.id.two_fa_infO_text_view_login_activity) - TextView twoFAInfoTextView; - @BindView(R.id.webview_login_activity) - WebView webView; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String authCode; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - try { - setContentView(R.layout.activity_login); - } catch (InflateException ie) { - Log.e("LoginActivity", "Failed to inflate LoginActivity: " + ie.getMessage()); - Toast.makeText(LoginActivity.this, R.string.no_system_webview_error, Toast.LENGTH_SHORT).show(); - finish(); - return; - } - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - setSupportActionBar(toolbar); - - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - webView.getSettings().setJavaScriptEnabled(true); - - Uri baseUri = Uri.parse(APIUtils.OAUTH_URL); - Uri.Builder uriBuilder = baseUri.buildUpon(); - uriBuilder.appendQueryParameter(APIUtils.CLIENT_ID_KEY, APIUtils.CLIENT_ID); - uriBuilder.appendQueryParameter(APIUtils.RESPONSE_TYPE_KEY, APIUtils.RESPONSE_TYPE); - uriBuilder.appendQueryParameter(APIUtils.STATE_KEY, APIUtils.STATE); - uriBuilder.appendQueryParameter(APIUtils.REDIRECT_URI_KEY, APIUtils.REDIRECT_URI); - uriBuilder.appendQueryParameter(APIUtils.DURATION_KEY, APIUtils.DURATION); - uriBuilder.appendQueryParameter(APIUtils.SCOPE_KEY, APIUtils.SCOPE); - - String url = uriBuilder.toString(); - - CookieManager.getInstance().removeAllCookies(aBoolean -> { - }); - - webView.loadUrl(url); - webView.setWebViewClient(new WebViewClient() { - @Override - public boolean shouldOverrideUrlLoading(WebView view, String url) { - if (url.contains("&code=") || url.contains("?code=")) { - Uri uri = Uri.parse(url); - String state = uri.getQueryParameter("state"); - if (state.equals(APIUtils.STATE)) { - authCode = uri.getQueryParameter("code"); - - Map params = new HashMap<>(); - params.put(APIUtils.GRANT_TYPE_KEY, "authorization_code"); - params.put("code", authCode); - params.put("redirect_uri", APIUtils.REDIRECT_URI); - - RedditAPI api = mRetrofit.create(RedditAPI.class); - Call accessTokenCall = api.getAccessToken(APIUtils.getHttpBasicAuthHeader(), params); - accessTokenCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - try { - String accountResponse = response.body(); - if (accountResponse == null) { - //Handle error - return; - } - - JSONObject responseJSON = new JSONObject(accountResponse); - String accessToken = responseJSON.getString(APIUtils.ACCESS_TOKEN_KEY); - String refreshToken = responseJSON.getString(APIUtils.REFRESH_TOKEN_KEY); - - FetchMyInfo.fetchAccountInfo(mOauthRetrofit, mRedditDataRoomDatabase, - accessToken, new FetchMyInfo.FetchMyInfoListener() { - @Override - public void onFetchMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) { - new ParseAndInsertNewAccountAsyncTask(name, accessToken, refreshToken, profileImageUrl, bannerImageUrl, - karma, authCode, mRedditDataRoomDatabase.accountDao(), - () -> { - Intent resultIntent = new Intent(); - setResult(Activity.RESULT_OK, resultIntent); - finish(); - }).execute(); - } - - @Override - public void onFetchMyInfoFailed(boolean parseFailed) { - if (parseFailed) { - Toast.makeText(LoginActivity.this, R.string.parse_user_info_error, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(LoginActivity.this, R.string.cannot_fetch_user_info, Toast.LENGTH_SHORT).show(); - } - - finish(); - } - }); - } catch (JSONException e) { - e.printStackTrace(); - Toast.makeText(LoginActivity.this, R.string.parse_json_response_error, Toast.LENGTH_SHORT).show(); - finish(); - } - } else { - Toast.makeText(LoginActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show(); - finish(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - Toast.makeText(LoginActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show(); - finish(); - } - }); - } else { - Toast.makeText(LoginActivity.this, R.string.something_went_wrong, Toast.LENGTH_SHORT).show(); - finish(); - } - - } else if (url.contains("error=access_denied")) { - Toast.makeText(LoginActivity.this, R.string.access_denied, Toast.LENGTH_SHORT).show(); - finish(); - } else { - view.loadUrl(url); - } - - return true; - } - - @Override - public void onPageStarted(WebView view, String url, Bitmap favicon) { - super.onPageStarted(view, url, favicon); - } - - @Override - public void onPageFinished(WebView view, String url) { - super.onPageFinished(view, url); - } - }); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - twoFAInfoTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); - Drawable infoDrawable = Utils.getTintedDrawable(this, R.drawable.ic_info_preference_24dp, mCustomThemeWrapper.getPrimaryIconColor()); - twoFAInfoTextView.setCompoundDrawablesWithIntrinsicBounds(infoDrawable, null, null, null); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return false; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java deleted file mode 100644 index bf354c21..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/MainActivity.java +++ /dev/null @@ -1,1529 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.graphics.Color; -import android.os.Build; -import android.os.Bundle; -import android.view.Gravity; -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 android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBarDrawerToggle; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.core.view.GravityCompat; -import androidx.drawerlayout.widget.DrawerLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.viewpager2.adapter.FragmentStateAdapter; -import androidx.viewpager2.widget.ViewPager2; -import androidx.work.Constraints; -import androidx.work.ExistingPeriodicWorkPolicy; -import androidx.work.NetworkType; -import androidx.work.PeriodicWorkRequest; -import androidx.work.WorkManager; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.bottomappbar.BottomAppBar; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.navigation.NavigationView; -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Account.AccountViewModel; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.Adapter.NavigationDrawerRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertSubscribedThingsAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SwitchAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SwitchToAnonymousAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FABMoreOptionsBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.RandomBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTimeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.ChangeConfirmToExitEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeDisableSwipingBetweenTabsEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeLockBottomAppBarEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeRequireAuthToAccountSectionEvent; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.FetchMyInfo; -import ml.docilealligator.infinityforreddit.FetchSubscribedThing; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.ReadMessage; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.PullNotificationWorker; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditViewModel; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Retrofit; - -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; - -public class MainActivity extends BaseActivity implements SortTypeSelectionCallback, - PostTypeBottomSheetFragment.PostTypeSelectionCallback, PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, - ActivityToolbarInterface, FABMoreOptionsBottomSheetFragment.FABOptionSelectionCallback, RandomBottomSheetFragment.RandomOptionSelectionCallback { - - static final String EXTRA_POST_TYPE = "EPT"; - static final String EXTRA_MESSSAGE_FULLNAME = "ENF"; - static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; - - private static final String FETCH_USER_INFO_STATE = "FUIS"; - private static final String FETCH_SUBSCRIPTIONS_STATE = "FSS"; - private static final String DRAWER_ON_ACCOUNT_SWITCH_STATE = "DOASS"; - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String ACCOUNT_PROFILE_IMAGE_URL_STATE = "APIUS"; - private static final String ACCOUNT_BANNER_IMAGE_URL_STATE = "ABIUS"; - private static final String ACCOUNT_KARMA_STATE = "AKS"; - private static final String MESSAGE_FULLNAME_STATE = "MFS"; - private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; - - private static final int LOGIN_ACTIVITY_REQUEST_CODE = 0; - - @BindView(R.id.drawer_layout) - DrawerLayout drawer; - @BindView(R.id.navigation_view_main_activity) - NavigationView navigationView; - @BindView(R.id.coordinator_layout_main_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_main_activity) - AppBarLayout appBarLayout; - @BindView(R.id.view_pager_main_activity) - ViewPager2 viewPager2; - @BindView(R.id.collapsing_toolbar_layout_main_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.toolbar) - Toolbar toolbar; - @BindView(R.id.nav_drawer_recycler_view_main_activity) - RecyclerView navDrawerRecyclerView; - @BindView(R.id.tab_layout_main_activity) - TabLayout tabLayout; - @BindView(R.id.bottom_app_bar_main_activity) - BottomAppBar bottomAppBar; - @BindView(R.id.linear_layout_bottom_app_bar_main_activity) - LinearLayout linearLayoutBottomAppBar; - @BindView(R.id.option_1_bottom_app_bar_main_activity) - ImageView option1BottomAppBar; - @BindView(R.id.option_2_bottom_app_bar_main_activity) - ImageView option2BottomAppBar; - @BindView(R.id.option_3_bottom_app_bar_main_activity) - ImageView option3BottomAppBar; - @BindView(R.id.option_4_bottom_app_bar_main_activity) - ImageView option4BottomAppBar; - @BindView(R.id.fab_main_activity) - FloatingActionButton fab; - SubscribedSubredditViewModel subscribedSubredditViewModel; - AccountViewModel accountViewModel; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - @Named("main_activity_tabs") - SharedPreferences mMainActivityTabsSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences mNsfwAndSpoilerSharedPreferences; - @Inject - @Named("bottom_app_bar") - SharedPreferences bottomAppBarSharedPreference; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private FragmentManager fragmentManager; - private SectionsPagerAdapter sectionsPagerAdapter; - private AppBarLayout.LayoutParams params; - private PostTypeBottomSheetFragment postTypeBottomSheetFragment; - private SortTypeBottomSheetFragment sortTypeBottomSheetFragment; - private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - private FABMoreOptionsBottomSheetFragment fabMoreOptionsBottomSheetFragment; - private NavigationDrawerRecyclerViewAdapter adapter; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String mProfileImageUrl; - private String mBannerImageUrl; - private int mKarma; - private boolean mFetchUserInfoSuccess = false; - private boolean mFetchSubscriptionsSuccess = false; - private boolean mDrawerOnAccountSwitch = false; - private String mMessageFullname; - private String mNewAccountName; - private Menu mMenu; - private boolean isInLazyMode = false; - private boolean showBottomAppBar; - private boolean mConfirmToExit; - private boolean mLockBottomAppBar; - private boolean mDisableSwipingBetweenTabs; - private boolean mShowFavoriteSubscribedSubreddits; - private boolean mShowSubscribedSubreddits; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setTheme(R.style.AppTheme_NoActionBarWithTransparentStatusBar); - - setHasDrawerLayout(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_main); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - drawer.setStatusBarBackgroundColor(Color.TRANSPARENT); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - drawer.setFitsSystemWindows(false); - drawer.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - - int navBarHeight = getNavBarHeight(); - if (navBarHeight > 0) { - CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); - params.bottomMargin += navBarHeight; - fab.setLayoutParams(params); - linearLayoutBottomAppBar.setPadding(0, - linearLayoutBottomAppBar.getPaddingTop(), 0, navBarHeight); - navDrawerRecyclerView.setPadding(0, 0, 0, navBarHeight); - } - } else { - drawer.setStatusBarBackgroundColor(mCustomThemeWrapper.getColorPrimaryDark()); - } - } - - postTypeBottomSheetFragment = new PostTypeBottomSheetFragment(); - sortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - fabMoreOptionsBottomSheetFragment = new FABMoreOptionsBottomSheetFragment(); - - setSupportActionBar(toolbar); - setToolbarGoToTop(toolbar); - - ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( - this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); - toggle.getDrawerArrowDrawable().setColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); - drawer.addDrawerListener(toggle); - drawer.addDrawerListener(new DrawerLayout.SimpleDrawerListener() { - @Override - public void onDrawerClosed(View drawerView) { - if (adapter != null) { - if (adapter.closeAccountSectionWithoutChangeIconResource(true)) { - adapter.notifyItemChanged(0); - } - } - } - }); - toggle.syncState(); - - params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - - showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); - mConfirmToExit = mSharedPreferences.getBoolean(SharedPreferencesUtils.CONFIRM_TO_EXIT, false); - mLockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); - mDisableSwipingBetweenTabs = mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false); - - fragmentManager = getSupportFragmentManager(); - - if (savedInstanceState != null) { - mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE); - mFetchSubscriptionsSuccess = savedInstanceState.getBoolean(FETCH_SUBSCRIPTIONS_STATE); - mDrawerOnAccountSwitch = savedInstanceState.getBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE); - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - mProfileImageUrl = savedInstanceState.getString(ACCOUNT_PROFILE_IMAGE_URL_STATE); - mBannerImageUrl = savedInstanceState.getString(ACCOUNT_BANNER_IMAGE_URL_STATE); - mKarma = savedInstanceState.getInt(ACCOUNT_KARMA_STATE); - mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); - mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - } else { - mMessageFullname = getIntent().getStringExtra(EXTRA_MESSSAGE_FULLNAME); - mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); - getCurrentAccountAndBindView(); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - int backgroundColor = mCustomThemeWrapper.getBackgroundColor(); - drawer.setBackgroundColor(backgroundColor); - int bottomAppBarIconColor = mCustomThemeWrapper.getBottomAppBarIconColor(); - option1BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option2BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option3BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option4BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - navigationView.setBackgroundColor(backgroundColor); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - applyTabLayoutTheme(tabLayout); - bottomAppBar.setBackgroundTint(ColorStateList.valueOf(mCustomThemeWrapper.getBottomAppBarBackgroundColor())); - applyFABTheme(fab); - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - boolean enableNotification = mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_NOTIFICATION_KEY, true); - long notificationInterval = Long.parseLong(mSharedPreferences.getString(SharedPreferencesUtils.NOTIFICATION_INTERVAL_KEY, "1")); - TimeUnit timeUnit = (notificationInterval == 15 || notificationInterval == 30) ? TimeUnit.MINUTES : TimeUnit.HOURS; - - WorkManager workManager = WorkManager.getInstance(this); - - if (mNewAccountName != null) { - if (account == null || !account.getUsername().equals(mNewAccountName)) { - new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { - EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); - Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); - - mNewAccountName = null; - if (newAccount == null) { - mNullAccessToken = true; - } else { - mAccessToken = newAccount.getAccessToken(); - mAccountName = newAccount.getUsername(); - mProfileImageUrl = newAccount.getProfileImageUrl(); - mBannerImageUrl = newAccount.getBannerImageUrl(); - mKarma = newAccount.getKarma(); - } - - if (enableNotification) { - Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); - - PeriodicWorkRequest pullNotificationRequest = - new PeriodicWorkRequest.Builder(PullNotificationWorker.class, - notificationInterval, timeUnit) - .setConstraints(constraints) - .build(); - - workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, - ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); - } else { - workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); - } - - bindView(); - }).execute(); - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - mProfileImageUrl = account.getProfileImageUrl(); - mBannerImageUrl = account.getBannerImageUrl(); - mKarma = account.getKarma(); - - if (enableNotification) { - Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); - - PeriodicWorkRequest pullNotificationRequest = - new PeriodicWorkRequest.Builder(PullNotificationWorker.class, - notificationInterval, timeUnit) - .setConstraints(constraints) - .build(); - - workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, - ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); - } else { - workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); - } - - bindView(); - } - } else { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - mProfileImageUrl = account.getProfileImageUrl(); - mBannerImageUrl = account.getBannerImageUrl(); - mKarma = account.getKarma(); - } - - if (enableNotification) { - Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); - - PeriodicWorkRequest pullNotificationRequest = - new PeriodicWorkRequest.Builder(PullNotificationWorker.class, - notificationInterval, timeUnit) - .setConstraints(constraints) - .build(); - - workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, - ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); - } else { - workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); - } - - bindView(); - } - }).execute(); - } - - private void bottomAppBarOptionAction(int option) { - switch (option) { - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: { - Intent intent = new Intent(this, SubscribedThingListingActivity.class); - startActivity(intent); - break; - } - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: { - Intent intent = new Intent(this, SubscribedThingListingActivity.class); - intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); - startActivity(intent); - break; - } - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX: { - Intent intent = new Intent(this, InboxActivity.class); - startActivity(intent); - break; - } - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_PROFILE: { - Intent intent = new Intent(this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); - startActivity(intent); - break; - } - } - } - - private int getBottomAppBarOptionDrawableResource(int option) { - switch (option) { - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: - return R.drawable.ic_subscritptions_bottom_app_bar_24dp; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: - return R.drawable.ic_multi_reddit_24dp; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX: - return R.drawable.ic_inbox_24dp; - default: - return R.drawable.ic_account_circle_24dp; - } - } - - private void bindView() { - if (isDestroyed()) { - return; - } - - if (mAccessToken == null) { - bottomAppBar.setVisibility(View.GONE); - fab.setVisibility(View.GONE); - } else { - if (showBottomAppBar) { - int optionCount = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT, 4); - int option1 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS); - int option2 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS); - - bottomAppBar.setVisibility(View.VISIBLE); - - if (optionCount == 2) { - linearLayoutBottomAppBar.setWeightSum(3); - option1BottomAppBar.setVisibility(View.GONE); - option3BottomAppBar.setVisibility(View.GONE); - - option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); - option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); - - option2BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option1); - }); - - option4BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option2); - }); - } else { - int option3 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX); - int option4 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_PROFILE); - - option1BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); - option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); - option3BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option3)); - option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option4)); - - option1BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option1); - }); - - option2BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option2); - }); - - option3BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option3); - }); - - option4BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option4); - }); - } - } else { - CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); - lp.setAnchorId(View.NO_ID); - lp.gravity = Gravity.END | Gravity.BOTTOM; - fab.setLayoutParams(lp); - } - - int fabOption = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS); - switch (fabOption) { - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_REFRESH: - fab.setImageResource(R.drawable.ic_refresh_24dp); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: - fab.setImageResource(R.drawable.ic_sort_toolbar_24dp); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: - fab.setImageResource(R.drawable.ic_post_layout_24dp); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SEARCH: - fab.setImageResource(R.drawable.ic_search_black_24dp); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: - fab.setImageResource(R.drawable.ic_subreddit_24dp); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_USER: - fab.setImageResource(R.drawable.ic_user_24dp); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_RANDOM: - fab.setImageResource(R.drawable.ic_random_24dp); - break; - default: - fab.setImageResource(R.drawable.ic_add_day_night_24dp); - break; - } - fab.setOnClickListener(view -> { - switch (fabOption) { - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_REFRESH: { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.refresh(); - } - break; - } - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: { - changeSortType(); - break; - } - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: { - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - break; - } - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SEARCH: { - Intent intent = new Intent(this, SearchActivity.class); - startActivity(intent); - break; - } - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: - goToSubreddit(); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_USER: - goToUser(); - break; - case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_RANDOM: - randomThing(); - break; - default: - postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); - break; - } - }); - fab.setOnLongClickListener(view -> { - fabMoreOptionsBottomSheetFragment.show(getSupportFragmentManager(), fabMoreOptionsBottomSheetFragment.getTag()); - return true; - }); - fab.setVisibility(View.VISIBLE); - } - - adapter = new NavigationDrawerRecyclerViewAdapter(this, mSharedPreferences, - mNsfwAndSpoilerSharedPreferences, mCustomThemeWrapper, mAccountName, - mProfileImageUrl, mBannerImageUrl, mKarma, - new NavigationDrawerRecyclerViewAdapter.ItemClickListener() { - @Override - public void onMenuClick(int stringId) { - Intent intent = null; - switch (stringId) { - case R.string.profile: - intent = new Intent(MainActivity.this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); - break; - case R.string.subscriptions: - intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); - break; - case R.string.multi_reddit: - intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); - intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); - break; - case R.string.inbox: - intent = new Intent(MainActivity.this, InboxActivity.class); - break; - case R.string.upvoted: - intent = new Intent(MainActivity.this, AccountPostsActivity.class); - intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_UPVOTED); - break; - case R.string.downvoted: - intent = new Intent(MainActivity.this, AccountPostsActivity.class); - intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_DOWNVOTED); - break; - case R.string.hidden: - intent = new Intent(MainActivity.this, AccountPostsActivity.class); - intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_HIDDEN); - break; - case R.string.saved: - intent = new Intent(MainActivity.this, AccountSavedThingActivity.class); - break; - case R.string.gilded: - intent = new Intent(MainActivity.this, AccountPostsActivity.class); - intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_GILDED); - break; - case R.string.light_theme: - mSharedPreferences.edit().putString(SharedPreferencesUtils.THEME_KEY, "0").apply(); - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); - mCustomThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); - break; - case R.string.dark_theme: - mSharedPreferences.edit().putString(SharedPreferencesUtils.THEME_KEY, "1").apply(); - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { - mCustomThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); - } else { - mCustomThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); - } - break; - case R.string.enable_nsfw: - if (sectionsPagerAdapter != null) { - mNsfwAndSpoilerSharedPreferences.edit().putBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, true).apply(); - sectionsPagerAdapter.changeNSFW(true); - } - break; - case R.string.disable_nsfw: - if (sectionsPagerAdapter != null) { - mNsfwAndSpoilerSharedPreferences.edit().putBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false).apply(); - sectionsPagerAdapter.changeNSFW(false); - } - break; - case R.string.settings: - intent = new Intent(MainActivity.this, SettingsActivity.class); - break; - case R.string.add_account: - Intent addAccountIntent = new Intent(MainActivity.this, LoginActivity.class); - startActivityForResult(addAccountIntent, LOGIN_ACTIVITY_REQUEST_CODE); - break; - case R.string.anonymous_account: - new SwitchToAnonymousAccountAsyncTask(mRedditDataRoomDatabase, false, - () -> { - Intent anonymousIntent = new Intent(MainActivity.this, MainActivity.class); - startActivity(anonymousIntent); - finish(); - }).execute(); - break; - case R.string.log_out: - new SwitchToAnonymousAccountAsyncTask(mRedditDataRoomDatabase, true, - () -> { - Intent logOutIntent = new Intent(MainActivity.this, MainActivity.class); - startActivity(logOutIntent); - finish(); - }).execute(); - - } - if (intent != null) { - startActivity(intent); - } - drawer.closeDrawers(); - } - - @Override - public void onSubscribedSubredditClick(String subredditName) { - Intent intent = new Intent(MainActivity.this, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); - startActivity(intent); - } - - @Override - public void onAccountClick(String accountName) { - new SwitchAccountAsyncTask(mRedditDataRoomDatabase, accountName, newAccount -> { - Intent intent = new Intent(MainActivity.this, MainActivity.class); - startActivity(intent); - finish(); - }).execute(); - } - }); - navDrawerRecyclerView.setLayoutManager(new LinearLayoutManager(this)); - navDrawerRecyclerView.setAdapter(adapter); - - int tabCount = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_COUNT, 3); - mShowFavoriteSubscribedSubreddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, false); - mShowSubscribedSubreddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, false); - sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle(), tabCount, - mShowFavoriteSubscribedSubreddits, mShowSubscribedSubreddits); - viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(1); - viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); - if (mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true)) { - if (mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) { - tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); - } else { - tabLayout.setTabMode(TabLayout.MODE_FIXED); - } - new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { - if (mAccessToken == null) { - switch (position) { - case 0: - tab.setText(R.string.popular); - break; - case 1: - tab.setText(R.string.all); - break; - } - } else { - switch (position) { - case 0: - tab.setText(mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.home))); - break; - case 1: - tab.setText(mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, getString(R.string.popular))); - break; - case 2: - tab.setText(mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE, getString(R.string.all))); - break; - } - if (position >= tabCount && (mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) && sectionsPagerAdapter != null) { - List favoriteSubscribedSubreddits = sectionsPagerAdapter.favoriteSubscribedSubreddits; - List subscribedSubreddits = sectionsPagerAdapter.subscribedSubreddits; - if (position - tabCount < favoriteSubscribedSubreddits.size()) { - tab.setText(favoriteSubscribedSubreddits.get(position - tabCount).getName()); - } else if (position - tabCount - favoriteSubscribedSubreddits.size() < subscribedSubreddits.size()) { - tab.setText(subscribedSubreddits.get(position - tabCount - favoriteSubscribedSubreddits.size()).getName()); - } - } - } - }).attach(); - } else { - tabLayout.setVisibility(View.GONE); - } - - viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageSelected(int position) { - if (mAccessToken != null) { - if (showBottomAppBar) { - bottomAppBar.performShow(); - } - fab.show(); - } - sectionsPagerAdapter.displaySortTypeInToolbar(); - } - }); - - fixViewPager2Sensitivity(viewPager2); - - loadSubscriptions(); - - subscribedSubredditViewModel = new ViewModelProvider(this, - new SubscribedSubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName)) - .get(SubscribedSubredditViewModel.class); - subscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, - subscribedSubredditData -> { - adapter.setSubscribedSubreddits(subscribedSubredditData); - if (mShowSubscribedSubreddits && sectionsPagerAdapter != null) { - sectionsPagerAdapter.setSubscribedSubreddits(subscribedSubredditData); - } - }); - subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> { - adapter.setFavoriteSubscribedSubreddits(subscribedSubredditData); - if (mShowFavoriteSubscribedSubreddits && sectionsPagerAdapter != null) { - sectionsPagerAdapter.setFavoriteSubscribedSubreddits(subscribedSubredditData); - } - }); - - accountViewModel = new ViewModelProvider(this, - new AccountViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName)).get(AccountViewModel.class); - accountViewModel.getAccountsExceptCurrentAccountLiveData().observe(this, adapter::changeAccountsDataset); - accountViewModel.getCurrentAccountLiveData().observe(this, account -> { - if (account != null) { - adapter.updateKarma(account.getKarma()); - } - }); - - if (getIntent().hasExtra(EXTRA_POST_TYPE)) { - String type = getIntent().getStringExtra(EXTRA_POST_TYPE); - if (type != null && type.equals("popular")) { - viewPager2.setCurrentItem(1); - } else { - viewPager2.setCurrentItem(2); - } - } - - loadUserData(); - - if (mAccessToken != null) { - if (mMessageFullname != null) { - ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { - @Override - public void readSuccess() { - mMessageFullname = null; - } - - @Override - public void readFailed() { - - } - }); - } - } - } - - private void loadSubscriptions() { - if (mAccessToken != null && !mFetchSubscriptionsSuccess) { - FetchSubscribedThing.fetchSubscribedThing(mOauthRetrofit, mAccessToken, mAccountName, null, - new ArrayList<>(), new ArrayList<>(), - new ArrayList<>(), - new FetchSubscribedThing.FetchSubscribedThingListener() { - @Override - public void onFetchSubscribedThingSuccess(ArrayList subscribedSubredditData, - ArrayList subscribedUserData, - ArrayList subredditData) { - new InsertSubscribedThingsAsyncTask( - mRedditDataRoomDatabase, - mAccountName, - subscribedSubredditData, - subscribedUserData, - subredditData, - () -> mFetchSubscriptionsSuccess = true).execute(); - } - - @Override - public void onFetchSubscribedThingFail() { - mFetchSubscriptionsSuccess = false; - } - }); - } - } - - private void loadUserData() { - if (!mFetchUserInfoSuccess) { - FetchMyInfo.fetchAccountInfo(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, - new FetchMyInfo.FetchMyInfoListener() { - @Override - public void onFetchMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) { - mAccountName = name; - mProfileImageUrl = profileImageUrl; - mBannerImageUrl = bannerImageUrl; - mKarma = karma; - mFetchUserInfoSuccess = true; - } - - @Override - public void onFetchMyInfoFailed(boolean parseFailed) { - mFetchUserInfoSuccess = false; - } - }); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == LOGIN_ACTIVITY_REQUEST_CODE && resultCode == Activity.RESULT_OK) { - Intent intent = new Intent(this, MainActivity.class); - startActivity(intent); - finish(); - } - - super.onActivityResult(requestCode, resultCode, data); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.main_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_main_activity); - - if (isInLazyMode) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } else { - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } - - return true; - } - - private void changeSortType() { - int currentPostType = sectionsPagerAdapter.getCurrentPostType(); - Bundle bundle = new Bundle(); - if (currentPostType != PostDataSource.TYPE_FRONT_PAGE) { - bundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - } else { - bundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, false); - } - sortTypeBottomSheetFragment.setArguments(bundle); - sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_search_main_activity: - Intent intent = new Intent(this, SearchActivity.class); - startActivity(intent); - return true; - case R.id.action_sort_main_activity: - changeSortType(); - return true; - case R.id.action_refresh_main_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_main_activity).setTitle(R.string.action_start_lazy_mode); - } - sectionsPagerAdapter.refresh(); - mFetchUserInfoSuccess = false; - loadUserData(); - return true; - case R.id.action_lazy_mode_main_activity: - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_main_activity); - if (isInLazyMode) { - sectionsPagerAdapter.stopLazyMode(); - isInLazyMode = false; - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } else { - if (sectionsPagerAdapter.startLazyMode()) { - isInLazyMode = true; - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } - } - return true; - case R.id.action_change_post_layout_main_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - } - return false; - } - - @Override - public void onBackPressed() {; - if (drawer.isDrawerOpen(GravityCompat.START)) { - drawer.closeDrawer(GravityCompat.START); - } else { - if (mConfirmToExit) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.exit_app) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } else { - super.onBackPressed(); - } - } - } - - @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 - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess); - outState.putBoolean(FETCH_SUBSCRIPTIONS_STATE, mFetchSubscriptionsSuccess); - outState.putBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE, mDrawerOnAccountSwitch); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putString(ACCOUNT_PROFILE_IMAGE_URL_STATE, mProfileImageUrl); - outState.putString(ACCOUNT_BANNER_IMAGE_URL_STATE, mBannerImageUrl); - outState.putInt(ACCOUNT_KARMA_STATE, mKarma); - outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); - outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Override - public void sortTypeSelected(SortType sortType) { - sectionsPagerAdapter.changeSortType(sortType); - } - - @Override - public void sortTypeSelected(String sortType) { - Bundle bundle = new Bundle(); - bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); - sortTimeBottomSheetFragment.setArguments(bundle); - sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); - } - - @Override - public void postTypeSelected(int postType) { - Intent intent; - switch (postType) { - case PostTypeBottomSheetFragment.TYPE_TEXT: - intent = new Intent(MainActivity.this, PostTextActivity.class); - startActivity(intent); - break; - case PostTypeBottomSheetFragment.TYPE_LINK: - intent = new Intent(MainActivity.this, PostLinkActivity.class); - startActivity(intent); - break; - case PostTypeBottomSheetFragment.TYPE_IMAGE: - intent = new Intent(MainActivity.this, PostImageActivity.class); - startActivity(intent); - break; - case PostTypeBottomSheetFragment.TYPE_VIDEO: - intent = new Intent(MainActivity.this, PostVideoActivity.class); - startActivity(intent); - } - } - - @Override - public void postLayoutSelected(int postLayout) { - sectionsPagerAdapter.changePostLayout(postLayout); - } - - public void postScrollUp() { - if (mAccessToken != null) { - if (showBottomAppBar && !mLockBottomAppBar) { - bottomAppBar.performShow(); - } - if (!(showBottomAppBar && mLockBottomAppBar)) { - fab.show(); - } - } - } - - public void postScrollDown() { - if (mAccessToken != null) { - if (!(showBottomAppBar && mLockBottomAppBar)) { - fab.hide(); - } - if (showBottomAppBar && !mLockBottomAppBar) { - bottomAppBar.performHide(); - } - } - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - if (!getClass().getName().equals(event.excludeActivityClassName)) { - finish(); - } - } - - @Subscribe - public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { - sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); - if (adapter != null) { - adapter.setNSFWEnabled(changeNSFWEvent.nsfw); - } - } - - @Subscribe - public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { - recreate(); - } - - @Subscribe - public void onChangeConfirmToExitEvent(ChangeConfirmToExitEvent changeConfirmToExitEvent) { - mConfirmToExit = changeConfirmToExitEvent.confirmToExit; - } - - @Subscribe - public void onChangeLockBottomAppBar(ChangeLockBottomAppBarEvent changeLockBottomAppBarEvent) { - mLockBottomAppBar = changeLockBottomAppBarEvent.lockBottomAppBar; - } - - @Subscribe - public void onChangeDisableSwipingBetweenTabsEvent(ChangeDisableSwipingBetweenTabsEvent changeDisableSwipingBetweenTabsEvent) { - mDisableSwipingBetweenTabs = changeDisableSwipingBetweenTabsEvent.disableSwipingBetweenTabs; - viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); - } - - @Subscribe - public void onChangeRequireAuthToAccountSectionEvent(ChangeRequireAuthToAccountSectionEvent changeRequireAuthToAccountSectionEvent) { - adapter.setRequireAuthToAccountSection(changeRequireAuthToAccountSectionEvent.requireAuthToAccountSection); - } - - @Override - public void onLongPress() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.goBackToTop(); - } - } - - @Override - public void displaySortType() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.displaySortTypeInToolbar(); - } - } - - @Override - public void fabOptionSelected(int option) { - switch (option) { - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SUBMIT_POST: - postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_REFRESH: - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.refresh(); - } - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_SORT_TYPE: - changeSortType(); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_POST_LAYOUT: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SEARCH: - Intent intent = new Intent(this, SearchActivity.class); - startActivity(intent); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_SUBREDDIT: { - goToSubreddit(); - break; - } - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_USER: { - goToUser(); - break; - } - case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { - randomThing(); - break; - } - } - } - - private void goToSubreddit() { - EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); - thingEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.go_to_subreddit) - .setView(thingEditText) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); - subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); - startActivity(subredditIntent); - }) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - }) - .show(); - } - - private void goToUser() { - EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); - thingEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.go_to_user) - .setView(thingEditText) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - Intent userIntent = new Intent(this, ViewUserDetailActivity.class); - userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); - startActivity(userIntent); - }) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - }) - .show(); - } - - private void randomThing() { - RandomBottomSheetFragment randomBottomSheetFragment = new RandomBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putBoolean(RandomBottomSheetFragment.EXTRA_IS_NSFW, mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)); - randomBottomSheetFragment.setArguments(bundle); - randomBottomSheetFragment.show(getSupportFragmentManager(), randomBottomSheetFragment.getTag()); - } - - @Override - public void randomOptionSelected(int option) { - Intent intent = new Intent(this, FetchRandomSubredditOrPostActivity.class); - intent.putExtra(FetchRandomSubredditOrPostActivity.EXTRA_RANDOM_OPTION, option); - startActivity(intent); - } - - private class SectionsPagerAdapter extends FragmentStateAdapter { - int tabCount; - boolean showFavoriteSubscribedSubreddits; - boolean showSubscribedSubreddits; - List favoriteSubscribedSubreddits; - List subscribedSubreddits; - - SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle, int tabCount, boolean showFavoriteSubscribedSubreddits, boolean showSubscribedSubreddits) { - super(fm, lifecycle); - this.tabCount = tabCount; - favoriteSubscribedSubreddits = new ArrayList<>(); - subscribedSubreddits = new ArrayList<>(); - this.showFavoriteSubscribedSubreddits = showFavoriteSubscribedSubreddits; - this.showSubscribedSubreddits = showSubscribedSubreddits; - } - - @NonNull - @Override - public Fragment createFragment(int position) { - if (mAccessToken == null) { - if (position == 0) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putString(PostFragment.EXTRA_NAME, "popular"); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } else { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putString(PostFragment.EXTRA_NAME, "all"); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } - } - - if (position == 0) { - int postType = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_HOME); - String name = mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME, ""); - return generatePostFragment(postType, name); - } else if (position == 1) { - int postType = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_POPULAR); - String name = mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME, ""); - return generatePostFragment(postType, name); - } else { - if (showFavoriteSubscribedSubreddits) { - if (position >= tabCount && position - tabCount < favoriteSubscribedSubreddits.size()) { - int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT; - String name = favoriteSubscribedSubreddits.get(position - tabCount).getName(); - return generatePostFragment(postType, name); - } - } - if (showSubscribedSubreddits) { - if (position >= tabCount && position - tabCount - favoriteSubscribedSubreddits.size() < subscribedSubreddits.size()) { - int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT; - String name = subscribedSubreddits.get(position - tabCount - favoriteSubscribedSubreddits.size()).getName(); - return generatePostFragment(postType, name); - } - } - int postType = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_ALL); - String name = mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME, ""); - return generatePostFragment(postType, name); - } - } - - public void setFavoriteSubscribedSubreddits(List favoriteSubscribedSubreddits) { - this.favoriteSubscribedSubreddits = favoriteSubscribedSubreddits; - notifyDataSetChanged(); - } - - public void setSubscribedSubreddits(List subscribedSubreddits) { - this.subscribedSubreddits = subscribedSubreddits; - notifyDataSetChanged(); - } - - private Fragment generatePostFragment(int postType, String name) { - if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_HOME) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_FRONT_PAGE); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_ALL) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putString(PostFragment.EXTRA_NAME, "all"); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putString(PostFragment.EXTRA_NAME, name); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putString(PostFragment.EXTRA_NAME, name); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_MULTI_REDDIT); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); - bundle.putString(PostFragment.EXTRA_USER_NAME, name); - bundle.putString(PostFragment.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SUBMITTED); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } else { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putString(PostFragment.EXTRA_NAME, "popular"); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } - } - - @Override - public int getItemCount() { - if (mAccessToken == null) { - return 2; - } - return tabCount + favoriteSubscribedSubreddits.size() + subscribedSubreddits.size(); - } - - @Nullable - private PostFragment getCurrentFragment() { - if (viewPager2 == null || fragmentManager == null) { - return null; - } - Fragment fragment = fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); - if (fragment instanceof PostFragment) { - return (PostFragment) fragment; - } - return null; - } - - boolean handleKeyDown(int keyCode) { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - return currentFragment.handleKeyDown(keyCode); - } - return false; - } - - boolean startLazyMode() { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - return currentFragment.startLazyMode(); - } - - return false; - } - - void stopLazyMode() { - for (int i = 0; i < getItemCount(); i++) { - Fragment fragment = fragmentManager.findFragmentByTag("f" + i); - if (fragment instanceof PostFragment && ((PostFragment) fragment).isInLazyMode()) { - ((PostFragment) fragment).stopLazyMode(); - } - } - } - - int getCurrentPostType() { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - return currentFragment.getPostType(); - } - return PostDataSource.TYPE_SUBREDDIT; - } - - void changeSortType(SortType sortType) { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - currentFragment.changeSortType(sortType); - } - displaySortTypeInToolbar(); - } - - public void refresh() { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - currentFragment.refresh(); - } - } - - void changeNSFW(boolean nsfw) { - for (int i = 0; i < getItemCount(); i++) { - Fragment fragment = fragmentManager.findFragmentByTag("f" + i); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeNSFW(nsfw); - } - } - } - - void changePostLayout(int postLayout) { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - currentFragment.changePostLayout(postLayout); - } - } - - void goBackToTop() { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - currentFragment.goBackToTop(); - } - } - - void displaySortTypeInToolbar() { - PostFragment currentFragment = getCurrentFragment(); - if (currentFragment != null) { - SortType sortType = currentFragment.getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostImageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostImageActivity.java deleted file mode 100644 index 3f0b7e52..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostImageActivity.java +++ /dev/null @@ -1,678 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.os.Environment; -import android.provider.MediaStore; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.core.content.FileProvider; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; -import com.libRG.CustomTextView; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.io.File; -import java.io.IOException; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadSubredditIconAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FlairBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SubmitImagePostEvent; -import ml.docilealligator.infinityforreddit.Event.SubmitVideoOrGifPostEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Service.SubmitPostService; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class PostImageActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { - - static final String EXTRA_SUBREDDIT_NAME = "ESN"; - - private static final String SUBREDDIT_NAME_STATE = "SNS"; - private static final String SUBREDDIT_ICON_STATE = "SIS"; - private static final String SUBREDDIT_SELECTED_STATE = "SSS"; - private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; - private static final String IMAGE_URI_STATE = "IUS"; - private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; - private static final String IS_POSTING_STATE = "IPS"; - private static final String FLAIR_STATE = "FS"; - private static final String IS_SPOILER_STATE = "ISS"; - private static final String IS_NSFW_STATE = "INS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; - private static final int PICK_IMAGE_REQUEST_CODE = 1; - private static final int CAPTURE_IMAGE_REQUEST_CODE = 2; - - @BindView(R.id.coordinator_layout_post_image_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_post_image_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_post_image_activity) - Toolbar toolbar; - @BindView(R.id.subreddit_icon_gif_image_view_post_image_activity) - GifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_post_image_activity) - TextView subredditNameTextView; - @BindView(R.id.rules_button_post_image_activity) - Button rulesButton; - @BindView(R.id.divider_1_post_image_activity) - View divider1; - @BindView(R.id.flair_custom_text_view_post_image_activity) - CustomTextView flairTextView; - @BindView(R.id.spoiler_custom_text_view_post_image_activity) - CustomTextView spoilerTextView; - @BindView(R.id.nsfw_custom_text_view_post_image_activity) - CustomTextView nsfwTextView; - @BindView(R.id.divider_2_post_image_activity) - View divider2; - @BindView(R.id.post_title_edit_text_post_image_activity) - EditText titleEditText; - @BindView(R.id.divider_3_post_image_activity) - View divider3; - @BindView(R.id.select_image_constraint_layout_post_image_activity) - ConstraintLayout constraintLayout; - @BindView(R.id.capture_fab_post_image_activity) - FloatingActionButton captureFab; - @BindView(R.id.select_from_library_fab_post_image_activity) - FloatingActionButton selectFromLibraryFab; - @BindView(R.id.select_again_text_view_post_image_activity) - TextView selectAgainTextView; - @BindView(R.id.image_view_post_image_activity) - ImageView imageView; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("upload_media") - Retrofit mUploadMediaRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String iconUrl; - private String subredditName; - private boolean subredditSelected = false; - private boolean subredditIsUser; - private boolean loadSubredditIconSuccessful = true; - private boolean isPosting; - private Uri imageUri; - private int primaryTextColor; - private int flairBackgroundColor; - private int flairTextColor; - private int spoilerBackgroundColor; - private int spoilerTextColor; - private int nsfwBackgroundColor; - private int nsfwTextColor; - private Flair flair; - private boolean isSpoiler = false; - private boolean isNSFW = false; - private Resources resources; - private Menu mMemu; - private RequestManager mGlide; - private FlairBottomSheetFragment flairSelectionBottomSheetFragment; - private Snackbar mPostingSnackbar; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_post_image); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mGlide = Glide.with(this); - - mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); - - resources = getResources(); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - - subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); - iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); - subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); - subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); - loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); - isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); - flair = savedInstanceState.getParcelable(FLAIR_STATE); - isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); - isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); - - if (savedInstanceState.getString(IMAGE_URI_STATE) != null) { - imageUri = Uri.parse(savedInstanceState.getString(IMAGE_URI_STATE)); - loadImage(); - } - - if (subredditName != null) { - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - if (!loadSubredditIconSuccessful) { - loadSubredditIcon(); - } - } - displaySubredditIcon(); - - if (isPosting) { - mPostingSnackbar.show(); - } - - if (flair != null) { - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - if (isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - } - if (isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - } - } else { - getCurrentAccount(); - - isPosting = false; - - if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { - loadSubredditIconSuccessful = false; - subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - subredditSelected = true; - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - loadSubredditIcon(); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - - imageUri = getIntent().getData(); - if (imageUri != null) { - loadImage(); - } - } - - iconGifImageView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - subredditNameTextView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - rulesButton.setOnClickListener(view -> { - if (subredditName == null) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - } else { - Intent intent = new Intent(this, RulesActivity.class); - if (subredditIsUser) { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); - } - startActivity(intent); - } - }); - - flairTextView.setOnClickListener(view -> { - if (flair == null) { - flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); - flairSelectionBottomSheetFragment.setArguments(bundle); - flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); - } else { - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - }); - - spoilerTextView.setOnClickListener(view -> { - if (!isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - isSpoiler = true; - } else { - spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - spoilerTextView.setTextColor(primaryTextColor); - isSpoiler = false; - } - }); - - nsfwTextView.setOnClickListener(view -> { - if (!isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - isNSFW = true; - } else { - nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - nsfwTextView.setTextColor(primaryTextColor); - isNSFW = false; - } - }); - - captureFab.setOnClickListener(view -> { - Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - if (pictureIntent.resolveActivity(getPackageManager()) != null) { - try { - imageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", - File.createTempFile("temp_img", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); - pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); - startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); - } catch (IOException ex) { - Snackbar.make(coordinatorLayout, R.string.error_creating_temp_file, Snackbar.LENGTH_SHORT).show(); - } - } else { - Snackbar.make(coordinatorLayout, R.string.no_camera_available, Snackbar.LENGTH_SHORT).show(); - } - }); - - selectFromLibraryFab.setOnClickListener(view -> { - Intent intent = new Intent(); - intent.setType("image/*"); - intent.setAction(Intent.ACTION_GET_CONTENT); - startActivityForResult(Intent.createChooser(intent, resources.getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); - }); - - selectAgainTextView.setOnClickListener(view -> { - imageUri = null; - selectAgainTextView.setVisibility(View.GONE); - mGlide.clear(imageView); - imageView.setVisibility(View.GONE); - constraintLayout.setVisibility(View.VISIBLE); - }); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - subredditNameTextView.setTextColor(secondaryTextColor); - rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); - flairTextColor = mCustomThemeWrapper.getFlairTextColor(); - spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); - spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); - nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); - nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); - flairTextView.setTextColor(primaryTextColor); - spoilerTextView.setTextColor(primaryTextColor); - nsfwTextView.setTextColor(primaryTextColor); - titleEditText.setTextColor(primaryTextColor); - titleEditText.setHintTextColor(secondaryTextColor); - applyFABTheme(captureFab); - applyFABTheme(selectFromLibraryFab); - selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent()); - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - }).execute(); - } - - private void loadImage() { - constraintLayout.setVisibility(View.GONE); - imageView.setVisibility(View.VISIBLE); - selectAgainTextView.setVisibility(View.VISIBLE); - mGlide.load(imageUri).into(imageView); - } - - private void displaySubredditIcon() { - if (iconUrl != null && !iconUrl.equals("")) { - 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(iconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - } - - private void loadSubredditIcon() { - new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { - iconUrl = iconImageUrl; - displaySubredditIcon(); - loadSubredditIconSuccessful = true; - }).execute(); - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.post_image_activity, menu); - applyMenuItemTheme(menu); - mMemu = menu; - if (isPosting) { - mMemu.findItem(R.id.action_send_post_image_activity).setEnabled(false); - mMemu.findItem(R.id.action_send_post_image_activity).getIcon().setAlpha(130); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("") || imageUri != null) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); - return true; - case R.id.action_send_post_image_activity: - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (imageUri == null) { - Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); - return true; - } - - isPosting = true; - - item.setEnabled(false); - item.getIcon().setAlpha(130); - - mPostingSnackbar.show(); - - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } - - Intent intent = new Intent(this, SubmitPostService.class); - intent.setData(imageUri); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - String mimeType = getContentResolver().getType(imageUri); - if (mimeType != null && mimeType.contains("gif")) { - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); - } else { - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_IMAGE); - } - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(intent); - } else { - startService(intent); - } - - return true; - } - - return false; - } - - @Override - public void onBackPressed() { - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - } else { - if (!titleEditText.getText().toString().equals("") || imageUri != null) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } else { - finish(); - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(SUBREDDIT_NAME_STATE, subredditName); - outState.putString(SUBREDDIT_ICON_STATE, iconUrl); - outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); - outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); - if (imageUri != null) { - outState.putString(IMAGE_URI_STATE, imageUri.toString()); - } - outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); - outState.putBoolean(IS_POSTING_STATE, isPosting); - outState.putParcelable(FLAIR_STATE, flair); - outState.putBoolean(IS_SPOILER_STATE, isSpoiler); - outState.putBoolean(IS_NSFW_STATE, isNSFW); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); - iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); - subredditSelected = true; - subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); - - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - displaySubredditIcon(); - - flairTextView.setVisibility(View.VISIBLE); - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - } else if (requestCode == PICK_IMAGE_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - if (data == null) { - Snackbar.make(coordinatorLayout, R.string.error_getting_image, Snackbar.LENGTH_SHORT).show(); - return; - } - - imageUri = data.getData(); - loadImage(); - } - } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - loadImage(); - } - } - } - - @Override - protected void onDestroy() { - EventBus.getDefault().unregister(this); - super.onDestroy(); - } - - @Override - public void flairSelected(Flair flair) { - this.flair = flair; - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Subscribe - public void onSubmitImagePostEvent(SubmitImagePostEvent submitImagePostEvent) { - isPosting = false; - mPostingSnackbar.dismiss(); - if (submitImagePostEvent.postSuccess) { - Intent intent = new Intent(PostImageActivity.this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); - startActivity(intent); - finish(); - } else { - mMemu.findItem(R.id.action_send_post_image_activity).setEnabled(true); - mMemu.findItem(R.id.action_send_post_image_activity).getIcon().setAlpha(255); - if (submitImagePostEvent.errorMessage == null || submitImagePostEvent.errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, submitImagePostEvent.errorMessage.substring(0, 1).toUpperCase() - + submitImagePostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); - } - } - } - - @Subscribe - public void onSubmitVideoOrGifPostEvent(SubmitVideoOrGifPostEvent submitVideoOrGifPostEvent) { - isPosting = false; - mPostingSnackbar.dismiss(); - mMemu.findItem(R.id.action_send_post_image_activity).setEnabled(true); - mMemu.findItem(R.id.action_send_post_image_activity).getIcon().setAlpha(255); - - if (submitVideoOrGifPostEvent.postSuccess) { - Intent intent = new Intent(this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, - mAccountName); - startActivity(intent); - finish(); - } else if (submitVideoOrGifPostEvent.errorProcessingVideoOrGif) { - Snackbar.make(coordinatorLayout, R.string.error_processing_image, Snackbar.LENGTH_SHORT).show(); - } else { - if (submitVideoOrGifPostEvent.errorMessage == null || submitVideoOrGifPostEvent.errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, submitVideoOrGifPostEvent.errorMessage.substring(0, 1).toUpperCase() - + submitVideoOrGifPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostLinkActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostLinkActivity.java deleted file mode 100644 index 46f0df8c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostLinkActivity.java +++ /dev/null @@ -1,552 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.libRG.CustomTextView; - -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 jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadSubredditIconAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FlairBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SubmitTextOrLinkPostEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Service.SubmitPostService; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { - - static final String EXTRA_SUBREDDIT_NAME = "ESN"; - static final String EXTRA_LINK = "EL"; - - private static final String SUBREDDIT_NAME_STATE = "SNS"; - private static final String SUBREDDIT_ICON_STATE = "SIS"; - private static final String SUBREDDIT_SELECTED_STATE = "SSS"; - private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; - private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; - private static final String IS_POSTING_STATE = "IPS"; - private static final String FLAIR_STATE = "FS"; - private static final String IS_SPOILER_STATE = "ISS"; - private static final String IS_NSFW_STATE = "INS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; - - @BindView(R.id.coordinator_layout_post_link_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_post_link_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_post_link_activity) - Toolbar toolbar; - @BindView(R.id.subreddit_icon_gif_image_view_post_link_activity) - GifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_post_link_activity) - TextView subredditNameTextView; - @BindView(R.id.rules_button_post_link_activity) - Button rulesButton; - @BindView(R.id.divider_1_post_link_activity) - View divider1; - @BindView(R.id.divider_2_post_link_activity) - View divider2; - @BindView(R.id.divider_3_post_link_activity) - View divider3; - @BindView(R.id.flair_custom_text_view_post_link_activity) - CustomTextView flairTextView; - @BindView(R.id.spoiler_custom_text_view_post_link_activity) - CustomTextView spoilerTextView; - @BindView(R.id.nsfw_custom_text_view_post_link_activity) - CustomTextView nsfwTextView; - @BindView(R.id.post_title_edit_text_post_link_activity) - EditText titleEditText; - @BindView(R.id.post_link_edit_text_post_link_activity) - EditText linkEditText; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String iconUrl; - private String subredditName; - private boolean subredditSelected = false; - private boolean subredditIsUser; - private boolean loadSubredditIconSuccessful = true; - private boolean isPosting; - private int primaryTextColor; - private int flairBackgroundColor; - private int flairTextColor; - private int spoilerBackgroundColor; - private int spoilerTextColor; - private int nsfwBackgroundColor; - private int nsfwTextColor; - private Flair flair; - private boolean isSpoiler = false; - private boolean isNSFW = false; - private Resources resources; - private Menu mMemu; - private RequestManager mGlide; - private FlairBottomSheetFragment flairSelectionBottomSheetFragment; - private Snackbar mPostingSnackbar; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_post_link); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mGlide = Glide.with(this); - - mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); - - resources = getResources(); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - - subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); - iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); - subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); - subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); - loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); - isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); - flair = savedInstanceState.getParcelable(FLAIR_STATE); - isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); - isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); - - if (subredditName != null) { - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - if (!loadSubredditIconSuccessful) { - loadSubredditIcon(); - } - } - displaySubredditIcon(); - - if (isPosting) { - mPostingSnackbar.show(); - } - - if (flair != null) { - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - if (isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - } - if (isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - } - } else { - getCurrentAccount(); - - isPosting = false; - - if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { - loadSubredditIconSuccessful = false; - subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - subredditSelected = true; - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - loadSubredditIcon(); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - - String link = getIntent().getStringExtra(EXTRA_LINK); - if (link != null) { - linkEditText.setText(link); - } - } - - iconGifImageView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - subredditNameTextView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - rulesButton.setOnClickListener(view -> { - if (subredditName == null) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - } else { - Intent intent = new Intent(this, RulesActivity.class); - if (subredditIsUser) { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); - } - startActivity(intent); - } - }); - - flairTextView.setOnClickListener(view -> { - if (flair == null) { - flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); - flairSelectionBottomSheetFragment.setArguments(bundle); - flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); - } else { - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - }); - - spoilerTextView.setOnClickListener(view -> { - if (!isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - isSpoiler = true; - } else { - spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - spoilerTextView.setTextColor(primaryTextColor); - isSpoiler = false; - } - }); - - nsfwTextView.setOnClickListener(view -> { - if (!isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - isNSFW = true; - } else { - nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - nsfwTextView.setTextColor(primaryTextColor); - isNSFW = false; - } - }); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - subredditNameTextView.setTextColor(secondaryTextColor); - rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); - flairTextColor = mCustomThemeWrapper.getFlairTextColor(); - spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); - spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); - nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); - nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); - flairTextView.setTextColor(primaryTextColor); - spoilerTextView.setTextColor(primaryTextColor); - nsfwTextView.setTextColor(primaryTextColor); - titleEditText.setTextColor(primaryTextColor); - titleEditText.setHintTextColor(secondaryTextColor); - linkEditText.setTextColor(primaryTextColor); - linkEditText.setHintTextColor(secondaryTextColor); - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - }).execute(); - } - - private void displaySubredditIcon() { - if (iconUrl != null && !iconUrl.equals("")) { - 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(iconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - } - - private void loadSubredditIcon() { - new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { - iconUrl = iconImageUrl; - displaySubredditIcon(); - loadSubredditIconSuccessful = true; - }).execute(); - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.post_link_activity, menu); - applyMenuItemTheme(menu); - mMemu = menu; - if (isPosting) { - mMemu.findItem(R.id.action_send_post_link_activity).setEnabled(false); - mMemu.findItem(R.id.action_send_post_link_activity).getIcon().setAlpha(130); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("") || !linkEditText.getText().toString().equals("")) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); - return true; - case R.id.action_send_post_link_activity: - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (linkEditText.getText() == null || linkEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.link_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - isPosting = true; - - item.setEnabled(false); - item.getIcon().setAlpha(130); - - mPostingSnackbar.show(); - - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } - - Intent intent = new Intent(this, SubmitPostService.class); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_CONTENT, linkEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_LINK); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TEXT_OR_LINK); - startService(intent); - - return true; - } - - return false; - } - - @Override - public void onBackPressed() { - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - } else { - if (!titleEditText.getText().toString().equals("") || !linkEditText.getText().toString().equals("")) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } else { - finish(); - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(SUBREDDIT_NAME_STATE, subredditName); - outState.putString(SUBREDDIT_ICON_STATE, iconUrl); - outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); - outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); - outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); - outState.putBoolean(IS_POSTING_STATE, isPosting); - outState.putParcelable(FLAIR_STATE, flair); - outState.putBoolean(IS_SPOILER_STATE, isSpoiler); - outState.putBoolean(IS_NSFW_STATE, isNSFW); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); - iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); - subredditSelected = true; - subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); - - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - displaySubredditIcon(); - - flairTextView.setVisibility(View.VISIBLE); - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - } - } - - @Override - protected void onDestroy() { - EventBus.getDefault().unregister(this); - super.onDestroy(); - } - - @Override - public void flairSelected(Flair flair) { - this.flair = flair; - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Subscribe - public void onSubmitLinkPostEvent(SubmitTextOrLinkPostEvent submitTextOrLinkPostEvent) { - isPosting = false; - mPostingSnackbar.dismiss(); - if (submitTextOrLinkPostEvent.postSuccess) { - Intent intent = new Intent(PostLinkActivity.this, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, submitTextOrLinkPostEvent.post); - startActivity(intent); - finish(); - } else { - mMemu.findItem(R.id.action_send_post_link_activity).setEnabled(true); - mMemu.findItem(R.id.action_send_post_link_activity).getIcon().setAlpha(255); - if (submitTextOrLinkPostEvent.errorMessage == null || submitTextOrLinkPostEvent.errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, submitTextOrLinkPostEvent.errorMessage.substring(0, 1).toUpperCase() - + submitTextOrLinkPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostTextActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostTextActivity.java deleted file mode 100644 index 1ebdab2c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostTextActivity.java +++ /dev/null @@ -1,569 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.libRG.CustomTextView; - -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 jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.Adapter.MarkdownBottomBarRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadSubredditIconAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FlairBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SubmitTextOrLinkPostEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Service.SubmitPostService; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class PostTextActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { - - static final String EXTRA_SUBREDDIT_NAME = "ESN"; - static final String EXTRA_CONTENT = "EC"; - - private static final String SUBREDDIT_NAME_STATE = "SNS"; - private static final String SUBREDDIT_ICON_STATE = "SIS"; - private static final String SUBREDDIT_SELECTED_STATE = "SSS"; - private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; - private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; - private static final String IS_POSTING_STATE = "IPS"; - private static final String FLAIR_STATE = "FS"; - private static final String IS_SPOILER_STATE = "ISS"; - private static final String IS_NSFW_STATE = "INS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; - - @BindView(R.id.coordinator_layout_post_text_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_post_text_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_post_text_activity) - Toolbar toolbar; - @BindView(R.id.subreddit_icon_gif_image_view_search_activity) - GifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_search_activity) - TextView subredditNameTextView; - @BindView(R.id.rules_button_post_text_activity) - Button rulesButton; - @BindView(R.id.divider_1_post_text_activity) - View divider1; - @BindView(R.id.flair_custom_text_view_post_text_activity) - CustomTextView flairTextView; - @BindView(R.id.spoiler_custom_text_view_post_text_activity) - CustomTextView spoilerTextView; - @BindView(R.id.nsfw_custom_text_view_post_text_activity) - CustomTextView nsfwTextView; - @BindView(R.id.divider_2_post_text_activity) - View divider2; - @BindView(R.id.post_title_edit_text_post_text_activity) - EditText titleEditText; - @BindView(R.id.divider_3_post_text_activity) - View divider3; - @BindView(R.id.post_text_content_edit_text_post_text_activity) - EditText contentEditText; - @BindView(R.id.markdown_bottom_bar_recycler_view_post_text_activity) - RecyclerView markdownBottomBarRecyclerView; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String iconUrl; - private String subredditName; - private boolean subredditSelected = false; - private boolean subredditIsUser; - private boolean loadSubredditIconSuccessful = true; - private boolean isPosting; - private int primaryTextColor; - private int flairBackgroundColor; - private int flairTextColor; - private int spoilerBackgroundColor; - private int spoilerTextColor; - private int nsfwBackgroundColor; - private int nsfwTextColor; - private Flair flair; - private boolean isSpoiler = false; - private boolean isNSFW = false; - private Resources resources; - private Menu mMenu; - private RequestManager mGlide; - private FlairBottomSheetFragment flairSelectionBottomSheetFragment; - private Snackbar mPostingSnackbar; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_post_text); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mGlide = Glide.with(this); - - mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); - - resources = getResources(); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - - subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); - iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); - subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); - subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); - loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); - isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); - flair = savedInstanceState.getParcelable(FLAIR_STATE); - isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); - isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); - - if (subredditName != null) { - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - if (!loadSubredditIconSuccessful) { - loadSubredditIcon(); - } - } - displaySubredditIcon(); - - if (isPosting) { - mPostingSnackbar.show(); - } - - if (flair != null) { - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - if (isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - } - if (isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - } - } else { - getCurrentAccount(); - - isPosting = false; - - if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { - loadSubredditIconSuccessful = false; - subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - subredditSelected = true; - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - loadSubredditIcon(); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - - String text = getIntent().getStringExtra(EXTRA_CONTENT); - if (text != null) { - contentEditText.setText(text); - } - } - - iconGifImageView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - subredditNameTextView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - rulesButton.setOnClickListener(view -> { - if (subredditName == null) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - } else { - Intent intent = new Intent(this, RulesActivity.class); - if (subredditIsUser) { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); - } - startActivity(intent); - } - }); - - flairTextView.setOnClickListener(view -> { - if (flair == null) { - flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - if (subredditIsUser) { - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); - } - flairSelectionBottomSheetFragment.setArguments(bundle); - flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); - } else { - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - }); - - spoilerTextView.setOnClickListener(view -> { - if (!isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - isSpoiler = true; - } else { - spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - spoilerTextView.setTextColor(primaryTextColor); - isSpoiler = false; - } - }); - - nsfwTextView.setOnClickListener(view -> { - if (!isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - isNSFW = true; - } else { - nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - nsfwTextView.setTextColor(primaryTextColor); - isNSFW = false; - } - }); - - MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { - MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); - }); - - markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, - LinearLayoutManager.HORIZONTAL, false)); - markdownBottomBarRecyclerView.setAdapter(adapter); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - subredditNameTextView.setTextColor(secondaryTextColor); - rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); - flairTextColor = mCustomThemeWrapper.getFlairTextColor(); - spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); - spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); - nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); - nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); - flairTextView.setTextColor(primaryTextColor); - spoilerTextView.setTextColor(primaryTextColor); - nsfwTextView.setTextColor(primaryTextColor); - titleEditText.setTextColor(primaryTextColor); - titleEditText.setHintTextColor(secondaryTextColor); - contentEditText.setTextColor(primaryTextColor); - contentEditText.setHintTextColor(secondaryTextColor); - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - }).execute(); - } - - private void displaySubredditIcon() { - if (iconUrl != null && !iconUrl.equals("")) { - 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(iconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - } - - private void loadSubredditIcon() { - new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { - iconUrl = iconImageUrl; - displaySubredditIcon(); - loadSubredditIconSuccessful = true; - }).execute(); - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.post_text_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - if (isPosting) { - mMenu.findItem(R.id.action_send_post_text_activity).setEnabled(false); - mMenu.findItem(R.id.action_send_post_text_activity).getIcon().setAlpha(130); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - int itemId = item.getItemId(); - if (itemId == android.R.id.home) { - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("") || !contentEditText.getText().toString().equals("")) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); - return true; - } else if (itemId == R.id.action_preview_post_text_activity) { - Intent intent = new Intent(this, FullMarkdownActivity.class); - intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); - startActivity(intent); - } else if (itemId == R.id.action_send_post_text_activity) { - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - isPosting = true; - - item.setEnabled(false); - item.getIcon().setAlpha(130); - - mPostingSnackbar.show(); - - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } - - Intent intent = new Intent(this, SubmitPostService.class); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_CONTENT, contentEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_SELF); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TEXT_OR_LINK); - startService(intent); - - return true; - } - - return false; - } - - @Override - public void onBackPressed() { - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - } else { - if (!titleEditText.getText().toString().equals("") || !contentEditText.getText().toString().equals("")) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } else { - finish(); - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(SUBREDDIT_NAME_STATE, subredditName); - outState.putString(SUBREDDIT_ICON_STATE, iconUrl); - outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); - outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); - outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); - outState.putBoolean(IS_POSTING_STATE, isPosting); - outState.putParcelable(FLAIR_STATE, flair); - outState.putBoolean(IS_SPOILER_STATE, isSpoiler); - outState.putBoolean(IS_NSFW_STATE, isNSFW); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); - iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); - subredditSelected = true; - subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); - - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - displaySubredditIcon(); - - flairTextView.setVisibility(View.VISIBLE); - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - } - } - - @Override - protected void onDestroy() { - EventBus.getDefault().unregister(this); - super.onDestroy(); - } - - @Override - public void flairSelected(Flair flair) { - this.flair = flair; - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Subscribe - public void onSubmitTextPostEvent(SubmitTextOrLinkPostEvent submitTextOrLinkPostEvent) { - isPosting = false; - mPostingSnackbar.dismiss(); - if (submitTextOrLinkPostEvent.postSuccess) { - Intent intent = new Intent(PostTextActivity.this, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, submitTextOrLinkPostEvent.post); - startActivity(intent); - finish(); - } else { - mMenu.findItem(R.id.action_send_post_text_activity).setEnabled(true); - mMenu.findItem(R.id.action_send_post_text_activity).getIcon().setAlpha(255); - if (submitTextOrLinkPostEvent.errorMessage == null || submitTextOrLinkPostEvent.errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, submitTextOrLinkPostEvent.errorMessage.substring(0, 1).toUpperCase() - + submitTextOrLinkPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostVideoActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostVideoActivity.java deleted file mode 100644 index 38e49c10..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/PostVideoActivity.java +++ /dev/null @@ -1,679 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.provider.MediaStore; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; -import com.google.android.exoplayer2.ExoPlayerFactory; -import com.google.android.exoplayer2.Player; -import com.google.android.exoplayer2.SimpleExoPlayer; -import com.google.android.exoplayer2.source.ExtractorMediaSource; -import com.google.android.exoplayer2.ui.PlayerView; -import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; -import com.google.android.exoplayer2.util.Util; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; -import com.libRG.CustomTextView; - -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 jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadSubredditIconAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FlairBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SubmitVideoOrGifPostEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Service.SubmitPostService; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class PostVideoActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { - - static final String EXTRA_SUBREDDIT_NAME = "ESN"; - - private static final String SUBREDDIT_NAME_STATE = "SNS"; - private static final String SUBREDDIT_ICON_STATE = "SIS"; - private static final String SUBREDDIT_SELECTED_STATE = "SSS"; - private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; - private static final String VIDEO_URI_STATE = "IUS"; - private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; - private static final String IS_POSTING_STATE = "IPS"; - private static final String FLAIR_STATE = "FS"; - private static final String IS_SPOILER_STATE = "ISS"; - private static final String IS_NSFW_STATE = "INS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; - private static final int PICK_VIDEO_REQUEST_CODE = 1; - private static final int CAPTURE_VIDEO_REQUEST_CODE = 2; - - @BindView(R.id.coordinator_layout_post_video_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_post_video_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_post_video_activity) - Toolbar toolbar; - @BindView(R.id.subreddit_icon_gif_image_view_post_video_activity) - GifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_post_video_activity) - TextView subredditNameTextView; - @BindView(R.id.rules_button_post_video_activity) - Button rulesButton; - @BindView(R.id.divider_1_post_video_activity) - View divider1; - @BindView(R.id.flair_custom_text_view_post_video_activity) - CustomTextView flairTextView; - @BindView(R.id.spoiler_custom_text_view_post_video_activity) - CustomTextView spoilerTextView; - @BindView(R.id.nsfw_custom_text_view_post_video_activity) - CustomTextView nsfwTextView; - @BindView(R.id.divider_2_post_video_activity) - View divider2; - @BindView(R.id.post_title_edit_text_post_video_activity) - EditText titleEditText; - @BindView(R.id.divider_3_post_video_activity) - View divider3; - @BindView(R.id.select_video_constraint_layout_post_video_activity) - ConstraintLayout constraintLayout; - @BindView(R.id.capture_fab_post_video_activity) - FloatingActionButton captureFab; - @BindView(R.id.select_from_library_fab_post_video_activity) - FloatingActionButton selectFromLibraryFab; - @BindView(R.id.select_again_text_view_post_video_activity) - TextView selectAgainTextView; - @BindView(R.id.player_view_post_video_activity) - PlayerView videoPlayerView; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("upload_media") - Retrofit mUploadMediaRetrofit; - @Inject - @Named("upload_video") - Retrofit mUploadVideoRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String iconUrl; - private String subredditName; - private boolean subredditSelected = false; - private boolean subredditIsUser; - private Uri videoUri; - private boolean loadSubredditIconSuccessful = true; - private boolean isPosting; - private boolean wasPlaying; - private int primaryTextColor; - private int flairBackgroundColor; - private int flairTextColor; - private int spoilerBackgroundColor; - private int spoilerTextColor; - private int nsfwBackgroundColor; - private int nsfwTextColor; - private Flair flair; - private boolean isSpoiler = false; - private boolean isNSFW = false; - private Resources resources; - private Menu mMemu; - private RequestManager mGlide; - private FlairBottomSheetFragment mFlairSelectionBottomSheetFragment; - private Snackbar mPostingSnackbar; - private DataSource.Factory dataSourceFactory; - private SimpleExoPlayer player; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_post_video); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mGlide = Glide.with(this); - - player = ExoPlayerFactory.newSimpleInstance(this); - videoPlayerView.setPlayer(player); - dataSourceFactory = new DefaultDataSourceFactory(this, - Util.getUserAgent(this, "Infinity")); - player.setRepeatMode(Player.REPEAT_MODE_ALL); - - mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); - - resources = getResources(); - - if (savedInstanceState != null) { - subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); - iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); - subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); - subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); - loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); - isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); - flair = savedInstanceState.getParcelable(FLAIR_STATE); - isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); - isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - - if (savedInstanceState.getString(VIDEO_URI_STATE) != null) { - videoUri = Uri.parse(savedInstanceState.getString(VIDEO_URI_STATE)); - loadVideo(); - } - - if (subredditName != null) { - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - if (!loadSubredditIconSuccessful) { - loadSubredditIcon(); - } - } - displaySubredditIcon(); - - if (isPosting) { - mPostingSnackbar.show(); - } - - if (flair != null) { - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - if (isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - } - if (isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - } - } else { - getCurrentAccount(); - - isPosting = false; - - if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { - loadSubredditIconSuccessful = false; - subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - subredditSelected = true; - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - loadSubredditIcon(); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - - videoUri = getIntent().getData(); - if (videoUri != null) { - loadVideo(); - } - } - - iconGifImageView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - subredditNameTextView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - rulesButton.setOnClickListener(view -> { - if (subredditName == null) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - } else { - Intent intent = new Intent(this, RulesActivity.class); - if (subredditIsUser) { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); - } - startActivity(intent); - } - }); - - flairTextView.setOnClickListener(view -> { - if (flair == null) { - mFlairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); - mFlairSelectionBottomSheetFragment.setArguments(bundle); - mFlairSelectionBottomSheetFragment.show(getSupportFragmentManager(), mFlairSelectionBottomSheetFragment.getTag()); - } else { - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - }); - - spoilerTextView.setOnClickListener(view -> { - if (!isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - isSpoiler = true; - } else { - spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - spoilerTextView.setTextColor(primaryTextColor); - isSpoiler = false; - } - }); - - nsfwTextView.setOnClickListener(view -> { - if (!isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - isNSFW = true; - } else { - nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - nsfwTextView.setTextColor(primaryTextColor); - isNSFW = false; - } - }); - - captureFab.setOnClickListener(view -> { - Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); - if (takeVideoIntent.resolveActivity(getPackageManager()) != null) { - startActivityForResult(takeVideoIntent, CAPTURE_VIDEO_REQUEST_CODE); - } - }); - - selectFromLibraryFab.setOnClickListener(view -> { - Intent intent = new Intent(); - intent.setType("video/*"); - intent.setAction(Intent.ACTION_GET_CONTENT); - startActivityForResult(Intent.createChooser(intent, resources.getString(R.string.select_from_gallery)), PICK_VIDEO_REQUEST_CODE); - }); - - selectAgainTextView.setOnClickListener(view -> { - wasPlaying = false; - player.setPlayWhenReady(false); - videoUri = null; - videoPlayerView.setVisibility(View.GONE); - selectAgainTextView.setVisibility(View.GONE); - constraintLayout.setVisibility(View.VISIBLE); - }); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - subredditNameTextView.setTextColor(secondaryTextColor); - rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); - flairTextColor = mCustomThemeWrapper.getFlairTextColor(); - spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); - spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); - nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); - nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); - flairTextView.setTextColor(primaryTextColor); - spoilerTextView.setTextColor(primaryTextColor); - nsfwTextView.setTextColor(primaryTextColor); - titleEditText.setTextColor(primaryTextColor); - titleEditText.setHintTextColor(secondaryTextColor); - applyFABTheme(captureFab); - applyFABTheme(selectFromLibraryFab); - selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent()); - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - }).execute(); - } - - private void loadVideo() { - constraintLayout.setVisibility(View.GONE); - selectAgainTextView.setVisibility(View.VISIBLE); - videoPlayerView.setVisibility(View.VISIBLE); - player.prepare(new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(videoUri)); - player.setPlayWhenReady(true); - wasPlaying = true; - } - - private void displaySubredditIcon() { - if (iconUrl != null && !iconUrl.equals("")) { - 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(iconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - } - - private void loadSubredditIcon() { - new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { - iconUrl = iconImageUrl; - displaySubredditIcon(); - loadSubredditIconSuccessful = true; - }).execute(); - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.post_video_activity, menu); - applyMenuItemTheme(menu); - mMemu = menu; - if (isPosting) { - mMemu.findItem(R.id.action_send_post_video_activity).setEnabled(false); - mMemu.findItem(R.id.action_send_post_video_activity).getIcon().setAlpha(130); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("") || videoUri != null) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); - return true; - case R.id.action_send_post_video_activity: - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (videoUri == null) { - Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); - return true; - } - - isPosting = true; - - item.setEnabled(false); - item.getIcon().setAlpha(130); - - mPostingSnackbar.show(); - - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } - - Intent intent = new Intent(this, SubmitPostService.class); - intent.setData(videoUri); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(intent); - } else { - startService(intent); - } - - return true; - } - - return false; - } - - @Override - public void onBackPressed() { - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - } else { - if (!titleEditText.getText().toString().equals("") || videoUri != null) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } else { - finish(); - } - } - } - - @Override - protected void onStart() { - super.onStart(); - if (wasPlaying) { - player.setPlayWhenReady(true); - } - } - - @Override - protected void onStop() { - super.onStop(); - player.setPlayWhenReady(false); - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(SUBREDDIT_NAME_STATE, subredditName); - outState.putString(SUBREDDIT_ICON_STATE, iconUrl); - outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); - outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); - if (videoUri != null) { - outState.putString(VIDEO_URI_STATE, videoUri.toString()); - } - outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); - outState.putBoolean(IS_POSTING_STATE, isPosting); - outState.putParcelable(FLAIR_STATE, flair); - outState.putBoolean(IS_SPOILER_STATE, isSpoiler); - outState.putBoolean(IS_NSFW_STATE, isNSFW); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - if (data != null) { - subredditName = data.getStringExtra(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); - iconUrl = data.getStringExtra(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); - subredditSelected = true; - subredditIsUser = data.getBooleanExtra(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER, false); - - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - displaySubredditIcon(); - - flairTextView.setVisibility(View.VISIBLE); - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - } - } else if (requestCode == PICK_VIDEO_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - if (data == null) { - Snackbar.make(coordinatorLayout, R.string.error_getting_video, Snackbar.LENGTH_SHORT).show(); - return; - } - - videoUri = data.getData(); - loadVideo(); - } - } else if (requestCode == CAPTURE_VIDEO_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - if (data != null && data.getData() != null) { - videoUri = data.getData(); - loadVideo(); - } else { - Snackbar.make(coordinatorLayout, R.string.error_getting_video, Snackbar.LENGTH_SHORT).show(); - } - } - } - } - - @Override - protected void onDestroy() { - EventBus.getDefault().unregister(this); - super.onDestroy(); - player.release(); - } - - @Override - public void flairSelected(Flair flair) { - this.flair = flair; - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Subscribe - public void onSubmitVideoPostEvent(SubmitVideoOrGifPostEvent submitVideoOrGifPostEvent) { - isPosting = false; - mPostingSnackbar.dismiss(); - mMemu.findItem(R.id.action_send_post_video_activity).setEnabled(true); - mMemu.findItem(R.id.action_send_post_video_activity).getIcon().setAlpha(255); - - if (submitVideoOrGifPostEvent.postSuccess) { - Intent intent = new Intent(this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, - mAccountName); - startActivity(intent); - finish(); - } else if (submitVideoOrGifPostEvent.errorProcessingVideoOrGif) { - Snackbar.make(coordinatorLayout, R.string.error_processing_video, Snackbar.LENGTH_SHORT).show(); - } else { - if (submitVideoOrGifPostEvent.errorMessage == null || submitVideoOrGifPostEvent.errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, submitVideoOrGifPostEvent.errorMessage.substring(0, 1).toUpperCase() - + submitVideoOrGifPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java deleted file mode 100644 index bc70c30d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ReportActivity.java +++ /dev/null @@ -1,219 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.snackbar.Snackbar; -import com.r0adkll.slidr.Slidr; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.ReportReasonRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FetchRules; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.ReportReason; -import ml.docilealligator.infinityforreddit.ReportThing; -import ml.docilealligator.infinityforreddit.Rule; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class ReportActivity extends BaseActivity { - - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - public static final String EXTRA_THING_FULLNAME = "ETF"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String GENERAL_REASONS_STATE = "GRS"; - private static final String RULES_REASON_STATE = "RRS"; - - @BindView(R.id.coordinator_layout_report_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_report_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_report_activity) - Toolbar toolbar; - @BindView(R.id.recycler_view_report_activity) - RecyclerView recyclerView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mFullname; - private String mSubredditName; - private ArrayList generalReasons; - private ArrayList rulesReasons; - private ReportReasonRecyclerViewAdapter mAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_report); - - ButterKnife.bind(this); - - 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); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mFullname = getIntent().getStringExtra(EXTRA_THING_FULLNAME); - mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - - generalReasons = savedInstanceState.getParcelableArrayList(GENERAL_REASONS_STATE); - rulesReasons = savedInstanceState.getParcelableArrayList(RULES_REASON_STATE); - } else { - getCurrentAccount(); - } - - if (generalReasons != null) { - mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, generalReasons); - } else { - mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, ReportReason.getGeneralReasons(this)); - } - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - recyclerView.setAdapter(mAdapter); - - if (rulesReasons == null) { - FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { - @Override - public void success(ArrayList rules) { - mAdapter.setRules(ReportReason.convertRulesToReasons(rules)); - } - - @Override - public void failed() { - Snackbar.make(coordinatorLayout, R.string.error_loading_rules_without_retry, Snackbar.LENGTH_SHORT).show(); - } - }); - } else { - mAdapter.setRules(rulesReasons); - } - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - }).execute(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.report_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_send_report_activity: - ReportReason reportReason = mAdapter.getSelectedReason(); - if (reportReason != null) { - Toast.makeText(ReportActivity.this, R.string.reporting, Toast.LENGTH_SHORT).show(); - ReportThing.reportThing(mOauthRetrofit, mAccessToken, mFullname, mSubredditName, - reportReason.getReasonType(), reportReason.getReportReason(), new ReportThing.ReportThingListener() { - @Override - public void success() { - Toast.makeText(ReportActivity.this, R.string.report_successful, Toast.LENGTH_SHORT).show(); - finish(); - } - - @Override - public void failed() { - Toast.makeText(ReportActivity.this, R.string.report_failed, Toast.LENGTH_SHORT).show(); - } - }); - } else { - Toast.makeText(ReportActivity.this, R.string.report_reason_not_selected, Toast.LENGTH_SHORT).show(); - } - return true; - } - - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - if (mAdapter != null) { - outState.putParcelableArrayList(GENERAL_REASONS_STATE, mAdapter.getGeneralReasons()); - outState.putParcelableArrayList(RULES_REASON_STATE, mAdapter.getRules()); - } - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java deleted file mode 100644 index 8e030da8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/RulesActivity.java +++ /dev/null @@ -1,295 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.widget.ProgressBar; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.RulesRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.FetchRules; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Rule; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class RulesActivity extends BaseActivity { - - static final String EXTRA_SUBREDDIT_NAME = "ESN"; - - @BindView(R.id.coordinator_layout_rules_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_rules_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_rules_activity) - Toolbar toolbar; - @BindView(R.id.progress_bar_rules_activity) - ProgressBar progressBar; - @BindView(R.id.recycler_view_rules_activity) - RecyclerView recyclerView; - @BindView(R.id.error_text_view_rules_activity) - TextView errorTextView; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String mSubredditName; - private RulesRecyclerViewAdapter mAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_rules); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - - int navBarHeight = getNavBarHeight(); - if (navBarHeight > 0) { - recyclerView.setPadding(0, 0, 0, navBarHeight); - } - } - } - - appBarLayout.setBackgroundColor(mCustomThemeWrapper.getColorPrimary()); - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mSubredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME); - - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper); - recyclerView.setAdapter(mAdapter); - - //fetchRules(); - - FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { - @Override - public void success(ArrayList rules) { - progressBar.setVisibility(View.GONE); - if (rules == null || rules.size() == 0) { - errorTextView.setVisibility(View.VISIBLE); - errorTextView.setText(R.string.no_rule); - errorTextView.setOnClickListener(view -> { - }); - } - mAdapter.changeDataset(rules); - } - - @Override - public void failed() { - displayError(); - } - }); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorAccent())); - errorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); - } - - /*private void fetchRules() { - progressBar.setVisibility(View.VISIBLE); - errorTextView.setVisibility(View.GONE); - - RedditAPI api = mRetrofit.create(RedditAPI.class); - Call rulesCall = api.getRules(mSubredditName); - rulesCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseRulesAsyncTask(response.body(), new ParseRulesAsyncTask.ParseRulesAsyncTaskListener() { - @Override - public void parseSuccessful(ArrayList rules) { - progressBar.setVisibility(View.GONE); - if (rules == null || rules.size() == 0) { - errorTextView.setVisibility(View.VISIBLE); - errorTextView.setText(R.string.no_rule); - errorTextView.setOnClickListener(view -> { - }); - } - mAdapter.changeDataset(rules); - } - - @Override - public void parseFailed() { - displayError(); - } - }).execute(); - } else { - displayError(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - displayError(); - } - }); - }*/ - - private void displayError() { - progressBar.setVisibility(View.GONE); - errorTextView.setVisibility(View.VISIBLE); - errorTextView.setText(R.string.error_loading_rules); - errorTextView.setOnClickListener(view -> { - progressBar.setVisibility(View.VISIBLE); - errorTextView.setVisibility(View.GONE); - FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { - @Override - public void success(ArrayList rules) { - progressBar.setVisibility(View.GONE); - if (rules == null || rules.size() == 0) { - errorTextView.setVisibility(View.VISIBLE); - errorTextView.setText(R.string.no_rule); - errorTextView.setOnClickListener(view -> { - }); - } - mAdapter.changeDataset(rules); - } - - @Override - public void failed() { - displayError(); - } - }); - }); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - /*private static class ParseRulesAsyncTask extends AsyncTask, ArrayList> { - private String response; - private ParseRulesAsyncTaskListener parseRulesAsyncTaskListener; - - ParseRulesAsyncTask(String response, ParseRulesAsyncTaskListener parseRulesAsyncTaskListener) { - this.response = response; - this.parseRulesAsyncTaskListener = parseRulesAsyncTaskListener; - } - - @Override - protected ArrayList doInBackground(Void... voids) { - try { - JSONArray rulesArray = new JSONObject(response).getJSONArray(JSONUtils.RULES_KEY); - ArrayList rules = new ArrayList<>(); - for (int i = 0; i < rulesArray.length(); i++) { - String shortName = rulesArray.getJSONObject(i).getString(JSONUtils.SHORT_NAME_KEY); - String description = null; - if (rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_KEY)) { - description = Utils.modifyMarkdown(rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_KEY)); - } - rules.add(new Rule(shortName, description)); - } - return rules; - } catch (JSONException e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(ArrayList rules) { - if (rules != null) { - parseRulesAsyncTaskListener.parseSuccessful(rules); - } else { - parseRulesAsyncTaskListener.parseFailed(); - } - } - - interface ParseRulesAsyncTaskListener { - void parseSuccessful(ArrayList rules); - - void parseFailed(); - } - }*/ -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchActivity.java deleted file mode 100644 index 69c637e9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchActivity.java +++ /dev/null @@ -1,391 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.drawable.ColorDrawable; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.RelativeLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.ferfalk.simplesearchview.SimpleSearchView; -import com.google.android.material.appbar.AppBarLayout; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.SearchActivityRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RecentSearchQuery.DeleteRecentSearchQuery; -import ml.docilealligator.infinityforreddit.RecentSearchQuery.RecentSearchQuery; -import ml.docilealligator.infinityforreddit.RecentSearchQuery.RecentSearchQueryViewModel; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class SearchActivity extends BaseActivity { - - static final String EXTRA_QUERY = "EQ"; - static final String EXTRA_SUBREDDIT_NAME = "ESN"; - static final String EXTRA_SUBREDDIT_IS_USER = "ESIU"; - static final String EXTRA_SEARCH_ONLY_SUBREDDITS = "ESOS"; - static final String EXTRA_RETURN_SUBREDDIT_NAME = "ERSN"; - static final String EXTRA_RETURN_SUBREDDIT_ICON_URL = "ERSIURL"; - - private static final String NULL_ACCOUNT_NAME_STATE = "NANS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String SUBREDDIT_NAME_STATE = "SNS"; - private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; - - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; - private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 1; - - @BindView(R.id.coordinator_layout_search_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_search_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar) - Toolbar toolbar; - @BindView(R.id.search_view_search_activity) - SimpleSearchView simpleSearchView; - @BindView(R.id.subreddit_name_relative_layout_search_activity) - RelativeLayout subredditNameRelativeLayout; - @BindView(R.id.search_in_text_view_search_activity) - TextView searchInTextView; - @BindView(R.id.subreddit_name_text_view_search_activity) - TextView subredditNameTextView; - @BindView(R.id.divider_search_activity) - View divider; - @BindView(R.id.recent_summary_text_view_search_activity) - TextView recentSummaryTextView; - @BindView(R.id.recycler_view_search_activity) - RecyclerView recyclerView; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccountName = false; - private String mAccountName; - private String query; - private String subredditName; - private boolean subredditIsUser; - private boolean searchOnlySubreddits; - private SearchActivityRecyclerViewAdapter adapter; - RecentSearchQueryViewModel mRecentSearchQueryViewModel; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_search); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - setSupportActionBar(toolbar); - - searchOnlySubreddits = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_SUBREDDITS, false); - - simpleSearchView.setOnSearchViewListener(new SimpleSearchView.SearchViewListener() { - @Override - public void onSearchViewShown() { - - } - - @Override - public void onSearchViewClosed() { - finish(); - } - - @Override - public void onSearchViewShownAnimation() { - - } - - @Override - public void onSearchViewClosedAnimation() { - - } - }); - - simpleSearchView.setOnQueryTextListener(new SimpleSearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - search(query); - return true; - } - - @Override - public boolean onQueryTextChange(String newText) { - return false; - } - - @Override - public boolean onQueryTextCleared() { - return false; - } - }); - - if (savedInstanceState != null) { - mNullAccountName = savedInstanceState.getBoolean(NULL_ACCOUNT_NAME_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); - subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); - - if (subredditName == null) { - subredditNameTextView.setText(R.string.all_subreddits); - } else { - subredditNameTextView.setText(subredditName); - } - - if (!mNullAccountName && mAccountName == null) { - getCurrentAccountAndInitializeViewPager(); - } else { - bindView(); - } - } else { - query = getIntent().getStringExtra(EXTRA_QUERY); - getCurrentAccountAndInitializeViewPager(); - } - - if (searchOnlySubreddits) { - subredditNameRelativeLayout.setVisibility(View.GONE); - } else { - subredditNameRelativeLayout.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - intent.putExtra(SubredditSelectionActivity.EXTRA_EXTRA_CLEAR_SELECTION, true); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - } - - Intent intent = getIntent(); - if (intent.hasExtra(EXTRA_SUBREDDIT_NAME)) { - subredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); - subredditNameTextView.setText(subredditName); - subredditIsUser = intent.getBooleanExtra(EXTRA_SUBREDDIT_IS_USER, false); - } - } - - private void getCurrentAccountAndInitializeViewPager() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccountName = true; - } else { - mAccountName = account.getUsername(); - } - bindView(); - }).execute(); - } - - private void bindView() { - if (mAccountName != null) { - adapter = new SearchActivityRecyclerViewAdapter(this, mCustomThemeWrapper, new SearchActivityRecyclerViewAdapter.ItemOnClickListener() { - @Override - public void onClick(String query) { - search(query); - } - - @Override - public void onDelete(RecentSearchQuery recentSearchQuery) { - DeleteRecentSearchQuery.deleteRecentSearchQueryListener(mRedditDataRoomDatabase, recentSearchQuery, () -> {}); - } - }); - recyclerView.setNestedScrollingEnabled(false); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - recyclerView.setAdapter(adapter); - mRecentSearchQueryViewModel = new ViewModelProvider(this, - new RecentSearchQueryViewModel.Factory(mRedditDataRoomDatabase, mAccountName)) - .get(RecentSearchQueryViewModel.class); - - mRecentSearchQueryViewModel.getAllRecentSearchQueries().observe(this, recentSearchQueries -> { - if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) { - divider.setVisibility(View.VISIBLE); - recentSummaryTextView.setVisibility(View.VISIBLE); - } else { - divider.setVisibility(View.GONE); - recentSummaryTextView.setVisibility(View.GONE); - } - adapter.setRecentSearchQueries(recentSearchQueries); - }); - } - } - - private void search(String query) { - if (searchOnlySubreddits) { - Intent intent = new Intent(SearchActivity.this, SearchSubredditsResultActivity.class); - intent.putExtra(SearchSubredditsResultActivity.EXTRA_QUERY, query); - startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); - } else { - Intent intent = new Intent(SearchActivity.this, SearchResultActivity.class); - intent.putExtra(SearchResultActivity.EXTRA_QUERY, query); - if (subredditName != null) { - if (subredditIsUser) { - intent.putExtra(SearchResultActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - intent.putExtra(SearchResultActivity.EXTRA_SUBREDDIT_NAME, subredditName); - } - } - startActivity(intent); - finish(); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - simpleSearchView.setSearchBackground(new ColorDrawable(mCustomThemeWrapper.getColorPrimary())); - int toolbarPrimaryTextAndIconColorColor = mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor(); - simpleSearchView.setIconsColor(toolbarPrimaryTextAndIconColorColor); - simpleSearchView.setTextColor(toolbarPrimaryTextAndIconColorColor); - simpleSearchView.setBackIconColor(toolbarPrimaryTextAndIconColorColor); - simpleSearchView.setHintTextColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); - int colorAccent = mCustomThemeWrapper.getColorAccent(); - searchInTextView.setTextColor(colorAccent); - subredditNameTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); - divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); - recentSummaryTextView.setTextColor(colorAccent); - } - - @Override - protected void onStart() { - super.onStart(); - simpleSearchView.showSearch(false); - simpleSearchView.getSearchEditText().requestFocus(); - - if (query != null) { - simpleSearchView.getSearchEditText().setText(query); - simpleSearchView.getSearchEditText().setSelection(query.length()); - query = null; - } - - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - } - - @Override - protected void onPause() { - super.onPause(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.hideSoftInputFromWindow(simpleSearchView.getSearchEditText().getWindowToken(), 0); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - if (simpleSearchView.onActivityResult(requestCode, resultCode, data)) { - return; - } - - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); - subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); - - if (subredditName == null) { - subredditNameTextView.setText(R.string.all_subreddits); - } else { - subredditNameTextView.setText(subredditName); - } - } - } else if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - String name = data.getExtras().getString(SearchSubredditsResultActivity.EXTRA_RETURN_SUBREDDIT_NAME); - String iconUrl = data.getExtras().getString(SearchSubredditsResultActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); - Intent returnIntent = new Intent(); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); - setResult(Activity.RESULT_OK, returnIntent); - finish(); - } - } - - super.onActivityResult(requestCode, resultCode, data); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.search_activity, menu); - simpleSearchView.setMenuItem(menu.findItem(R.id.action_search_search_activity)); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCOUNT_NAME_STATE, mNullAccountName); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putString(SUBREDDIT_NAME_STATE, subredditName); - outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchResultActivity.java deleted file mode 100644 index 89d2faf3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchResultActivity.java +++ /dev/null @@ -1,513 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -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.FragmentManager; -import androidx.lifecycle.Lifecycle; -import androidx.viewpager2.adapter.FragmentStateAdapter; -import androidx.viewpager2.widget.ViewPager2; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SearchPostSortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SearchUserAndSubredditSortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTimeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.Fragment.SubredditListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.UserListingFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RecentSearchQuery.InsertRecentSearchQuery; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -public class SearchResultActivity extends BaseActivity implements SortTypeSelectionCallback, - PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { - static final String EXTRA_QUERY = "QK"; - static final String EXTRA_SUBREDDIT_NAME = "ESN"; - - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String INSERT_SEARCH_QUERY_SUCCESS_STATE = "ISQSS"; - @BindView(R.id.coordinator_layout_search_result_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_search_result_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_search_result_activity) - Toolbar toolbar; - @BindView(R.id.tab_layout_search_result_activity) - TabLayout tabLayout; - @BindView(R.id.view_pager_search_result_activity) - ViewPager2 viewPager2; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String mQuery; - private String mSubredditName; - private boolean mInsertSearchQuerySuccess; - private FragmentManager fragmentManager; - private SectionsPagerAdapter sectionsPagerAdapter; - private SearchPostSortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment; - private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; - private SearchUserAndSubredditSortTypeBottomSheetFragment searchUserAndSubredditSortTypeBottomSheetFragment; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - private SlidrInterface mSlidrInterface; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_search_result); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - } - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - // Get the intent, verify the action and get the query - Intent intent = getIntent(); - String query = intent.getStringExtra(EXTRA_QUERY); - - mSubredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); - - if (query != null) { - mQuery = query; - setTitle(query); - } - - fragmentManager = getSupportFragmentManager(); - - if (savedInstanceState == null) { - getCurrentAccountAndInitializeViewPager(); - } else { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - mInsertSearchQuerySuccess = savedInstanceState.getBoolean(INSERT_SEARCH_QUERY_SUCCESS_STATE); - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndInitializeViewPager(); - } else { - initializeViewPager(); - } - } - - searchPostSortTypeBottomSheetFragment = new SearchPostSortTypeBottomSheetFragment(); - Bundle bundle = new Bundle(); - searchPostSortTypeBottomSheetFragment.setArguments(bundle); - - sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); - - searchUserAndSubredditSortTypeBottomSheetFragment = new SearchUserAndSubredditSortTypeBottomSheetFragment(); - - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - } - - @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()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - applyTabLayoutTheme(tabLayout); - } - - private void getCurrentAccountAndInitializeViewPager() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - initializeViewPager(); - }).execute(); - } - - private void initializeViewPager() { - sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); - viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(3); - viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); - viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageSelected(int position) { - sectionsPagerAdapter.displaySortTypeInToolbar(); - if (position == 0) { - unlockSwipeRightToGoBack(); - } else { - lockSwipeRightToGoBack(); - } - } - }); - new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { - switch (position) { - case 0: - tab.setText(R.string.posts); - break; - case 1: - tab.setText(R.string.subreddits); - break; - case 2: - tab.setText(R.string.users); - break; - } - }).attach(); - fixViewPager2Sensitivity(viewPager2); - - if (mAccountName != null && !mInsertSearchQuerySuccess && mQuery != null) { - InsertRecentSearchQuery.insertRecentSearchQueryListener(mRedditDataRoomDatabase, mAccountName, - mQuery, () -> mInsertSearchQuerySuccess = true); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.search_result_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - onBackPressed(); - return true; - case R.id.action_sort_search_result_activity: - switch (viewPager2.getCurrentItem()) { - case 0: { - searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag()); - break; - } - case 1: - case 2: - Bundle bundle = new Bundle(); - bundle.putInt(SearchUserAndSubredditSortTypeBottomSheetFragment.EXTRA_FRAGMENT_POSITION, viewPager2.getCurrentItem()); - searchUserAndSubredditSortTypeBottomSheetFragment.setArguments(bundle); - searchUserAndSubredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchUserAndSubredditSortTypeBottomSheetFragment.getTag()); - break; - } - return true; - case R.id.action_search_search_result_activity: - Intent intent = new Intent(this, SearchActivity.class); - if (mSubredditName != null && !mSubredditName.equals("")) { - intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, mSubredditName); - } - intent.putExtra(SearchActivity.EXTRA_QUERY, mQuery); - finish(); - startActivity(intent); - return true; - case R.id.action_refresh_search_result_activity: - sectionsPagerAdapter.refresh(); - return true; - case R.id.action_change_post_layout_search_result_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - } - return super.onOptionsItemSelected(item); - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putBoolean(INSERT_SEARCH_QUERY_SUCCESS_STATE, mInsertSearchQuerySuccess); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Override - public void sortTypeSelected(SortType sortType) { - sectionsPagerAdapter.changeSortType(sortType); - } - - @Override - public void sortTypeSelected(String sortType) { - Bundle bundle = new Bundle(); - bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); - sortTimeBottomSheetFragment.setArguments(bundle); - sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); - } - - @Override - public void searchUserAndSubredditSortTypeSelected(SortType sortType, int fragmentPosition) { - sectionsPagerAdapter.changeSortType(sortType, fragmentPosition); - } - - @Override - public void postLayoutSelected(int postLayout) { - sectionsPagerAdapter.changePostLayout(postLayout); - } - - @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 displaySortType() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.displaySortTypeInToolbar(); - } - } - - private class SectionsPagerAdapter extends FragmentStateAdapter { - - public SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { - super(fm, lifecycle); - } - - @NonNull - @Override - public Fragment createFragment(int position) { - switch (position) { - case 0: { - PostFragment mFragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SEARCH); - bundle.putString(PostFragment.EXTRA_NAME, mSubredditName); - bundle.putString(PostFragment.EXTRA_QUERY, mQuery); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - mFragment.setArguments(bundle); - return mFragment; - } - case 1: { - SubredditListingFragment mFragment = new SubredditListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(SubredditListingFragment.EXTRA_QUERY, mQuery); - bundle.putBoolean(SubredditListingFragment.EXTRA_IS_POSTING, false); - bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - mFragment.setArguments(bundle); - return mFragment; - } - default: { - UserListingFragment mFragment = new UserListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(UserListingFragment.EXTRA_QUERY, mQuery); - bundle.putString(UserListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(UserListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - mFragment.setArguments(bundle); - return mFragment; - } - } - } - - @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; - } - - void changeSortType(SortType sortType) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeSortType(sortType); - displaySortTypeInToolbar(); - } - } - - void changeSortType(SortType sortType, int fragmentPosition) { - Fragment fragment = fragmentManager.findFragmentByTag("f" + fragmentPosition); - if (fragment instanceof SubredditListingFragment) { - ((SubredditListingFragment) fragment).changeSortType(sortType); - } else if (fragment instanceof UserListingFragment) { - ((UserListingFragment) fragment).changeSortType(sortType); - } - displaySortTypeInToolbar(); - } - - public void refresh() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof FragmentCommunicator) { - ((FragmentCommunicator) fragment).refresh(); - } - } - - void changeNSFW(boolean nsfw) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeNSFW(nsfw); - } - } - - void changePostLayout(int postLayout) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changePostLayout(postLayout); - } - } - - void goBackToTop() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).goBackToTop(); - } else if (fragment instanceof SubredditListingFragment) { - ((SubredditListingFragment) fragment).goBackToTop(); - } else if (fragment instanceof UserListingFragment) { - ((UserListingFragment) fragment).goBackToTop(); - } - } - - void displaySortTypeInToolbar() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - SortType sortType = ((PostFragment) fragment).getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } else if (fragment instanceof SubredditListingFragment) { - SortType sortType = ((SubredditListingFragment) fragment).getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } else if (fragment instanceof UserListingFragment) { - SortType sortType = ((UserListingFragment) fragment).getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } - } - - @Override - public int getItemCount() { - return 3; - } - } - - private void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - private void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchSubredditsResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchSubredditsResultActivity.java deleted file mode 100644 index 92affa75..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SearchSubredditsResultActivity.java +++ /dev/null @@ -1,205 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.app.Activity; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; - -import com.google.android.material.appbar.AppBarLayout; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.SubredditListingFragment; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class SearchSubredditsResultActivity extends BaseActivity implements ActivityToolbarInterface { - - static final String EXTRA_QUERY = "EQ"; - static final String EXTRA_RETURN_SUBREDDIT_NAME = "ERSN"; - static final String EXTRA_RETURN_SUBREDDIT_ICON_URL = "ERSIURL"; - - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String FRAGMENT_OUT_STATE = "FOS"; - - @BindView(R.id.coordinator_layout_search_subreddits_result_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_search_subreddits_result_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_search_subreddits_result_activity) - Toolbar toolbar; - Fragment mFragment; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_search_subreddits_result); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - } - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - String query = getIntent().getExtras().getString(EXTRA_QUERY); - - if (savedInstanceState == null) { - getCurrentAccountAndInitializeFragment(query); - } else { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndInitializeFragment(query); - } else { - mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_search_subreddits_result_activity, mFragment).commit(); - } - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - private void getCurrentAccountAndInitializeFragment(String query) { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - - mFragment = new SubredditListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(SubredditListingFragment.EXTRA_QUERY, query); - bundle.putBoolean(SubredditListingFragment.EXTRA_IS_POSTING, true); - bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - mFragment.setArguments(bundle); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_search_subreddits_result_activity, mFragment).commit(); - }).execute(); - } - - public void getSelectedSubreddit(String name, String iconUrl) { - Intent returnIntent = new Intent(); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); - setResult(Activity.RESULT_OK, returnIntent); - finish(); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Override - public void onLongPress() { - if (mFragment != null) { - ((SubredditListingFragment) mFragment).goBackToTop(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java deleted file mode 100644 index e90432f3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java +++ /dev/null @@ -1,261 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.r0adkll.slidr.Slidr; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.Adapter.UserFlairRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FetchUserFlairs; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SelectUserFlair; -import ml.docilealligator.infinityforreddit.UserFlair; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class SelectUserFlairActivity extends BaseActivity implements ActivityToolbarInterface { - - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String USER_FLAIRS_STATE = "UFS"; - - @BindView(R.id.coordinator_layout_select_user_flair_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_select_user_flair_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_select_user_flair_activity) - Toolbar toolbar; - @BindView(R.id.recycler_view_select_user_flair_activity) - RecyclerView recyclerView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private LinearLayoutManager mLinearLayoutManager; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private ArrayList mUserFlairs; - private String mSubredditName; - private UserFlairRecyclerViewAdapter mAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_select_user_flair); - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - setTitle(mSubredditName); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - mUserFlairs = savedInstanceState.getParcelableArrayList(USER_FLAIRS_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - } else { - getCurrentAccountAndBindView(); - } - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - bindView(); - }).execute(); - } - - private void bindView() { - if (mUserFlairs == null) { - FetchUserFlairs.fetchUserFlairsInSubreddit(mOauthRetrofit, mAccessToken, mSubredditName, - new FetchUserFlairs.FetchUserFlairsInSubredditListener() { - @Override - public void fetchSuccessful(ArrayList userFlairs) { - mUserFlairs = userFlairs; - instantiateRecyclerView(); - } - - @Override - public void fetchFailed() { - - } - }); - } else { - instantiateRecyclerView(); - } - } - - private void instantiateRecyclerView() { - mAdapter = new UserFlairRecyclerViewAdapter(mCustomThemeWrapper, mUserFlairs, (userFlair, editUserFlair) -> { - if (editUserFlair) { - View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_flair, null); - EditText flairEditText = dialogView.findViewById(R.id.flair_edit_text_edit_flair_dialog); - flairEditText.setText(userFlair.getText()); - flairEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.edit_flair) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); - } - userFlair.setText(flairEditText.getText().toString()); - selectUserFlair(userFlair); - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); - } - }) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); - } - }) - .show(); - } else { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.select_this_user_flair) - .setMessage(userFlair.getText()) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> selectUserFlair(userFlair)) - .setNegativeButton(R.string.no, null) - .show(); - } - }); - mLinearLayoutManager = new LinearLayoutManager(SelectUserFlairActivity.this); - recyclerView.setLayoutManager(mLinearLayoutManager); - recyclerView.setAdapter(mAdapter); - } - - private void selectUserFlair(UserFlair userFlair) { - SelectUserFlair.selectUserFlair(mOauthRetrofit, mAccessToken, userFlair, mSubredditName, mAccountName, - new SelectUserFlair.SelectUserFlairListener() { - @Override - public void success() { - Toast.makeText(SelectUserFlairActivity.this, R.string.select_user_flair_success, Toast.LENGTH_SHORT).show(); - finish(); - } - - @Override - public void failed(String errorMessage) { - if (errorMessage == null || errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.select_user_flair_success, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); - } - } - }); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putParcelableArrayList(USER_FLAIRS_STATE, mUserFlairs); - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - @Override - public void onLongPress() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectedSubredditsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectedSubredditsActivity.java deleted file mode 100644 index 3c9b7aba..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectedSubredditsActivity.java +++ /dev/null @@ -1,175 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.app.Activity; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.r0adkll.slidr.Slidr; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.Adapter.SelectedSubredditsRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class SelectedSubredditsActivity extends BaseActivity implements ActivityToolbarInterface { - - public static final String EXTRA_SELECTED_SUBREDDITS = "ESS"; - public static final String EXTRA_RETURN_SELECTED_SUBREDDITS = "ERSS"; - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 1; - private static final String SELECTED_SUBREDDITS_STATE = "SSS"; - - @BindView(R.id.coordinator_layout_selected_subreddits_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_selected_subreddits_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_selected_subreddits_activity) - Toolbar toolbar; - @BindView(R.id.recycler_view_selected_subreddits_activity) - RecyclerView recyclerView; - @BindView(R.id.fab_selected_subreddits_activity) - FloatingActionButton fab; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private LinearLayoutManager linearLayoutManager; - private SelectedSubredditsRecyclerViewAdapter adapter; - private ArrayList subreddits; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_selected_subreddits); - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - if (savedInstanceState != null) { - subreddits = savedInstanceState.getStringArrayList(SELECTED_SUBREDDITS_STATE); - } else { - subreddits = getIntent().getStringArrayListExtra(EXTRA_SELECTED_SUBREDDITS); - } - - adapter = new SelectedSubredditsRecyclerViewAdapter(mCustomThemeWrapper, subreddits); - linearLayoutManager = new LinearLayoutManager(this); - recyclerView.setLayoutManager(linearLayoutManager); - recyclerView.setAdapter(adapter); - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (dy > 0) { - fab.hide(); - } else { - fab.show(); - } - } - }); - - fab.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditMultiselectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.selected_subreddits_activity, menu); - 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_selected_subreddits_activity) { - if (adapter != null) { - Intent returnIntent = new Intent(); - returnIntent.putExtra(EXTRA_RETURN_SELECTED_SUBREDDITS, adapter.getSubreddits()); - setResult(Activity.RESULT_OK, returnIntent); - } - finish(); - } - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE && resultCode == RESULT_OK) { - if (data != null) { - if (subreddits == null) { - subreddits = new ArrayList<>(); - } - subreddits = data.getStringArrayListExtra(SubredditMultiselectionActivity.EXTRA_RETURN_SELECTED_SUBREDDITS); - adapter.addSubreddits(subreddits); - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - if (adapter != null) { - outState.putStringArrayList(SELECTED_SUBREDDITS_STATE, adapter.getSubreddits()); - } - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - applyFABTheme(fab); - } - - @Override - public void onLongPress() { - if (linearLayoutManager != null) { - linearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SendPrivateMessageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SendPrivateMessageActivity.java deleted file mode 100644 index c000079d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SendPrivateMessageActivity.java +++ /dev/null @@ -1,210 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.EditText; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.snackbar.Snackbar; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.ComposeMessage; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import retrofit2.Retrofit; - -public class SendPrivateMessageActivity extends BaseActivity { - public static final String EXTRA_RECIPIENT_USERNAME = "ERU"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - @BindView(R.id.coordinator_layout_send_private_message_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_send_private_message_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_send_private_message_activity) - Toolbar toolbar; - @BindView(R.id.username_edit_text_send_private_message_activity) - EditText usernameEditText; - @BindView(R.id.divider_1_send_private_message_activity) - View divider1; - @BindView(R.id.subjet_edit_text_send_private_message_activity) - EditText subjectEditText; - @BindView(R.id.divider_2_send_private_message_activity) - View divider2; - @BindView(R.id.content_edit_text_send_private_message_activity) - EditText messageEditText; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private boolean isSubmitting = false; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_send_private_message); - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (savedInstanceState == null) { - getCurrentAccount(); - } else { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - } - - setSupportActionBar(toolbar); - - String username = getIntent().getStringExtra(EXTRA_RECIPIENT_USERNAME); - if (username != null) { - usernameEditText.setText(username); - } - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - }).execute(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.send_private_message_activity, menu); - 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_send_send_private_message_activity) { - if (!isSubmitting) { - isSubmitting = true; - if (usernameEditText.getText() == null || usernameEditText.getText().toString().equals("")) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.message_username_required, Snackbar.LENGTH_LONG).show(); - return true; - } - - if (subjectEditText.getText() == null || subjectEditText.getText().toString().equals("")) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.message_subject_required, Snackbar.LENGTH_LONG).show(); - return true; - } - - if (messageEditText.getText() == null || messageEditText.getText().toString().equals("")) { - isSubmitting = false; - Snackbar.make(coordinatorLayout, R.string.message_content_required, Snackbar.LENGTH_LONG).show(); - return true; - } - - item.setEnabled(false); - item.getIcon().setAlpha(130); - Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_message, Snackbar.LENGTH_INDEFINITE); - sendingSnackbar.show(); - - ComposeMessage.composeMessage(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale, - usernameEditText.getText().toString(), subjectEditText.getText().toString(), - messageEditText.getText().toString(), new ComposeMessage.ComposeMessageListener() { - @Override - public void composeMessageSuccess() { - isSubmitting = false; - item.setEnabled(true); - item.getIcon().setAlpha(255); - Toast.makeText(SendPrivateMessageActivity.this, R.string.send_message_success, Toast.LENGTH_SHORT).show(); - finish(); - } - - @Override - public void composeMessageFailed(String errorMessage) { - isSubmitting = false; - sendingSnackbar.dismiss(); - item.setEnabled(true); - item.getIcon().setAlpha(255); - - if (errorMessage == null || errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.send_message_failed, Snackbar.LENGTH_LONG).show(); - } else { - Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); - } - } - }); - } - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - usernameEditText.setTextColor(primaryTextColor); - subjectEditText.setTextColor(primaryTextColor); - messageEditText.setTextColor(primaryTextColor); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - usernameEditText.setHintTextColor(secondaryTextColor); - subjectEditText.setHintTextColor(secondaryTextColor); - messageEditText.setHintTextColor(secondaryTextColor); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SettingsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SettingsActivity.java deleted file mode 100644 index 10b9b034..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SettingsActivity.java +++ /dev/null @@ -1,194 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import com.google.android.material.appbar.AppBarLayout; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Settings.AboutPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.CustomizeBottomAppBarFragment; -import ml.docilealligator.infinityforreddit.Settings.CustomizeMainPageTabsFragment; -import ml.docilealligator.infinityforreddit.Settings.FontPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.GesturesAndButtonsPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.InterfacePreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.MainPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.NsfwAndBlurringFragment; - -public class SettingsActivity extends BaseActivity implements - PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { - - private static final String TITLE_STATE = "TS"; - - @BindView(R.id.appbar_layout_settings_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_settings_activity) - Toolbar toolbar; - private boolean mNullAccountName; - private String mAccountName; - - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_settings); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - setSupportActionBar(toolbar); - - getCurrentAccountAndBindView(savedInstanceState); - - getSupportFragmentManager().addOnBackStackChangedListener(() -> { - if (getSupportFragmentManager().getBackStackEntryCount() == 0) { - setTitle(R.string.settings_activity_label); - } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof AboutPreferenceFragment) { - setTitle(R.string.settings_about_master_title); - } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof InterfacePreferenceFragment) { - setTitle(R.string.settings_interface_title); - } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof FontPreferenceFragment) { - setTitle(R.string.settings_font_title); - } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof GesturesAndButtonsPreferenceFragment) { - setTitle(R.string.settings_gestures_and_buttons_title); - } - }); - } - - private void getCurrentAccountAndBindView(Bundle savedInstanceState) { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (getSupportFragmentManager().isDestroyed()) { - return; - } - if (account == null) { - mNullAccountName = true; - } else { - mAccountName = account.getUsername(); - } - - if (savedInstanceState == null) { - getSupportFragmentManager() - .beginTransaction() - .replace(R.id.frame_layout_settings_activity, new MainPreferenceFragment()) - .commit(); - } else { - setTitle(savedInstanceState.getCharSequence(TITLE_STATE)); - } - }).execute(); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } - return false; - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putCharSequence(TITLE_STATE, getTitle()); - } - - @Override - public boolean onSupportNavigateUp() { - if (getSupportFragmentManager().popBackStackImmediate()) { - return true; - } - return super.onSupportNavigateUp(); - } - - @Override - public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) { - // Instantiate the new Fragment - final Bundle args = pref.getExtras(); - final Fragment fragment = getSupportFragmentManager().getFragmentFactory().instantiate( - getClassLoader(), - pref.getFragment()); - if (fragment instanceof CustomizeMainPageTabsFragment) { - args.putString(CustomizeMainPageTabsFragment.EXTRA_ACCOUNT_NAME, mAccountName); - } else if (fragment instanceof NsfwAndBlurringFragment) { - args.putString(NsfwAndBlurringFragment.EXTRA_ACCOUNT_NAME, mAccountName); - } else if (fragment instanceof CustomizeBottomAppBarFragment) { - args.putString(CustomizeBottomAppBarFragment.EXTRA_ACCOUNT_NAME, mAccountName); - } - fragment.setArguments(args); - fragment.setTargetFragment(caller, 0); - - getSupportFragmentManager().beginTransaction() - .setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right) - .replace(R.id.frame_layout_settings_activity, fragment) - .addToBackStack(null) - .commit(); - setTitle(pref.getTitle()); - return true; - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { - recreate(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ShareDataResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ShareDataResolverActivity.java deleted file mode 100644 index 66ebc4cf..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ShareDataResolverActivity.java +++ /dev/null @@ -1,79 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.util.Patterns; -import android.widget.Toast; - -import androidx.appcompat.app.AppCompatActivity; - -import ml.docilealligator.infinityforreddit.R; - -public class ShareDataResolverActivity extends AppCompatActivity { - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - Intent receivedIntent = getIntent(); - String action = receivedIntent.getAction(); - String type = receivedIntent.getType(); - - if (Intent.ACTION_SEND.equals(action) && type != null) { - if ("text/plain".equals(type)) { - String text = receivedIntent.getStringExtra(Intent.EXTRA_TEXT); - if (text != null) { - if (Patterns.WEB_URL.matcher(text).matches()) { - //It's a link - Intent intent = new Intent(this, PostLinkActivity.class); - intent.putExtra(PostLinkActivity.EXTRA_LINK, text); - startActivity(intent); - } else { - Intent intent = new Intent(this, PostTextActivity.class); - intent.putExtra(PostTextActivity.EXTRA_CONTENT, text); - startActivity(intent); - } - } else { - Toast.makeText(this, R.string.no_data_received, Toast.LENGTH_SHORT).show(); - } - } else if (type.equals("image/gif")) { - Uri videoUri = receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM); - if (videoUri != null) { - Intent intent = new Intent(this, PostVideoActivity.class); - intent.setData(videoUri); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(intent); - } else { - Toast.makeText(this, R.string.no_video_path_received, Toast.LENGTH_SHORT).show(); - } - } else if (type.startsWith("image/")) { - Uri imageUri = receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM); - if (imageUri != null) { - Intent intent = new Intent(this, PostImageActivity.class); - intent.setData(imageUri); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(intent); - } else { - Toast.makeText(this, R.string.no_image_path_received, Toast.LENGTH_SHORT).show(); - } - } else if (type.startsWith("video/")) { - Uri videoUri = receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM); - if (videoUri != null) { - Intent intent = new Intent(this, PostVideoActivity.class); - intent.setData(videoUri); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(intent); - } else { - Toast.makeText(this, R.string.no_video_path_received, Toast.LENGTH_SHORT).show(); - } - } else { - Toast.makeText(this, R.string.cannot_handle_intent, Toast.LENGTH_SHORT).show(); - } - } else { - Toast.makeText(this, R.string.cannot_handle_intent, Toast.LENGTH_SHORT).show(); - } - - finish(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubmitCrosspostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubmitCrosspostActivity.java deleted file mode 100644 index 37a9258b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubmitCrosspostActivity.java +++ /dev/null @@ -1,623 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; - -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.davemorrissey.labs.subscaleview.ImageSource; -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.libRG.CustomTextView; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadSubredditIconAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FlairBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SubmitCrosspostEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Service.SubmitPostService; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class SubmitCrosspostActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { - - public static final String EXTRA_POST = "EP"; - - private static final String SUBREDDIT_NAME_STATE = "SNS"; - private static final String SUBREDDIT_ICON_STATE = "SIS"; - private static final String SUBREDDIT_SELECTED_STATE = "SSS"; - private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; - private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; - private static final String IS_POSTING_STATE = "IPS"; - private static final String FLAIR_STATE = "FS"; - private static final String IS_SPOILER_STATE = "ISS"; - private static final String IS_NSFW_STATE = "INS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - - private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; - - @BindView(R.id.coordinator_layout_submit_crosspost_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_submit_crosspost_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_submit_crosspost_activity) - Toolbar toolbar; - @BindView(R.id.subreddit_icon_gif_image_view_submit_crosspost_activity) - GifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_submit_crosspost_activity) - TextView subredditNameTextView; - @BindView(R.id.rules_button_submit_crosspost_activity) - Button rulesButton; - @BindView(R.id.divider_1_submit_crosspost_activity) - View divider1; - @BindView(R.id.flair_custom_text_view_submit_crosspost_activity) - CustomTextView flairTextView; - @BindView(R.id.spoiler_custom_text_view_submit_crosspost_activity) - CustomTextView spoilerTextView; - @BindView(R.id.nsfw_custom_text_view_submit_crosspost_activity) - CustomTextView nsfwTextView; - @BindView(R.id.divider_2_submit_crosspost_activity) - View divider2; - @BindView(R.id.post_title_edit_text_submit_crosspost_activity) - EditText titleEditText; - @BindView(R.id.divider_3_submit_crosspost_activity) - View divider3; - @BindView(R.id.post_content_text_view_submit_crosspost_activity) - TextView contentTextView; - @BindView(R.id.frame_layout_submit_crosspost_activity) - FrameLayout frameLayout; - @BindView(R.id.image_view_submit_crosspost_activity) - SubsamplingScaleImageView imageView; - @BindView(R.id.play_button_image_view_submit_crosspost_activity) - ImageView playButton; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private Post post; - private String iconUrl; - private String subredditName; - private boolean subredditSelected = false; - private boolean subredditIsUser; - private boolean loadSubredditIconSuccessful = true; - private boolean isPosting; - private int primaryTextColor; - private int flairBackgroundColor; - private int flairTextColor; - private int spoilerBackgroundColor; - private int spoilerTextColor; - private int nsfwBackgroundColor; - private int nsfwTextColor; - private Flair flair; - private boolean isSpoiler = false; - private boolean isNSFW = false; - private Resources resources; - private Menu mMenu; - private RequestManager mGlide; - private FlairBottomSheetFragment flairSelectionBottomSheetFragment; - private Snackbar mPostingSnackbar; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_submit_crosspost); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mGlide = Glide.with(this); - - mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); - - resources = getResources(); - - post = getIntent().getParcelableExtra(EXTRA_POST); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccount(); - } - - subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); - iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); - subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); - subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); - loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); - isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); - flair = savedInstanceState.getParcelable(FLAIR_STATE); - isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); - isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); - - if (subredditName != null) { - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - flairTextView.setVisibility(View.VISIBLE); - if (!loadSubredditIconSuccessful) { - loadSubredditIcon(); - } - } - displaySubredditIcon(); - - if (isPosting) { - mPostingSnackbar.show(); - } - - if (flair != null) { - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - if (isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - } - if (isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - } - } else { - getCurrentAccount(); - - isPosting = false; - - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - - if (post.isSpoiler()) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - } - if (post.isNSFW()) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - } - - titleEditText.setText(post.getTitle()); - } - - if (post.getPostType() == Post.TEXT_TYPE) { - contentTextView.setVisibility(View.VISIBLE); - contentTextView.setText(post.getSelfTextPlain()); - } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { - contentTextView.setVisibility(View.VISIBLE); - contentTextView.setText(post.getUrl()); - } else if (post.getPostType() == Post.GIF_TYPE || post.getPostType() == Post.GALLERY_TYPE || post.getPostType() == Post.IMAGE_TYPE) { - Post.Preview preview = getPreview(post); - if (preview != null) { - frameLayout.setVisibility(View.VISIBLE); - mGlide.asBitmap().load(preview.getPreviewUrl()).into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - imageView.setImage(ImageSource.bitmap(resource)); - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - } - } else if (post.getPostType() == Post.VIDEO_TYPE) { - Post.Preview preview = getPreview(post); - if (preview != null) { - frameLayout.setVisibility(View.VISIBLE); - mGlide.asBitmap().load(preview.getPreviewUrl()).into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - imageView.setImage(ImageSource.bitmap(resource)); - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - playButton.setVisibility(View.VISIBLE); - } - } - - iconGifImageView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - subredditNameTextView.setOnClickListener(view -> { - Intent intent = new Intent(this, SubredditSelectionActivity.class); - startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); - }); - - rulesButton.setOnClickListener(view -> { - if (subredditName == null) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - } else { - Intent intent = new Intent(this, RulesActivity.class); - if (subredditIsUser) { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); - } - startActivity(intent); - } - }); - - flairTextView.setOnClickListener(view -> { - if (flair == null) { - flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - if (subredditIsUser) { - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); - } else { - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); - } - flairSelectionBottomSheetFragment.setArguments(bundle); - flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); - } else { - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - }); - - spoilerTextView.setOnClickListener(view -> { - if (!isSpoiler) { - spoilerTextView.setBackgroundColor(spoilerBackgroundColor); - spoilerTextView.setBorderColor(spoilerBackgroundColor); - spoilerTextView.setTextColor(spoilerTextColor); - isSpoiler = true; - } else { - spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - spoilerTextView.setTextColor(primaryTextColor); - isSpoiler = false; - } - }); - - nsfwTextView.setOnClickListener(view -> { - if (!isNSFW) { - nsfwTextView.setBackgroundColor(nsfwBackgroundColor); - nsfwTextView.setBorderColor(nsfwBackgroundColor); - nsfwTextView.setTextColor(nsfwTextColor); - isNSFW = true; - } else { - nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - nsfwTextView.setTextColor(primaryTextColor); - isNSFW = false; - } - }); - } - - @Nullable - private Post.Preview getPreview(Post post) { - ArrayList previews = post.getPreviews(); - if (previews != null && !previews.isEmpty()) { - return previews.get(0); - } - - return null; - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - subredditNameTextView.setTextColor(secondaryTextColor); - rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); - rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); - int dividerColor = mCustomThemeWrapper.getDividerColor(); - divider1.setBackgroundColor(dividerColor); - divider2.setBackgroundColor(dividerColor); - divider3.setBackgroundColor(dividerColor); - primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); - flairTextColor = mCustomThemeWrapper.getFlairTextColor(); - spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); - spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); - nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); - nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); - flairTextView.setTextColor(primaryTextColor); - spoilerTextView.setTextColor(primaryTextColor); - nsfwTextView.setTextColor(primaryTextColor); - titleEditText.setTextColor(primaryTextColor); - titleEditText.setHintTextColor(secondaryTextColor); - contentTextView.setTextColor(primaryTextColor); - contentTextView.setHintTextColor(secondaryTextColor); - } - - private void getCurrentAccount() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - }).execute(); - } - - private void displaySubredditIcon() { - if (iconUrl != null && !iconUrl.equals("")) { - 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(iconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(iconGifImageView); - } - } - - private void loadSubredditIcon() { - new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { - iconUrl = iconImageUrl; - displaySubredditIcon(); - loadSubredditIconSuccessful = true; - }).execute(); - } - - private void promptAlertDialog(int titleResId, int messageResId) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(titleResId) - .setMessage(messageResId) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> finish()) - .setNegativeButton(R.string.no, null) - .show(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.submit_crosspost_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - if (isPosting) { - mMenu.findItem(R.id.action_send_submit_crosspost_activity).setEnabled(false); - mMenu.findItem(R.id.action_send_submit_crosspost_activity).getIcon().setAlpha(130); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - return true; - } else { - if (!titleEditText.getText().toString().equals("")) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - return true; - } - } - finish(); - return true; - case R.id.action_send_submit_crosspost_activity: - if (!subredditSelected) { - Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); - return true; - } - - if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { - Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); - return true; - } - - isPosting = true; - - item.setEnabled(false); - item.getIcon().setAlpha(130); - - mPostingSnackbar.show(); - - String subredditName; - if (subredditIsUser) { - subredditName = "u_" + subredditNameTextView.getText().toString(); - } else { - subredditName = subredditNameTextView.getText().toString(); - } - - Intent intent = new Intent(this, SubmitPostService.class); - intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); - intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); - intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); - if (post.isCrosspost()) { - intent.putExtra(SubmitPostService.EXTRA_CONTENT, "t3_" + post.getCrosspostParentId()); - } else { - intent.putExtra(SubmitPostService.EXTRA_CONTENT, post.getFullName()); - } - intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_CROSSPOST); - intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); - intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); - intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); - intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_CROSSPOST); - startService(intent); - - return true; - } - - return false; - } - - @Override - public void onBackPressed() { - if (isPosting) { - promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); - } else { - if (!titleEditText.getText().toString().equals("")) { - promptAlertDialog(R.string.discard, R.string.discard_detail); - } else { - finish(); - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(SUBREDDIT_NAME_STATE, subredditName); - outState.putString(SUBREDDIT_ICON_STATE, iconUrl); - outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); - outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); - outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); - outState.putBoolean(IS_POSTING_STATE, isPosting); - outState.putParcelable(FLAIR_STATE, flair); - outState.putBoolean(IS_SPOILER_STATE, isSpoiler); - outState.putBoolean(IS_NSFW_STATE, isNSFW); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); - iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); - subredditSelected = true; - subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); - - subredditNameTextView.setTextColor(primaryTextColor); - subredditNameTextView.setText(subredditName); - displaySubredditIcon(); - - flairTextView.setVisibility(View.VISIBLE); - flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); - flairTextView.setTextColor(primaryTextColor); - flairTextView.setText(getString(R.string.flair)); - flair = null; - } - } - } - - @Override - protected void onDestroy() { - EventBus.getDefault().unregister(this); - super.onDestroy(); - } - - @Override - public void flairSelected(Flair flair) { - this.flair = flair; - flairTextView.setText(flair.getText()); - flairTextView.setBackgroundColor(flairBackgroundColor); - flairTextView.setBorderColor(flairBackgroundColor); - flairTextView.setTextColor(flairTextColor); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Subscribe - public void onSubmitTextPostEvent(SubmitCrosspostEvent submitCrosspostEvent) { - isPosting = false; - mPostingSnackbar.dismiss(); - if (submitCrosspostEvent.postSuccess) { - Intent intent = new Intent(this, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, submitCrosspostEvent.post); - startActivity(intent); - finish(); - } else { - mMenu.findItem(R.id.action_send_post_text_activity).setEnabled(true); - mMenu.findItem(R.id.action_send_post_text_activity).getIcon().setAlpha(255); - if (submitCrosspostEvent.errorMessage == null || submitCrosspostEvent.errorMessage.equals("")) { - Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); - } else { - Snackbar.make(coordinatorLayout, submitCrosspostEvent.errorMessage.substring(0, 1).toUpperCase() - + submitCrosspostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditFilterPopularAndAllActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditFilterPopularAndAllActivity.java deleted file mode 100644 index 55a62e7f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditFilterPopularAndAllActivity.java +++ /dev/null @@ -1,168 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.SubredditFilterRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubredditFilter.DeleteSubredditFilter; -import ml.docilealligator.infinityforreddit.SubredditFilter.InsertSubredditFilter; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilterViewModel; - -public class SubredditFilterPopularAndAllActivity extends BaseActivity { - - private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 1; - @BindView(R.id.coordinator_layout_subreddit_filter_popular_and_all_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_subreddit_filter_popular_and_all_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_subreddit_filter_popular_and_all_activity) - Toolbar toolbar; - @BindView(R.id.recycler_view_subreddit_filter_popular_and_all_activity) - RecyclerView recyclerView; - @BindView(R.id.fab_subreddit_filter_popular_and_all_activity) - FloatingActionButton fab; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - @Inject - RedditDataRoomDatabase redditDataRoomDatabase; - @Inject - CustomThemeWrapper customThemeWrapper; - SubredditFilterViewModel subredditFilterViewModel; - private SubredditFilterRecyclerViewAdapter adapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_subreddit_filter_popular_and_all); - - ButterKnife.bind(this); - - applyCustomTheme(); - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - adapter = new SubredditFilterRecyclerViewAdapter(subredditFilter -> DeleteSubredditFilter.deleteSubredditFilter(redditDataRoomDatabase, subredditFilter, () -> {})); - recyclerView.setLayoutManager(new LinearLayoutManager(this)); - recyclerView.setAdapter(adapter); - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (dy > 0) { - fab.hide(); - } else if (dy < 0) { - fab.show(); - } - } - }); - - subredditFilterViewModel = new ViewModelProvider(this, - new SubredditFilterViewModel.Factory(redditDataRoomDatabase)) - .get(SubredditFilterViewModel.class); - subredditFilterViewModel.getSubredditFilterLiveData().observe(this, subredditFilters -> adapter.updateSubredditsName(subredditFilters)); - - fab.setOnClickListener(view -> { - EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); - thingEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.choose_a_subreddit) - .setView(thingEditText) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - SubredditFilter subredditFilter = new SubredditFilter(thingEditText.getText().toString(), SubredditFilter.TYPE_POPULAR_AND_ALL); - InsertSubredditFilter.insertSubredditFilter(redditDataRoomDatabase, subredditFilter, - () -> {}); - }) - .setNegativeButton(R.string.cancel, null) - .setNeutralButton(R.string.search, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - - Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, true); - startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); - }) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - }) - .show(); - }); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE && resultCode == RESULT_OK && data != null) { - SubredditFilter subredditFilter = new SubredditFilter(data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_NAME), SubredditFilter.TYPE_POPULAR_AND_ALL); - InsertSubredditFilter.insertSubredditFilter(redditDataRoomDatabase, subredditFilter, - () -> {}); - } - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return sharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return customThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditMultiselectionActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditMultiselectionActivity.java deleted file mode 100644 index bf7a739b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditMultiselectionActivity.java +++ /dev/null @@ -1,266 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -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.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.google.android.material.appbar.AppBarLayout; -import com.r0adkll.slidr.Slidr; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.Adapter.SubredditMultiselectionRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditViewModel; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class SubredditMultiselectionActivity extends BaseActivity implements ActivityToolbarInterface { - - static final String EXTRA_RETURN_SELECTED_SUBREDDITS = "ERSS"; - - private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 1; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - - @BindView(R.id.coordinator_layout_subreddits_multiselection_activity) - CoordinatorLayout mCoordinatorLayout; - @BindView(R.id.appbar_layout_subreddits_multiselection_activity) - AppBarLayout mAppBarLayout; - @BindView(R.id.toolbar_subscribed_subreddits_multiselection_activity) - Toolbar mToolbar; - @BindView(R.id.swipe_refresh_layout_subscribed_subscribed_subreddits_multiselection_activity) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_subscribed_subscribed_subreddits_multiselection_activity) - RecyclerView mRecyclerView; - @BindView(R.id.no_subscriptions_linear_layout_subscribed_subreddits_multiselection_activity) - LinearLayout mLinearLayout; - @BindView(R.id.no_subscriptions_image_view_subscribed_subreddits_multiselection_activity) - ImageView mImageView; - @BindView(R.id.error_text_view_subscribed_subreddits_multiselection_activity) - TextView mErrorTextView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - public SubscribedSubredditViewModel mSubscribedSubredditViewModel; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private LinearLayoutManager mLinearLayoutManager; - private SubredditMultiselectionRecyclerViewAdapter mAdapter; - private RequestManager mGlide; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_subscribed_subreddits_multiselection); - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(mAppBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - mCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(mToolbar); - - int navBarHeight = getNavBarHeight(); - if (navBarHeight > 0) { - mRecyclerView.setPadding(0, 0, 0, navBarHeight); - } - } - } - - setSupportActionBar(mToolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - mGlide = Glide.with(this); - - mSwipeRefreshLayout.setEnabled(false); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - - if (!mNullAccessToken && mAccountName == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - } else { - getCurrentAccountAndBindView(); - } - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - Toast.makeText(this, R.string.logged_out, Toast.LENGTH_SHORT).show(); - finish(); - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - bindView(); - } - }).execute(); - } - - private void bindView() { - mLinearLayoutManager = new LinearLayoutManager(this); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - mAdapter = new SubredditMultiselectionRecyclerViewAdapter(this, mCustomThemeWrapper); - mRecyclerView.setAdapter(mAdapter); - - mSubscribedSubredditViewModel = new ViewModelProvider(this, - new SubscribedSubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName)) - .get(SubscribedSubredditViewModel.class); - mSubscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, subscribedSubredditData -> { - mSwipeRefreshLayout.setRefreshing(false); - if (subscribedSubredditData == null || subscribedSubredditData.size() == 0) { - mRecyclerView.setVisibility(View.GONE); - mLinearLayout.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.error_image).into(mImageView); - } else { - mLinearLayout.setVisibility(View.GONE); - mRecyclerView.setVisibility(View.VISIBLE); - mGlide.clear(mImageView); - } - - mAdapter.setSubscribedSubreddits(subscribedSubredditData); - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.subreddit_multiselection_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_save_subreddit_multiselection_activity: - if (mAdapter != null) { - Intent returnIntent = new Intent(); - returnIntent.putStringArrayListExtra(EXTRA_RETURN_SELECTED_SUBREDDITS, - mAdapter.getAllSelectedSubreddits()); - setResult(RESULT_OK, returnIntent); - } - finish(); - return true; - case R.id.action_search_subreddit_multiselection_activity: - Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, true); - startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); - } - - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE && resultCode == RESULT_OK && data != null && mAdapter != null) { - Intent returnIntent = new Intent(); - ArrayList selectedSubreddits = mAdapter.getAllSelectedSubreddits(); - selectedSubreddits.add(data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_NAME)); - returnIntent.putStringArrayListExtra(EXTRA_RETURN_SELECTED_SUBREDDITS, selectedSubreddits); - setResult(RESULT_OK, returnIntent); - finish(); - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); - mErrorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); - } - - @Override - public void onLongPress() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditSelectionActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditSelectionActivity.java deleted file mode 100644 index 3f61568b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubredditSelectionActivity.java +++ /dev/null @@ -1,298 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.app.Activity; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -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 com.google.android.material.appbar.AppBarLayout; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertSubscribedThingsAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.FetchSubscribedThing; -import ml.docilealligator.infinityforreddit.Fragment.SubscribedSubredditsListingFragment; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class SubredditSelectionActivity extends BaseActivity implements ActivityToolbarInterface { - - static final String EXTRA_EXTRA_CLEAR_SELECTION = "EECS"; - static final String EXTRA_RETURN_SUBREDDIT_NAME = "ERSN"; - static final String EXTRA_RETURN_SUBREDDIT_ICON_URL = "ERSIURL"; - static final String EXTRA_RETURN_SUBREDDIT_IS_USER = "ERSIU"; - - private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 0; - private static final String INSERT_SUBSCRIBED_SUBREDDIT_STATE = "ISSS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String ACCOUNT_PROFILE_IMAGE_URL = "APIU"; - private static final String FRAGMENT_OUT_STATE = "FOS"; - - @BindView(R.id.coordinator_layout_subreddit_selection_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_subreddit_selection_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_subreddit_selection_activity) - Toolbar toolbar; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String mAccountProfileImageUrl; - private boolean mInsertSuccess = false; - private Fragment mFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_subreddit_selection); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - } - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - - if (savedInstanceState == null) { - getCurrentAccountAndBindView(); - } else { - mInsertSuccess = savedInstanceState.getBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE); - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - mAccountProfileImageUrl = savedInstanceState.getString(ACCOUNT_PROFILE_IMAGE_URL); - - mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_subreddit_selection_activity, mFragment).commit(); - - if (!mNullAccessToken && mAccountName == null) { - getCurrentAccountAndBindView(); - } else { - bindView(false); - } - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - mAccountProfileImageUrl = account.getProfileImageUrl(); - } - bindView(true); - }).execute(); - } - - private void bindView(boolean initializeFragment) { - loadSubscriptions(); - - if (initializeFragment) { - mFragment = new SubscribedSubredditsListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(SubscribedSubredditsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - bundle.putString(SubscribedSubredditsListingFragment.EXTRA_ACCOUNT_PROFILE_IMAGE_URL, mAccountProfileImageUrl); - bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, true); - if (getIntent().hasExtra(EXTRA_EXTRA_CLEAR_SELECTION)) { - bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_EXTRA_CLEAR_SELECTION, - getIntent().getExtras().getBoolean(EXTRA_EXTRA_CLEAR_SELECTION)); - } - mFragment.setArguments(bundle); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_subreddit_selection_activity, mFragment).commit(); - } - } - - private void loadSubscriptions() { - if (!mInsertSuccess) { - FetchSubscribedThing.fetchSubscribedThing(mOauthRetrofit, mAccessToken, mAccountName, null, - new ArrayList<>(), new ArrayList<>(), - new ArrayList<>(), - new FetchSubscribedThing.FetchSubscribedThingListener() { - @Override - public void onFetchSubscribedThingSuccess(ArrayList subscribedSubredditData, - ArrayList subscribedUserData, - ArrayList subredditData) { - new InsertSubscribedThingsAsyncTask( - mRedditDataRoomDatabase, - mAccountName, - subscribedSubredditData, - subscribedUserData, - subredditData, - () -> mInsertSuccess = true).execute(); - } - - @Override - public void onFetchSubscribedThingFail() { - mInsertSuccess = false; - } - }); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.subreddit_selection_activity, menu); - applyMenuItemTheme(menu); - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_search_subreddit_selection_activity: - Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, true); - startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); - return true; - } - - return false; - } - - public void getSelectedSubreddit(String name, String iconUrl, boolean subredditIsUser) { - Intent returnIntent = new Intent(); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_IS_USER, subredditIsUser); - setResult(Activity.RESULT_OK, returnIntent); - finish(); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - String name = data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_NAME); - String iconUrl = data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); - Intent returnIntent = new Intent(); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); - returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_IS_USER, false); - setResult(Activity.RESULT_OK, returnIntent); - finish(); - } - } - super.onActivityResult(requestCode, resultCode, data); - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); - outState.putBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE, mInsertSuccess); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putString(ACCOUNT_PROFILE_IMAGE_URL, mAccountProfileImageUrl); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Override - public void onLongPress() { - if (mFragment != null) { - ((SubscribedSubredditsListingFragment) mFragment).goBackToTop(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubscribedThingListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubscribedThingListingActivity.java deleted file mode 100644 index 204baf7b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SubscribedThingListingActivity.java +++ /dev/null @@ -1,472 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentPagerAdapter; -import androidx.viewpager.widget.ViewPager; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.tabs.TabLayout; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertMultiRedditAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertSubscribedThingsAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.GoBackToMainPageEvent; -import ml.docilealligator.infinityforreddit.Event.RefreshMultiRedditsEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.FetchSubscribedThing; -import ml.docilealligator.infinityforreddit.Fragment.FollowedUsersListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.MultiRedditListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.SubscribedSubredditsListingFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.MultiReddit.DeleteMultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.FetchMyMultiReddits; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiReddit; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class SubscribedThingListingActivity extends BaseActivity implements ActivityToolbarInterface { - - public static final String EXTRA_SHOW_MULTIREDDITS = "ESM"; - private static final String INSERT_SUBSCRIBED_SUBREDDIT_STATE = "ISSS"; - private static final String INSERT_MULTIREDDIT_STATE = "IMS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - - @BindView(R.id.coordinator_layout_subscribed_thing_listing_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_subscribed_thing_listing_activity) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_subscribed_thing_listing_activity) - Toolbar toolbar; - @BindView(R.id.tab_layout_subscribed_thing_listing_activity) - TabLayout tabLayout; - @BindView(R.id.view_pager_subscribed_thing_listing_activity) - ViewPager viewPager; - @BindView(R.id.fab_subscribed_thing_listing_activity) - public FloatingActionButton fab; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private SlidrInterface mSlidrInterface; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private boolean mInsertSuccess = false; - private boolean mInsertMultiredditSuccess = false; - private boolean showMultiReddits = false; - private SectionsPagerAdapter sectionsPagerAdapter; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_subscribed_thing_listing); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - - int navBarHeight = getNavBarHeight(); - if (navBarHeight > 0) { - CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); - params.bottomMargin = navBarHeight; - fab.setLayoutParams(params); - } - } - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - if (savedInstanceState != null) { - mInsertSuccess = savedInstanceState.getBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE); - mInsertMultiredditSuccess = savedInstanceState.getBoolean(INSERT_MULTIREDDIT_STATE); - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndInitializeViewPager(); - } else { - initializeViewPagerAndLoadSubscriptions(); - } - } else { - showMultiReddits = getIntent().getBooleanExtra(EXTRA_SHOW_MULTIREDDITS, false); - getCurrentAccountAndInitializeViewPager(); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - applyTabLayoutTheme(tabLayout); - applyFABTheme(fab); - } - - private void getCurrentAccountAndInitializeViewPager() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - initializeViewPagerAndLoadSubscriptions(); - }).execute(); - } - - private void initializeViewPagerAndLoadSubscriptions() { - fab.setOnClickListener(view -> { - Intent intent = new Intent(this, CreateMultiRedditActivity.class); - startActivity(intent); - }); - sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.setAdapter(sectionsPagerAdapter); - viewPager.setOffscreenPageLimit(3); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - if (position == 0) { - unlockSwipeRightToGoBack(); - fab.hide(); - } else { - lockSwipeRightToGoBack(); - if (position == 1) { - fab.hide(); - } else { - fab.show(); - } - } - } - }); - tabLayout.setupWithViewPager(viewPager); - - if (showMultiReddits) { - viewPager.setCurrentItem(2); - } - - loadSubscriptions(false); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE, mInsertSuccess); - outState.putBoolean(INSERT_MULTIREDDIT_STATE, mInsertMultiredditSuccess); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - public void loadSubscriptions(boolean forceLoad) { - if (!(!forceLoad && mInsertSuccess)) { - FetchSubscribedThing.fetchSubscribedThing(mOauthRetrofit, mAccessToken, mAccountName, null, - new ArrayList<>(), new ArrayList<>(), - new ArrayList<>(), - new FetchSubscribedThing.FetchSubscribedThingListener() { - @Override - public void onFetchSubscribedThingSuccess(ArrayList subscribedSubredditData, - ArrayList subscribedUserData, - ArrayList subredditData) { - new InsertSubscribedThingsAsyncTask( - mRedditDataRoomDatabase, - mAccountName, - subscribedSubredditData, - subscribedUserData, - subredditData, - () -> { - mInsertSuccess = true; - sectionsPagerAdapter.stopRefreshProgressbar(); - }).execute(); - } - - @Override - public void onFetchSubscribedThingFail() { - mInsertSuccess = false; - sectionsPagerAdapter.stopRefreshProgressbar(); - Toast.makeText(SubscribedThingListingActivity.this, - R.string.error_loading_subscriptions, Toast.LENGTH_SHORT).show(); - } - }); - } - - if (!(!forceLoad && mInsertMultiredditSuccess)) { - loadMultiReddits(); - } - } - - private void loadMultiReddits() { - FetchMyMultiReddits.fetchMyMultiReddits(mOauthRetrofit, mAccessToken, new FetchMyMultiReddits.FetchMyMultiRedditsListener() { - @Override - public void success(ArrayList multiReddits) { - new InsertMultiRedditAsyncTask(mRedditDataRoomDatabase, multiReddits, mAccountName, () -> { - mInsertMultiredditSuccess = true; - sectionsPagerAdapter.stopMultiRedditRefreshProgressbar(); - }).execute(); - } - - @Override - public void failed() { - mInsertMultiredditSuccess = false; - sectionsPagerAdapter.stopMultiRedditRefreshProgressbar(); - Toast.makeText(SubscribedThingListingActivity.this, R.string.error_loading_multi_reddit_list, Toast.LENGTH_SHORT).show(); - } - }); - } - - public void deleteMultiReddit(MultiReddit multiReddit) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.delete) - .setMessage(R.string.delete_multi_reddit_dialog_message) - .setPositiveButton(R.string.delete, (dialogInterface, i) - -> DeleteMultiReddit.deleteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, - mAccessToken, mAccountName, multiReddit.getPath(), new DeleteMultiReddit.DeleteMultiRedditListener() { - @Override - public void success() { - Toast.makeText(SubscribedThingListingActivity.this, - R.string.delete_multi_reddit_success, Toast.LENGTH_SHORT).show(); - loadMultiReddits(); - } - - @Override - public void failed() { - Toast.makeText(SubscribedThingListingActivity.this, - R.string.delete_multi_reddit_failed, Toast.LENGTH_SHORT).show(); - } - })) - .setNegativeButton(R.string.cancel, null) - .show(); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - finish(); - } - - @Subscribe - public void goBackToMainPageEvent(GoBackToMainPageEvent event) { - finish(); - } - - @Subscribe - public void onRefreshMultiRedditsEvent(RefreshMultiRedditsEvent event) { - loadMultiReddits(); - } - - @Override - public void onLongPress() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.goBackToTop(); - } - } - - private void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - private void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } - - private class SectionsPagerAdapter extends FragmentPagerAdapter { - - private SubscribedSubredditsListingFragment subscribedSubredditsListingFragment; - private FollowedUsersListingFragment followedUsersListingFragment; - private MultiRedditListingFragment multiRedditListingFragment; - - public SectionsPagerAdapter(FragmentManager fm) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - } - - @NonNull - @Override - public Fragment getItem(int position) { - switch (position) { - case 0: { - SubscribedSubredditsListingFragment fragment = new SubscribedSubredditsListingFragment(); - Bundle bundle = new Bundle(); - bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, false); - bundle.putString(SubscribedSubredditsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } - case 1: { - FollowedUsersListingFragment fragment = new FollowedUsersListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(FollowedUsersListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - bundle.putString(FollowedUsersListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - fragment.setArguments(bundle); - return fragment; - } - default: { - MultiRedditListingFragment fragment = new MultiRedditListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(MultiRedditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(MultiRedditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } - } - } - - @Override - public int getCount() { - return 3; - } - - @Override - public CharSequence getPageTitle(int position) { - switch (position) { - case 0: - return getString(R.string.subreddits); - case 1: - return getString(R.string.users); - case 2: - return getString(R.string.multi_reddits); - } - - return null; - } - - @NonNull - @Override - public Object instantiateItem(@NonNull ViewGroup container, int position) { - Fragment fragment = (Fragment) super.instantiateItem(container, position); - if (position == 0) { - subscribedSubredditsListingFragment = (SubscribedSubredditsListingFragment) fragment; - } else if (position == 1) { - followedUsersListingFragment = (FollowedUsersListingFragment) fragment; - } else { - multiRedditListingFragment = (MultiRedditListingFragment) fragment; - } - - return fragment; - } - - void stopRefreshProgressbar() { - if (subscribedSubredditsListingFragment != null) { - ((FragmentCommunicator) subscribedSubredditsListingFragment).stopRefreshProgressbar(); - } - if (followedUsersListingFragment != null) { - ((FragmentCommunicator) followedUsersListingFragment).stopRefreshProgressbar(); - } - } - - void stopMultiRedditRefreshProgressbar() { - if (multiRedditListingFragment != null) { - ((FragmentCommunicator) multiRedditListingFragment).stopRefreshProgressbar(); - } - } - - void goBackToTop() { - if (viewPager.getCurrentItem() == 0) { - subscribedSubredditsListingFragment.goBackToTop(); - } else if (viewPager.getCurrentItem() == 1) { - followedUsersListingFragment.goBackToTop(); - } else { - multiRedditListingFragment.goBackToTop(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageOrGifActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageOrGifActivity.java deleted file mode 100644 index f580ff16..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImageOrGifActivity.java +++ /dev/null @@ -1,492 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.Manifest; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.text.Html; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import androidx.core.content.FileProvider; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.load.resource.gif.GifDrawable; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.CustomTarget; -import com.bumptech.glide.request.target.Target; -import com.bumptech.glide.request.transition.Transition; -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; -import com.github.piasy.biv.BigImageViewer; -import com.github.piasy.biv.loader.ImageLoader; -import com.github.piasy.biv.loader.glide.GlideImageLoader; -import com.github.piasy.biv.view.BigImageView; -import com.github.piasy.biv.view.GlideImageViewFactory; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrConfig; -import com.r0adkll.slidr.model.SlidrPosition; - -import java.io.File; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.AsyncTask.SaveBitmapImageToFileAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SaveGIFToFileAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SetAsWallpaperBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BuildConfig; -import ml.docilealligator.infinityforreddit.Font.ContentFontFamily; -import ml.docilealligator.infinityforreddit.Font.ContentFontStyle; -import ml.docilealligator.infinityforreddit.Font.FontFamily; -import ml.docilealligator.infinityforreddit.Font.FontStyle; -import ml.docilealligator.infinityforreddit.Font.TitleFontFamily; -import ml.docilealligator.infinityforreddit.Font.TitleFontStyle; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Service.DownloadMediaService; -import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.WallpaperSetter; - -public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWallpaperCallback { - - public static final String EXTRA_IMAGE_URL_KEY = "EIUK"; - public static final String EXTRA_GIF_URL_KEY = "EGUK"; - public static final String EXTRA_FILE_NAME_KEY = "EFNK"; - public static final String EXTRA_SUBREDDIT_OR_USERNAME_KEY = "ESOUK"; - public static final String EXTRA_POST_TITLE_KEY = "EPTK"; - private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; - @BindView(R.id.progress_bar_view_image_or_gif_activity) - ProgressBar mProgressBar; - @BindView(R.id.image_view_view_image_or_gif_activity) - BigImageView mImageView; - @BindView(R.id.load_image_error_linear_layout_view_image_or_gif_activity) - LinearLayout mLoadErrorLinearLayout; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - private boolean isActionBarHidden = false; - private boolean isDownloading = false; - private RequestManager glide; - private String mImageUrl; - private String mImageFileName; - private String mSubredditName; - private boolean isGif = true; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - ((Infinity) getApplication()).getAppComponent().inject(this); - - getTheme().applyStyle(R.style.Theme_Normal, true); - - getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(TitleFontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); - - BigImageViewer.initialize(GlideImageLoader.with(this)); - - setContentView(R.layout.activity_view_image_or_gif); - - ButterKnife.bind(this); - - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); - - Slidr.attach(this, new SlidrConfig.Builder().position(SlidrPosition.VERTICAL).distanceThreshold(0.125f).build()); - - glide = Glide.with(this); - - Intent intent = getIntent(); - mImageUrl = intent.getStringExtra(EXTRA_GIF_URL_KEY); - if (mImageUrl == null) { - isGif = false; - mImageUrl = intent.getStringExtra(EXTRA_IMAGE_URL_KEY); - } - mImageFileName = intent.getStringExtra(EXTRA_FILE_NAME_KEY); - String postTitle = intent.getStringExtra(EXTRA_POST_TITLE_KEY); - mSubredditName = intent.getStringExtra(EXTRA_SUBREDDIT_OR_USERNAME_KEY); - - if (postTitle != null) { - setTitle(Html.fromHtml(String.format("%s", postTitle))); - } else { - setTitle(""); - } - - mLoadErrorLinearLayout.setOnClickListener(view -> { - mProgressBar.setVisibility(View.VISIBLE); - mLoadErrorLinearLayout.setVisibility(View.GONE); - loadImage(); - }); - - mImageView.setOnClickListener(view -> { - if (isActionBarHidden) { - getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - isActionBarHidden = false; - } else { - getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE); - isActionBarHidden = true; - } - }); - - mImageView.setImageViewFactory(new GlideImageViewFactory()); - - mImageView.setImageLoaderCallback(new ImageLoader.Callback() { - @Override - public void onCacheHit(int imageType, File image) { - - } - - @Override - public void onCacheMiss(int imageType, File image) { - - } - - @Override - public void onStart() { - - } - - @Override - public void onProgress(int progress) { - - } - - @Override - public void onFinish() { - - } - - @Override - public void onSuccess(File image) { - mProgressBar.setVisibility(View.GONE); - - final SubsamplingScaleImageView view = mImageView.getSSIV(); - - if (view != null) { - view.setMinimumDpi(80); - - view.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() { - @Override - public void onReady() { - - } - - @Override - public void onImageLoaded() { - view.setDoubleTapZoomDpi(70); - view.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); - view.setQuickScaleEnabled(true); - } - - @Override - public void onPreviewLoadError(Exception e) { - - } - - @Override - public void onImageLoadError(Exception e) { - - } - - @Override - public void onTileLoadError(Exception e) { - - } - - @Override - public void onPreviewReleased() { - - } - }); - } - } - - @Override - public void onFail(Exception error) { - mProgressBar.setVisibility(View.GONE); - mLoadErrorLinearLayout.setVisibility(View.VISIBLE); - } - }); - - loadImage(); - } - - private void loadImage() { - mImageView.showImage(Uri.parse(mImageUrl)); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.view_image_or_gif_activity, menu); - if (!isGif) - menu.findItem(R.id.action_set_wallpaper_view_image_or_gif_activity).setVisible(true); - return true; - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_download_view_image_or_gif_activity: - if (isDownloading) { - return false; - } - - isDownloading = true; - - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(this, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - - return true; - case R.id.action_share_view_image_or_gif_activity: - if (isGif) - shareGif(); - else - shareImage(); - return true; - case R.id.action_set_wallpaper_view_image_or_gif_activity: - if (!isGif) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); - setAsWallpaperBottomSheetFragment.show(getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); - } else { - WallpaperSetter.set(mImageUrl, WallpaperSetter.BOTH_SCREENS, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } - return true; - } - - return false; - } - - private void download() { - isDownloading = false; - - Intent intent = new Intent(this, DownloadMediaService.class); - intent.putExtra(DownloadMediaService.EXTRA_URL, mImageUrl); - intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, isGif ? DownloadMediaService.EXTRA_MEDIA_TYPE_GIF : DownloadMediaService.EXTRA_MEDIA_TYPE_IMAGE); - intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, mImageFileName); - intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, mSubredditName); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(intent); - } else { - startService(intent); - } - Toast.makeText(this, R.string.download_started, Toast.LENGTH_SHORT).show(); - } - - private void shareImage() { - glide.asBitmap().load(mImageUrl).into(new CustomTarget() { - - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - if (getExternalCacheDir() != null) { - Toast.makeText(ViewImageOrGifActivity.this, R.string.save_image_first, Toast.LENGTH_SHORT).show(); - new SaveBitmapImageToFileAsyncTask(resource, getExternalCacheDir().getPath(), mImageFileName, - new SaveBitmapImageToFileAsyncTask.SaveBitmapImageToFileAsyncTaskListener() { - @Override - public void saveSuccess(File imageFile) { - Uri uri = FileProvider.getUriForFile(ViewImageOrGifActivity.this, - BuildConfig.APPLICATION_ID + ".provider", imageFile); - Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, uri); - shareIntent.setType("image/*"); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } - - @Override - public void saveFailed() { - Toast.makeText(ViewImageOrGifActivity.this, - R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); - } - }).execute(); - } else { - Toast.makeText(ViewImageOrGifActivity.this, - R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - } - - private void shareGif() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.save_gif_first, Toast.LENGTH_SHORT).show(); - glide.asGif().load(mImageUrl).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - return false; - } - - @Override - public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - if (getExternalCacheDir() != null) { - new SaveGIFToFileAsyncTask(resource, getExternalCacheDir().getPath(), mImageFileName, - new SaveGIFToFileAsyncTask.SaveGIFToFileAsyncTaskListener() { - @Override - public void saveSuccess(File imageFile) { - Uri uri = FileProvider.getUriForFile(ViewImageOrGifActivity.this, - BuildConfig.APPLICATION_ID + ".provider", imageFile); - Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, uri); - shareIntent.setType("image/*"); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } - - @Override - public void saveFailed() { - Toast.makeText(ViewImageOrGifActivity.this, - R.string.cannot_save_gif, Toast.LENGTH_SHORT).show(); - } - }).execute(); - } else { - Toast.makeText(ViewImageOrGifActivity.this, - R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); - } - return false; - } - }).submit(); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); - isDownloading = false; - } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { - download(); - } - } - } - - @Override - public void setToHomeScreen(int viewPagerPosition) { - WallpaperSetter.set(mImageUrl, WallpaperSetter.HOME_SCREEN, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - - @Override - public void setToLockScreen(int viewPagerPosition) { - WallpaperSetter.set(mImageUrl, WallpaperSetter.LOCK_SCREEN, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - - @Override - public void setToBoth(int viewPagerPosition) { - WallpaperSetter.set(mImageUrl, WallpaperSetter.BOTH_SCREENS, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java deleted file mode 100644 index 5beb5cfd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewImgurMediaActivity.java +++ /dev/null @@ -1,495 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.os.AsyncTask; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.viewpager.widget.ViewPager; - -import com.thefuntasty.hauler.DragDirection; -import com.thefuntasty.hauler.HaulerView; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.API.ImgurAPI; -import ml.docilealligator.infinityforreddit.Font.ContentFontFamily; -import ml.docilealligator.infinityforreddit.Font.ContentFontStyle; -import ml.docilealligator.infinityforreddit.Font.FontFamily; -import ml.docilealligator.infinityforreddit.Font.FontStyle; -import ml.docilealligator.infinityforreddit.Font.TitleFontFamily; -import ml.docilealligator.infinityforreddit.Font.TitleFontStyle; -import ml.docilealligator.infinityforreddit.Fragment.ViewImgurImageFragment; -import ml.docilealligator.infinityforreddit.Fragment.ViewImgurVideoFragment; -import ml.docilealligator.infinityforreddit.ImgurMedia; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.WallpaperSetter; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWallpaperCallback { - - public static final String EXTRA_IMGUR_TYPE = "EIT"; - public static final String EXTRA_IMGUR_ID = "EII"; - public static final int IMGUR_TYPE_GALLERY = 0; - public static final int IMGUR_TYPE_ALBUM = 1; - public static final int IMGUR_TYPE_IMAGE = 2; - private static final String IMGUR_IMAGES_STATE = "IIS"; - - @BindView(R.id.hauler_view_view_imgur_media_activity) - HaulerView haulerView; - @BindView(R.id.progress_bar_view_imgur_media_activity) - ProgressBar progressBar; - @BindView(R.id.view_pager_view_imgur_media_activity) - ViewPager viewPager; - @BindView(R.id.load_image_error_linear_layout_view_imgur_media_activity) - LinearLayout errorLinearLayout; - private SectionsPagerAdapter sectionsPagerAdapter; - private ArrayList images; - @Inject - @Named("imgur") - Retrofit imgurRetrofit; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - ((Infinity) getApplication()).getAppComponent().inject(this); - - getTheme().applyStyle(R.style.Theme_Normal, true); - - getTheme().applyStyle(FontStyle.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(TitleFontStyle.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(ContentFontStyle.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(FontFamily.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(TitleFontFamily.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(ContentFontFamily.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); - - setContentView(R.layout.activity_view_imgur_media); - - ButterKnife.bind(this); - - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); - - setTitle(" "); - - String imgurId = getIntent().getStringExtra(EXTRA_IMGUR_ID); - if (imgurId == null) { - finish(); - return; - } - - if (savedInstanceState != null) { - images = savedInstanceState.getParcelableArrayList(IMGUR_IMAGES_STATE); - } - - haulerView.setOnDragDismissedListener(dragDirection -> { - int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; - finish(); - overridePendingTransition(0, slide); - }); - - if (images == null) { - fetchImgurMedia(imgurId); - } else { - progressBar.setVisibility(View.GONE); - setupViewPager(); - } - - errorLinearLayout.setOnClickListener(view -> fetchImgurMedia(imgurId)); - } - - private void fetchImgurMedia(String imgurId) { - errorLinearLayout.setVisibility(View.GONE); - progressBar.setVisibility(View.VISIBLE); - switch (getIntent().getIntExtra(EXTRA_IMGUR_TYPE, IMGUR_TYPE_IMAGE)) { - case IMGUR_TYPE_GALLERY: - imgurRetrofit.create(ImgurAPI.class).getGalleryImages(APIUtils.IMGUR_CLIENT_ID, imgurId) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseImgurImagesAsyncTask(response.body(), new ParseImgurImagesAsyncTask.ParseImgurImagesAsyncTaskListener() { - @Override - public void success(ArrayList images) { - ViewImgurMediaActivity.this.images = images; - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.GONE); - setupViewPager(); - } - - @Override - public void failed() { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - }).execute(); - } else { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - }); - break; - case IMGUR_TYPE_ALBUM: - imgurRetrofit.create(ImgurAPI.class).getAlbumImages(APIUtils.IMGUR_CLIENT_ID, imgurId) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseImgurImagesAsyncTask(response.body(), new ParseImgurImagesAsyncTask.ParseImgurImagesAsyncTaskListener() { - @Override - public void success(ArrayList images) { - ViewImgurMediaActivity.this.images = images; - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.GONE); - setupViewPager(); - } - - @Override - public void failed() { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - }).execute(); - } else { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - }); - break; - case IMGUR_TYPE_IMAGE: - imgurRetrofit.create(ImgurAPI.class).getImage(APIUtils.IMGUR_CLIENT_ID, imgurId) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseImgurImageAsyncTask(response.body(), new ParseImgurImageAsyncTask.ParseImgurImageAsyncTaskListener() { - @Override - public void success(ImgurMedia image) { - ViewImgurMediaActivity.this.images = new ArrayList<>(); - ViewImgurMediaActivity.this.images.add(image); - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.GONE); - setupViewPager(); - } - - @Override - public void failed() { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - }).execute(); - } else { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - }); - break; - } - } - - private void setupViewPager() { - setToolbarTitle(0); - sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - setToolbarTitle(position); - } - }); - viewPager.setAdapter(sectionsPagerAdapter); - } - - private void setToolbarTitle(int position) { - if (images != null && position >= 0 && position < images.size()) { - if (images.get(position).getType() == ImgurMedia.TYPE_VIDEO) { - setTitle(getString(R.string.view_imgur_media_activity_video_label, position + 1, images.size())); - } else { - setTitle(getString(R.string.view_imgur_media_activity_image_label, position + 1, images.size())); - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putParcelableArrayList(IMGUR_IMAGES_STATE, images); - } - - @Override - public void setToHomeScreen(int viewPagerPosition) { - if (images != null && viewPagerPosition >= 0 && viewPagerPosition < images.size()) { - WallpaperSetter.set(images.get(viewPagerPosition).getLink(), WallpaperSetter.HOME_SCREEN, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImgurMediaActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImgurMediaActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } - - @Override - public void setToLockScreen(int viewPagerPosition) { - if (images != null && viewPagerPosition >= 0 && viewPagerPosition < images.size()) { - WallpaperSetter.set(images.get(viewPagerPosition).getLink(), WallpaperSetter.LOCK_SCREEN, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImgurMediaActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImgurMediaActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } - - @Override - public void setToBoth(int viewPagerPosition) { - if (images != null && viewPagerPosition >= 0 && viewPagerPosition < images.size()) { - WallpaperSetter.set(images.get(viewPagerPosition).getLink(), WallpaperSetter.BOTH_SCREENS, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewImgurMediaActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewImgurMediaActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } - - public int getCurrentPagePosition() { - return viewPager.getCurrentItem(); - } - - private class SectionsPagerAdapter extends FragmentStatePagerAdapter { - - SectionsPagerAdapter(@NonNull FragmentManager fm) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - } - - @NonNull - @Override - public Fragment getItem(int position) { - ImgurMedia imgurMedia = images.get(position); - if (imgurMedia.getType() == ImgurMedia.TYPE_VIDEO) { - ViewImgurVideoFragment fragment = new ViewImgurVideoFragment(); - Bundle bundle = new Bundle(); - bundle.putParcelable(ViewImgurVideoFragment.EXTRA_IMGUR_VIDEO, imgurMedia); - fragment.setArguments(bundle); - return fragment; - } else { - ViewImgurImageFragment fragment = new ViewImgurImageFragment(); - Bundle bundle = new Bundle(); - bundle.putParcelable(ViewImgurImageFragment.EXTRA_IMGUR_IMAGES, imgurMedia); - fragment.setArguments(bundle); - return fragment; - } - } - - @Override - public int getCount() { - return images.size(); - } - } - - private static class ParseImgurImagesAsyncTask extends AsyncTask { - - private String response; - private ArrayList images; - private boolean parseFailed = false; - private ParseImgurImagesAsyncTaskListener parseImgurImagesAsyncTaskListener; - - interface ParseImgurImagesAsyncTaskListener { - void success(ArrayList images); - - void failed(); - } - - ParseImgurImagesAsyncTask(String response, ParseImgurImagesAsyncTaskListener parseImgurImagesAsyncTaskListener) { - this.response = response; - this.parseImgurImagesAsyncTaskListener = parseImgurImagesAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONArray jsonArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.IMAGES_KEY); - images = new ArrayList<>(); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject image = jsonArray.getJSONObject(i); - String type = image.getString(JSONUtils.TYPE_KEY); - if (type.contains("gif")) { - images.add(new ImgurMedia(image.getString(JSONUtils.ID_KEY), - image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), - "video/mp4", image.getString(JSONUtils.MP4_KEY))); - } else { - images.add(new ImgurMedia(image.getString(JSONUtils.ID_KEY), - image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), - type, image.getString(JSONUtils.LINK_KEY))); - } - } - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - parseImgurImagesAsyncTaskListener.failed(); - } else { - parseImgurImagesAsyncTaskListener.success(images); - } - } - } - - private static class ParseImgurImageAsyncTask extends AsyncTask { - - private String response; - private ImgurMedia image; - private boolean parseFailed = false; - private ParseImgurImageAsyncTaskListener parseImgurImageAsyncTaskListener; - - interface ParseImgurImageAsyncTaskListener { - void success(ImgurMedia image); - - void failed(); - } - - ParseImgurImageAsyncTask(String response, ParseImgurImageAsyncTaskListener parseImgurImageAsyncTaskListener) { - this.response = response; - this.parseImgurImageAsyncTaskListener = parseImgurImageAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject image = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY); - String type = image.getString(JSONUtils.TYPE_KEY); - if (type.contains("gif")) { - this.image = new ImgurMedia(image.getString(JSONUtils.ID_KEY), - image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), - "video/mp4", image.getString(JSONUtils.MP4_KEY)); - } else { - this.image = new ImgurMedia(image.getString(JSONUtils.ID_KEY), - image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), - type, image.getString(JSONUtils.LINK_KEY)); - } - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - parseImgurImageAsyncTaskListener.failed(); - } else { - parseImgurImageAsyncTaskListener.success(image); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewMultiRedditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewMultiRedditDetailActivity.java deleted file mode 100644 index 1af66861..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewMultiRedditDetailActivity.java +++ /dev/null @@ -1,364 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.Window; -import android.view.WindowManager; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.r0adkll.slidr.Slidr; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTimeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.RefreshMultiRedditsEvent; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.MultiReddit.DeleteMultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiReddit; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Retrofit; - -public class ViewMultiRedditDetailActivity extends BaseActivity implements SortTypeSelectionCallback, - PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { - - public static final String EXTRA_MULTIREDDIT_DATA = "EMD"; - public static final String EXTRA_MULTIREDDIT_PATH = "EMP"; - - private static final String FRAGMENT_OUT_STATE_KEY = "FOSK"; - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - - @BindView(R.id.coordinator_layout_view_multi_reddit_detail_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.appbar_layout_view_multi_reddit_detail_activity) - AppBarLayout appBarLayout; - @BindView(R.id.collapsing_toolbar_layout_view_multi_reddit_detail_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.toolbar_view_multi_reddit_detail_activity) - Toolbar toolbar; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String multiPath; - private boolean isInLazyMode = false; - private Fragment mFragment; - private Menu mMenu; - private AppBarLayout.LayoutParams params; - private SortTypeBottomSheetFragment sortTypeBottomSheetFragment; - private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_view_multi_reddit_detail); - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(appBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(toolbar); - } - } - - MultiReddit multiReddit = getIntent().getParcelableExtra(EXTRA_MULTIREDDIT_DATA); - if (multiReddit == null) { - multiPath = getIntent().getStringExtra(EXTRA_MULTIREDDIT_PATH); - if (multiPath != null) { - toolbar.setTitle(multiPath.substring(multiPath.lastIndexOf("/", multiPath.length() - 2) + 1)); - } else { - Toast.makeText(this, R.string.error_getting_multi_reddit_data, Toast.LENGTH_SHORT).show(); - finish(); - return; - } - } else { - multiPath = multiReddit.getPath(); - toolbar.setTitle(multiReddit.getDisplayName()); - } - - setSupportActionBar(toolbar); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - setToolbarGoToTop(toolbar); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - - mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE_KEY); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_view_multi_reddit_detail_activity, mFragment).commit(); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndInitializeFragment(); - } - } else { - getCurrentAccountAndInitializeFragment(); - } - - sortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle bottomSheetBundle = new Bundle(); - bottomSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - sortTypeBottomSheetFragment.setArguments(bottomSheetBundle); - - sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); - - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - - params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - } - - private void getCurrentAccountAndInitializeFragment() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - initializeFragment(); - }).execute(); - } - - private void initializeFragment() { - mFragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putString(PostFragment.EXTRA_NAME, multiPath); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_MULTI_REDDIT); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - mFragment.setArguments(bundle); - getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_view_multi_reddit_detail_activity, mFragment).commit(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.view_multi_reddit_detail_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_multi_reddit_detail_activity); - if (isInLazyMode) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } else { - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_sort_view_multi_reddit_detail_activity: - sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); - return true; - case R.id.action_search_view_multi_reddit_detail_activity: - Intent intent = new Intent(this, SearchActivity.class); - startActivity(intent); - return true; - case R.id.action_refresh_view_multi_reddit_detail_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_view_multi_reddit_detail_activity).setTitle(R.string.action_start_lazy_mode); - } - if (mFragment instanceof FragmentCommunicator) { - ((FragmentCommunicator) mFragment).refresh(); - } - return true; - case R.id.action_lazy_mode_view_multi_reddit_detail_activity: - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_multi_reddit_detail_activity); - if (isInLazyMode) { - isInLazyMode = false; - ((FragmentCommunicator) mFragment).stopLazyMode(); - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = true; - if (((FragmentCommunicator) mFragment).startLazyMode()) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - appBarLayout.setExpanded(false); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = false; - } - } - return true; - case R.id.action_change_post_layout_view_multi_reddit_detail_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - case R.id.action_edit_view_multi_reddit_detail_activity: - Intent editIntent = new Intent(this, EditMultiRedditActivity.class); - editIntent.putExtra(EditMultiRedditActivity.EXTRA_MULTI_PATH, multiPath); - startActivity(editIntent); - return true; - case R.id.action_delete_view_multi_reddit_detail_activity: - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.delete) - .setMessage(R.string.delete_multi_reddit_dialog_message) - .setPositiveButton(R.string.delete, (dialogInterface, i) - -> DeleteMultiReddit.deleteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, - mAccessToken, mAccountName, multiPath, new DeleteMultiReddit.DeleteMultiRedditListener() { - @Override - public void success() { - Toast.makeText(ViewMultiRedditDetailActivity.this, - R.string.delete_multi_reddit_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new RefreshMultiRedditsEvent()); - finish(); - } - - @Override - public void failed() { - Toast.makeText(ViewMultiRedditDetailActivity.this, - R.string.delete_multi_reddit_failed, Toast.LENGTH_SHORT).show(); - } - })) - .setNegativeButton(R.string.cancel, null) - .show(); - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE_KEY, mFragment); - } - - @Override - public void sortTypeSelected(SortType sortType) { - ((PostFragment) mFragment).changeSortType(sortType); - displaySortType(); - } - - @Override - public void sortTypeSelected(String sortType) { - Bundle bundle = new Bundle(); - bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); - sortTimeBottomSheetFragment.setArguments(bundle); - sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); - } - - @Override - public void postLayoutSelected(int postLayout) { - if (mFragment != null) { - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + multiPath, postLayout).apply(); - ((FragmentCommunicator) mFragment).changePostLayout(postLayout); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - } - - @Override - public void onLongPress() { - if (mFragment != null) { - ((PostFragment) mFragment).goBackToTop(); - } - } - - @Override - public void displaySortType() { - if (mFragment != null) { - SortType sortType = ((PostFragment) mFragment).getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java deleted file mode 100644 index c2951c14..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPostDetailActivity.java +++ /dev/null @@ -1,1856 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Bundle; -import android.util.DisplayMetrics; -import android.view.HapticFeedbackConstants; -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 android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.core.content.res.ResourcesCompat; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.LinearSmoothScroller; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import androidx.transition.AutoTransition; -import androidx.transition.TransitionManager; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.evernote.android.state.State; -import com.github.piasy.biv.BigImageViewer; -import com.github.piasy.biv.loader.glide.GlideImageLoader; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; -import com.livefront.bridge.Bridge; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -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 javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import im.ene.toro.exoplayer.ExoCreator; -import im.ene.toro.media.PlaybackInfo; -import im.ene.toro.media.VolumeInfo; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.Adapter.CommentAndPostRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SwitchAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FlairBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostCommentSortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.Comment.Comment; -import ml.docilealligator.infinityforreddit.Comment.FetchComment; -import ml.docilealligator.infinityforreddit.Comment.FetchRemovedComment; -import ml.docilealligator.infinityforreddit.Comment.ParseComment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.CustomView.CustomToroContainer; -import ml.docilealligator.infinityforreddit.DeleteThing; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWBlurEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeNetworkStatusEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSpoilerBlurEvent; -import ml.docilealligator.infinityforreddit.Event.PostUpdateEventToDetailActivity; -import ml.docilealligator.infinityforreddit.Event.PostUpdateEventToPostList; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.ReadMessage; -import ml.docilealligator.infinityforreddit.Post.FetchPost; -import ml.docilealligator.infinityforreddit.Post.FetchRemovedPost; -import ml.docilealligator.infinityforreddit.Post.HidePost; -import ml.docilealligator.infinityforreddit.Post.ParsePost; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SaveThing; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.Subreddit.FetchSubredditData; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; -import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; -import static ml.docilealligator.infinityforreddit.Activity.CommentActivity.RETURN_EXTRA_COMMENT_DATA_KEY; -import static ml.docilealligator.infinityforreddit.Activity.CommentActivity.WRITE_COMMENT_REQUEST_CODE; - -public class ViewPostDetailActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback, - SortTypeSelectionCallback, ActivityToolbarInterface { - - public static final String EXTRA_POST_DATA = "EPD"; - public static final String EXTRA_POST_LIST_POSITION = "EPLI"; - public static final String EXTRA_POST_ID = "EPI"; - public static final String EXTRA_SINGLE_COMMENT_ID = "ESCI"; - public static final String EXTRA_MESSAGE_FULLNAME = "ENI"; - public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; - public static final int EDIT_COMMENT_REQUEST_CODE = 3; - public static final int GIVE_AWARD_REQUEST_CODE = 100; - private static final int EDIT_POST_REQUEST_CODE = 2; - @State - boolean mNullAccessToken = false; - @State - String mAccessToken; - @State - String mAccountName; - @State - Post mPost; - @State - boolean isLoadingMoreChildren = false; - @State - boolean isRefreshing = false; - @State - boolean isSingleCommentThreadMode = false; - @State - ArrayList comments; - @State - ArrayList children; - @State - int mChildrenStartingIndex = 0; - @State - boolean loadMoreChildrenSuccess = true; - @State - boolean hasMoreChildren; - @State - boolean isFetchingComments = false; - @State - String mMessageFullname; - @State - String mNewAccountName; - @State - String sortType; - @State - boolean mRespectSubredditRecommendedSortType; - @BindView(R.id.coordinator_layout_view_post_detail) - CoordinatorLayout mCoordinatorLayout; - @BindView(R.id.appbar_layout_view_post_detail_activity) - AppBarLayout mAppBarLayout; - @BindView(R.id.toolbar_view_post_detail_activity) - Toolbar mToolbar; - @BindView(R.id.swipe_refresh_layout_view_post_detail_activity) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_view_post_detail) - CustomToroContainer mRecyclerView; - @BindView(R.id.fetch_post_info_linear_layout_view_post_detail_activity) - LinearLayout mFetchPostInfoLinearLayout; - @BindView(R.id.fetch_post_info_image_view_view_post_detail_activity) - ImageView mFetchPostInfoImageView; - @BindView(R.id.fetch_post_info_text_view_view_post_detail_activity) - TextView mFetchPostInfoTextView; - @BindView(R.id.fab_view_post_detail_activity) - FloatingActionButton fab; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("pushshift") - Retrofit pushshiftRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("gfycat") - Retrofit mGfycatRetrofit; - @Inject - @Named("redgifs") - Retrofit mRedgifsRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences mNsfwAndSpoilerSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - @Inject - ExoCreator mExoCreator; - private RequestManager mGlide; - private Locale mLocale; - private Menu mMenu; - private int orientation; - private int postListPosition = -1; - private String mSingleCommentId; - private boolean showToast = false; - private boolean isSortingComments = false; - private boolean mVolumeKeysNavigateComments; - private boolean mIsSmoothScrolling = false; - private boolean mLockFab; - private boolean mSwipeUpToHideFab; - private boolean mExpandChildren; - private int mWindowWidth; - private LinearLayoutManager mLinearLayoutManager; - private CommentAndPostRecyclerViewAdapter mAdapter; - private RecyclerView.SmoothScroller mSmoothScroller; - private PostCommentSortTypeBottomSheetFragment mPostCommentSortTypeBottomSheetFragment; - private SlidrInterface mSlidrInterface; - private Drawable mSavedIcon; - private Drawable mUnsavedIcon; - private ColorDrawable backgroundSwipeRight; - private ColorDrawable backgroundSwipeLeft; - private Drawable drawableSwipeRight; - private Drawable drawableSwipeLeft; - private int swipeLeftAction; - private int swipeRightAction; - private float swipeActionThreshold; - private ItemTouchHelper touchHelper; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - super.onCreate(savedInstanceState); - - BigImageViewer.initialize(GlideImageLoader.with(this)); - - setContentView(R.layout.activity_view_post_detail); - - Bridge.restoreInstanceState(this, savedInstanceState); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - mSavedIcon = getMenuItemIcon(R.drawable.ic_bookmark_toolbar_24dp); - mUnsavedIcon = getMenuItemIcon(R.drawable.ic_bookmark_border_toolbar_24dp); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - - if (isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(mAppBarLayout); - } - - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - mCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - adjustToolbar(mToolbar); - - int navBarHeight = getNavBarHeight(); - if (navBarHeight > 0) { - CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); - params.bottomMargin = navBarHeight; - fab.setLayoutParams(params); - mRecyclerView.setPadding(0, 0, 0, navBarHeight + mRecyclerView.getPaddingBottom()); - showToast = true; - } - } - } - - DisplayMetrics displayMetrics = new DisplayMetrics(); - getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - mWindowWidth = displayMetrics.widthPixels; - - mToolbar.setTitle(""); - setSupportActionBar(mToolbar); - setToolbarGoToTop(mToolbar); - - mVolumeKeysNavigateComments = mSharedPreferences.getBoolean(SharedPreferencesUtils.VOLUME_KEYS_NAVIGATE_COMMENTS, false); - mLockFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON, false); - mSwipeUpToHideFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_UP_TO_HIDE_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON, false); - mExpandChildren = !mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_TOP_LEVEL_COMMENTS_FIRST, false); - if (savedInstanceState == null) { - mRespectSubredditRecommendedSortType = mSharedPreferences.getBoolean(SharedPreferencesUtils.RESPECT_SUBREDDIT_RECOMMENDED_COMMENT_SORT_TYPE, false); - } - - mGlide = Glide.with(this); - Resources resources = getResources(); - mLocale = getResources().getConfiguration().locale; - - mLinearLayoutManager = new LinearLayoutManager(this); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - - if (children != null && children.size() > 0) { - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (!mIsSmoothScrolling && !mLockFab) { - if (!recyclerView.canScrollVertically(1)) { - fab.hide(); - } else { - if (dy > 0) { - if (mSwipeUpToHideFab) { - fab.show(); - } else { - fab.hide(); - } - } else { - if (mSwipeUpToHideFab) { - fab.hide(); - } else { - fab.show(); - } - } - } - } - - if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { - int visibleItemCount = mLinearLayoutManager.getChildCount(); - int totalItemCount = mLinearLayoutManager.getItemCount(); - int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - - if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { - fetchMoreComments(); - } - } - } - - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_IDLE) { - mIsSmoothScrolling = false; - } - } - }); - } else { - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (!mIsSmoothScrolling && !mLockFab) { - if (!recyclerView.canScrollVertically(1)) { - fab.hide(); - } else { - if (dy > 0) { - if (mSwipeUpToHideFab) { - fab.show(); - } else { - fab.hide(); - } - } else { - if (mSwipeUpToHideFab) { - fab.hide(); - } else { - fab.show(); - } - } - } - } - } - - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_IDLE) { - mIsSmoothScrolling = false; - } - } - }); - } - - boolean enableSwipeAction = mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false); - boolean 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 CommentAndPostRecyclerViewAdapter.PostDetailBaseViewHolder) && - !(viewHolder instanceof CommentAndPostRecyclerViewAdapter.CommentViewHolder)) { - return makeMovementFlags(0, 0); - } - int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; - return makeMovementFlags(0, swipeFlags); - } - - @Override - public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { - return false; - } - - @Override - public boolean isItemViewSwipeEnabled() { - return true; - } - - @Override - public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { - if (touchHelper != null) { - touchHelper.attachToRecyclerView(null); - touchHelper.attachToRecyclerView(mRecyclerView); - if (mAdapter != null) { - mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); - } - } - } - - @Override - public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { - super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); - - View itemView = viewHolder.itemView; - int horizontalOffset = (int) Utils.convertDpToPixel(16, ViewPostDetailActivity.this); - if (dX > 0) { - if (dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { - if (!exceedThreshold) { - exceedThreshold = true; - if (vibrateWhenActionTriggered) { - viewHolder.itemView.setHapticFeedbackEnabled(true); - viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } - backgroundSwipeRight.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); - } else { - exceedThreshold = false; - backgroundSwipeRight.setBounds(0, 0, 0, 0); - } - - drawableSwipeRight.setBounds(itemView.getLeft() + ((int) dX) - horizontalOffset - drawableSwipeRight.getIntrinsicWidth(), - (itemView.getBottom() + itemView.getTop() - drawableSwipeRight.getIntrinsicHeight()) / 2, - itemView.getLeft() + ((int) dX) - horizontalOffset, - (itemView.getBottom() + itemView.getTop() + drawableSwipeRight.getIntrinsicHeight()) / 2); - backgroundSwipeRight.draw(c); - drawableSwipeRight.draw(c); - } else if (dX < 0) { - if (-dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { - if (!exceedThreshold) { - exceedThreshold = true; - if (vibrateWhenActionTriggered) { - viewHolder.itemView.setHapticFeedbackEnabled(true); - viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } - backgroundSwipeLeft.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); - } else { - exceedThreshold = false; - backgroundSwipeLeft.setBounds(0, 0, 0, 0); - } - drawableSwipeLeft.setBounds(itemView.getRight() + ((int) dX) + horizontalOffset, - (itemView.getBottom() + itemView.getTop() - drawableSwipeLeft.getIntrinsicHeight()) / 2, - itemView.getRight() + ((int) dX) + horizontalOffset + drawableSwipeLeft.getIntrinsicWidth(), - (itemView.getBottom() + itemView.getTop() + drawableSwipeLeft.getIntrinsicHeight()) / 2); - backgroundSwipeLeft.draw(c); - drawableSwipeLeft.draw(c); - } - } - - @Override - public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { - return swipeActionThreshold; - } - }); - - if (enableSwipeAction) { - touchHelper.attachToRecyclerView(mRecyclerView); - } - - mSwipeRefreshLayout.setOnRefreshListener(() -> refresh(true, true)); - - mSmoothScroller = new LinearSmoothScroller(this) { - @Override - protected int getVerticalSnapPreference() { - return LinearSmoothScroller.SNAP_TO_START; - } - }; - - mSingleCommentId = getIntent().getStringExtra(EXTRA_SINGLE_COMMENT_ID); - if (savedInstanceState == null) { - if (mSingleCommentId != null) { - isSingleCommentThreadMode = true; - } - mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); - mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); - } - - if (savedInstanceState == null) { - if (!mRespectSubredditRecommendedSortType || isSingleCommentThreadMode) { - sortType = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, SortType.Type.BEST.value.toUpperCase()); - if (sortType != null) { - mToolbar.setTitle(new SortType(SortType.Type.valueOf(sortType)).getType().fullName); - sortType = sortType.toLowerCase(); - } - } - } else { - if (sortType != null) { - mToolbar.setTitle(new SortType(SortType.Type.valueOf(sortType.toUpperCase())).getType().fullName); - } - } - - orientation = resources.getConfiguration().orientation; - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - - if (getIntent().hasExtra(EXTRA_POST_LIST_POSITION)) { - postListPosition = getIntent().getIntExtra(EXTRA_POST_LIST_POSITION, -1); - } - - mPostCommentSortTypeBottomSheetFragment = new PostCommentSortTypeBottomSheetFragment(); - } - - private void initializeSwipeActionDrawable() { - if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - backgroundSwipeRight = new ColorDrawable(mCustomThemeWrapper.getDownvoted()); - drawableSwipeRight = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_downward_black_24dp, null); - } else { - backgroundSwipeRight = new ColorDrawable(mCustomThemeWrapper.getUpvoted()); - drawableSwipeRight = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_upward_black_24dp, null); - } - - if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - backgroundSwipeLeft = new ColorDrawable(mCustomThemeWrapper.getUpvoted()); - drawableSwipeLeft = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_upward_black_24dp, null); - } else { - backgroundSwipeLeft = new ColorDrawable(mCustomThemeWrapper.getDownvoted()); - drawableSwipeLeft = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_downward_black_24dp, null); - } - } - - @Override - protected void onResume() { - super.onResume(); - if (mAdapter != null && mRecyclerView != null) { - mRecyclerView.onWindowVisibilityChanged(View.VISIBLE); - } - } - - @Override - protected void onPause() { - super.onPause(); - if (mAdapter != null && mRecyclerView != null) { - mRecyclerView.onWindowVisibilityChanged(View.GONE); - } - } - - @Override - public SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); - mFetchPostInfoTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); - applyFABTheme(fab); - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (mNewAccountName != null) { - if (account == null || !account.getUsername().equals(mNewAccountName)) { - new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { - EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); - Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); - - mNewAccountName = null; - if (newAccount == null) { - mNullAccessToken = true; - } else { - mAccessToken = newAccount.getAccessToken(); - mAccountName = newAccount.getUsername(); - } - - bindView(); - }).execute(); - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - bindView(); - } - } else { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - - bindView(); - } - }).execute(); - } - - private void bindView() { - if (mAccessToken != null && mMessageFullname != null) { - ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { - @Override - public void readSuccess() { - mMessageFullname = null; - } - - @Override - public void readFailed() { - - } - }); - } - - if (mPost == null) { - mPost = getIntent().getParcelableExtra(EXTRA_POST_DATA); - } - - if (mPost == null) { - fetchPostAndCommentsById(getIntent().getStringExtra(EXTRA_POST_ID)); - } else { - setupMenu(); - - mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, - mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, mGlide, - mWindowWidth, mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, - isSingleCommentThreadMode, mSharedPreferences, mNsfwAndSpoilerSharedPreferences, mExoCreator, - new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { - @Override - public void updatePost(Post post) { - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - - @Override - public void retryFetchingComments() { - fetchCommentsRespectRecommendedSort(false); - } - - @Override - public void retryFetchingMoreComments() { - isLoadingMoreChildren = false; - loadMoreChildrenSuccess = true; - - fetchMoreComments(); - } - }); - mRecyclerView.setAdapter(mAdapter); - - if (comments == null) { - fetchCommentsRespectRecommendedSort(false); - } else { - if (isRefreshing) { - isRefreshing = false; - refresh(true, true); - } else if (isFetchingComments) { - fetchCommentsRespectRecommendedSort(false); - } else { - mAdapter.addComments(comments, hasMoreChildren); - if (isLoadingMoreChildren) { - isLoadingMoreChildren = false; - fetchMoreComments(); - } - } - } - } - - mRecyclerView.setCacheManager(mAdapter); - mRecyclerView.setPlayerInitializer(order -> { - VolumeInfo volumeInfo = new VolumeInfo(true, 0f); - return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo); - }); - - fab.setOnClickListener(view -> scrollToNextParentComment()); - } - - private void setupMenu() { - if (mMenu != null) { - MenuItem saveItem = mMenu.findItem(R.id.action_save_view_post_detail_activity); - MenuItem hideItem = mMenu.findItem(R.id.action_hide_view_post_detail_activity); - - mMenu.findItem(R.id.action_comment_view_post_detail_activity).setVisible(true); - mMenu.findItem(R.id.action_sort_view_post_detail_activity).setVisible(true); - - if (mAccessToken != null) { - if (mPost.isSaved()) { - saveItem.setVisible(true); - saveItem.setIcon(mSavedIcon); - } else { - saveItem.setVisible(true); - saveItem.setIcon(mUnsavedIcon); - } - - if (mPost.isHidden()) { - hideItem.setVisible(true); - hideItem.setTitle(R.string.action_unhide_post); - } else { - hideItem.setVisible(true); - hideItem.setTitle(R.string.action_hide_post); - } - } else { - saveItem.setVisible(false); - hideItem.setVisible(false); - } - - if (mPost.getAuthor().equals(mAccountName)) { - if (mPost.getPostType() == Post.TEXT_TYPE) { - mMenu.findItem(R.id.action_edit_view_post_detail_activity).setVisible(true); - } - mMenu.findItem(R.id.action_delete_view_post_detail_activity).setVisible(true); - - MenuItem nsfwItem = mMenu.findItem(R.id.action_nsfw_view_post_detail_activity); - nsfwItem.setVisible(true); - if (mPost.isNSFW()) { - nsfwItem.setTitle(R.string.action_unmark_nsfw); - } else { - nsfwItem.setTitle(R.string.action_mark_nsfw); - } - - MenuItem spoilerItem = mMenu.findItem(R.id.action_spoiler_view_post_detail_activity); - spoilerItem.setVisible(true); - if (mPost.isSpoiler()) { - spoilerItem.setTitle(R.string.action_unmark_spoiler); - } else { - spoilerItem.setTitle(R.string.action_mark_spoiler); - } - - mMenu.findItem(R.id.action_edit_flair_view_post_detail_activity).setVisible(true); - } - - mMenu.findItem(R.id.action_view_crosspost_parent_view_post_detail_activity).setVisible(mPost.getCrosspostParentId() != null); - - if ("[deleted]".equals(mPost.getAuthor()) || - "[deleted]".equals(mPost.getSelfText()) || - "[removed]".equals(mPost.getSelfText()) - ) { - mMenu.findItem(R.id.action_see_removed_view_post_detail_activity).setVisible(true); - } - } - } - - private Drawable getMenuItemIcon(int drawableId) { - Drawable icon = getDrawable(drawableId); - if (icon != null) { - DrawableCompat.setTint(icon, mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); - } - - return icon; - } - - private void fetchPostAndCommentsById(String subredditId) { - mFetchPostInfoLinearLayout.setVisibility(View.GONE); - mSwipeRefreshLayout.setRefreshing(true); - mGlide.clear(mFetchPostInfoImageView); - - Call postAndComments; - if (mAccessToken == null) { - if (isSingleCommentThreadMode && mSingleCommentId != null) { - postAndComments = mRetrofit.create(RedditAPI.class).getPostAndCommentsSingleThreadById( - subredditId, mSingleCommentId, sortType); - } else { - postAndComments = mRetrofit.create(RedditAPI.class).getPostAndCommentsById(subredditId, - sortType); - } - } else { - if (isSingleCommentThreadMode && mSingleCommentId != null) { - postAndComments = mOauthRetrofit.create(RedditAPI.class).getPostAndCommentsSingleThreadByIdOauth(subredditId, - mSingleCommentId, sortType, APIUtils.getOAuthHeader(mAccessToken)); - } else { - postAndComments = mOauthRetrofit.create(RedditAPI.class).getPostAndCommentsByIdOauth(subredditId, - sortType, APIUtils.getOAuthHeader(mAccessToken)); - } - } - postAndComments.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - mSwipeRefreshLayout.setRefreshing(false); - - if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { - @Override - public void onParsePostSuccess(Post post) { - mPost = post; - - setupMenu(); - - mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, - mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, mGlide, - mWindowWidth, mAccessToken, mAccountName, mPost, mLocale, - mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences, - mNsfwAndSpoilerSharedPreferences, mExoCreator, - new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { - @Override - public void updatePost(Post post) { - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - - @Override - public void retryFetchingComments() { - fetchCommentsRespectRecommendedSort(false); - } - - @Override - public void retryFetchingMoreComments() { - isLoadingMoreChildren = false; - loadMoreChildrenSuccess = true; - - fetchMoreComments(); - } - }); - mRecyclerView.setAdapter(mAdapter); - - if (mRespectSubredditRecommendedSortType) { - fetchCommentsRespectRecommendedSort(false); - } else { - ParseComment.parseComment(response.body(), new ArrayList<>(), mLocale, - mExpandChildren, new ParseComment.ParseCommentListener() { - @Override - public void onParseCommentSuccess(ArrayList expandedComments, String parentId, ArrayList moreChildrenFullnames) { - ViewPostDetailActivity.this.children = moreChildrenFullnames; - - hasMoreChildren = children.size() != 0; - mAdapter.addComments(expandedComments, hasMoreChildren); - - if (children.size() > 0) { - mRecyclerView.clearOnScrollListeners(); - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (!mIsSmoothScrolling && !mLockFab) { - if (!recyclerView.canScrollVertically(1)) { - fab.hide(); - } else { - if (dy > 0) { - if (mSwipeUpToHideFab) { - fab.show(); - } else { - fab.hide(); - } - } else { - if (mSwipeUpToHideFab) { - fab.hide(); - } else { - fab.show(); - } - } - } - } - - if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { - int visibleItemCount = mLinearLayoutManager.getChildCount(); - int totalItemCount = mLinearLayoutManager.getItemCount(); - int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - - if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { - fetchMoreComments(); - } - } - } - - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_IDLE) { - mIsSmoothScrolling = false; - } - } - }); - } - } - - @Override - public void onParseCommentFailed() { - mAdapter.initiallyLoadCommentsFailed(); - } - }); - } - } - - @Override - public void onParsePostFail() { - showErrorView(subredditId); - } - }); - } else { - showErrorView(subredditId); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - showErrorView(subredditId); - } - }); - } - - private void fetchCommentsRespectRecommendedSort(boolean changeRefreshState, boolean checkSortState, String sortType) { - if (mRespectSubredditRecommendedSortType && mPost != null) { - FetchSubredditData.fetchSubredditData(mRetrofit, mPost.getSubredditName(), - new FetchSubredditData.FetchSubredditDataListener() { - @Override - public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { - if (subredditData.getSuggestedCommentSort() == null || subredditData.getSuggestedCommentSort().equals("null") || subredditData.getSuggestedCommentSort().equals("")) { - mRespectSubredditRecommendedSortType = false; - ViewPostDetailActivity.this.sortType = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, SortType.Type.BEST.value.toUpperCase()); - if (ViewPostDetailActivity.this.sortType != null) { - mToolbar.setTitle(new SortType(SortType.Type.valueOf(ViewPostDetailActivity.this.sortType)).getType().fullName); - ViewPostDetailActivity.this.sortType = ViewPostDetailActivity.this.sortType.toLowerCase(); - } - fetchComments(changeRefreshState, checkSortState, sortType); - } else { - ViewPostDetailActivity.this.sortType = subredditData.getSuggestedCommentSort(); - String sortTypeTemp = ViewPostDetailActivity.this.sortType.toLowerCase().substring(0, 1).toUpperCase() + ViewPostDetailActivity.this.sortType.substring(1); - mToolbar.setTitle(sortTypeTemp); - fetchComments(changeRefreshState, checkSortState, subredditData.getSuggestedCommentSort()); - } - } - - @Override - public void onFetchSubredditDataFail() { - mRespectSubredditRecommendedSortType = false; - ViewPostDetailActivity.this.sortType = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, SortType.Type.BEST.value.toUpperCase()); - if (ViewPostDetailActivity.this.sortType != null) { - mToolbar.setTitle(new SortType(SortType.Type.valueOf(ViewPostDetailActivity.this.sortType)).getType().fullName); - ViewPostDetailActivity.this.sortType = ViewPostDetailActivity.this.sortType.toLowerCase(); - } - } - }); - } else { - fetchComments(changeRefreshState, checkSortState, sortType); - } - } - - private void fetchComments(boolean changeRefreshState, boolean checkSortState, String sortType) { - isFetchingComments = true; - mAdapter.setSingleComment(mSingleCommentId, isSingleCommentThreadMode); - mAdapter.initiallyLoading(); - String commentId = null; - if (isSingleCommentThreadMode) { - commentId = mSingleCommentId; - } - - Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchComments(retrofit, mAccessToken, mPost.getId(), commentId, sortType, mExpandChildren, - mLocale, new FetchComment.FetchCommentListener() { - @Override - public void onFetchCommentSuccess(ArrayList expandedComments, - String parentId, ArrayList children) { - if (checkSortState && isSortingComments) { - if (changeRefreshState) { - isRefreshing = false; - } - - return; - } - - ViewPostDetailActivity.this.children = children; - - comments = expandedComments; - hasMoreChildren = children.size() != 0; - mAdapter.addComments(expandedComments, hasMoreChildren); - - if (children.size() > 0) { - mRecyclerView.clearOnScrollListeners(); - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (!mIsSmoothScrolling && !mLockFab) { - if (!recyclerView.canScrollVertically(1)) { - fab.hide(); - } else { - if (dy > 0) { - if (mSwipeUpToHideFab) { - fab.show(); - } else { - fab.hide(); - } - } else { - if (mSwipeUpToHideFab) { - fab.hide(); - } else { - fab.show(); - } - } - } - } - - if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { - int visibleItemCount = mLinearLayoutManager.getChildCount(); - int totalItemCount = mLinearLayoutManager.getItemCount(); - int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - - if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { - fetchMoreComments(); - } - } - } - - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_IDLE) { - mIsSmoothScrolling = false; - } - } - }); - } - if (changeRefreshState) { - isRefreshing = false; - } - - isFetchingComments = false; - } - - @Override - public void onFetchCommentFailed() { - isFetchingComments = false; - if (checkSortState && isSortingComments) { - if (changeRefreshState) { - isRefreshing = false; - } - - return; - } - - mAdapter.initiallyLoadCommentsFailed(); - if (changeRefreshState) { - isRefreshing = false; - } - } - }); - } - - private void fetchCommentsRespectRecommendedSort(boolean changeRefreshState) { - fetchCommentsRespectRecommendedSort(changeRefreshState, true, sortType); - } - - void fetchMoreComments() { - if (isFetchingComments || isLoadingMoreChildren || !loadMoreChildrenSuccess) { - return; - } - - isLoadingMoreChildren = true; - - Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchMoreComment(retrofit, mAccessToken, children, mChildrenStartingIndex, - 0, mExpandChildren, mLocale, new FetchComment.FetchMoreCommentListener() { - @Override - public void onFetchMoreCommentSuccess(ArrayList expandedComments, int childrenStartingIndex) { - hasMoreChildren = childrenStartingIndex < children.size(); - mAdapter.addComments(expandedComments, hasMoreChildren); - mChildrenStartingIndex = childrenStartingIndex; - isLoadingMoreChildren = false; - loadMoreChildrenSuccess = true; - } - - @Override - public void onFetchMoreCommentFailed() { - isLoadingMoreChildren = false; - loadMoreChildrenSuccess = false; - mAdapter.loadMoreCommentsFailed(); - } - }); - } - - private void refresh(boolean fetchPost, boolean fetchComments) { - if (mAdapter != null && !isRefreshing) { - isRefreshing = true; - mChildrenStartingIndex = 0; - - mFetchPostInfoLinearLayout.setVisibility(View.GONE); - mGlide.clear(mFetchPostInfoImageView); - - if (fetchComments) { - fetchCommentsRespectRecommendedSort(!fetchPost); - } - - if (fetchPost) { - Retrofit retrofit; - if (mAccessToken == null) { - retrofit = mRetrofit; - } else { - retrofit = mOauthRetrofit; - } - FetchPost.fetchPost(retrofit, mPost.getId(), mAccessToken, mLocale, - new FetchPost.FetchPostListener() { - @Override - public void fetchPostSuccess(Post post) { - mPost = post; - mAdapter.updatePost(mPost); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - isRefreshing = false; - setupMenu(); - mSwipeRefreshLayout.setRefreshing(false); - } - - @Override - public void fetchPostFailed() { - showMessage(R.string.refresh_post_failed); - isRefreshing = false; - } - }); - } - } - } - - private void showErrorView(String subredditId) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchPostInfoLinearLayout.setVisibility(View.VISIBLE); - mFetchPostInfoLinearLayout.setOnClickListener(view -> fetchPostAndCommentsById(subredditId)); - mFetchPostInfoTextView.setText(R.string.load_post_error); - mGlide.load(R.drawable.error_image).into(mFetchPostInfoImageView); - } - - private void showMessage(int resId) { - if (showToast) { - Toast.makeText(ViewPostDetailActivity.this, resId, Toast.LENGTH_SHORT).show(); - } else { - Snackbar.make(mCoordinatorLayout, resId, Snackbar.LENGTH_SHORT).show(); - } - } - - private void markNSFW() { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); - } - - Map params = new HashMap<>(); - params.put(APIUtils.ID_KEY, mPost.getFullName()); - mOauthRetrofit.create(RedditAPI.class).markNSFW(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); - } - - refresh(true, false); - showMessage(R.string.mark_nsfw_success); - } else { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); - } - - showMessage(R.string.mark_nsfw_failed); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); - } - - showMessage(R.string.mark_nsfw_failed); - } - }); - } - - private void unmarkNSFW() { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); - } - - Map params = new HashMap<>(); - params.put(APIUtils.ID_KEY, mPost.getFullName()); - mOauthRetrofit.create(RedditAPI.class).unmarkNSFW(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); - } - - refresh(true, false); - showMessage(R.string.unmark_nsfw_success); - } else { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); - } - - showMessage(R.string.unmark_nsfw_failed); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (mMenu != null) { - mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); - } - - showMessage(R.string.unmark_nsfw_failed); - } - }); - } - - private void markSpoiler() { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); - } - - Map params = new HashMap<>(); - params.put(APIUtils.ID_KEY, mPost.getFullName()); - mOauthRetrofit.create(RedditAPI.class).markSpoiler(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); - } - - refresh(true, false); - showMessage(R.string.mark_spoiler_success); - } else { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); - } - - showMessage(R.string.mark_spoiler_failed); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); - } - - showMessage(R.string.mark_spoiler_failed); - } - }); - } - - private void unmarkSpoiler() { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); - } - - Map params = new HashMap<>(); - params.put(APIUtils.ID_KEY, mPost.getFullName()); - mOauthRetrofit.create(RedditAPI.class).unmarkSpoiler(APIUtils.getOAuthHeader(mAccessToken), params) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); - } - - refresh(true, false); - showMessage(R.string.unmark_spoiler_success); - } else { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); - } - - showMessage(R.string.unmark_spoiler_failed); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - if (mMenu != null) { - mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); - } - - showMessage(R.string.unmark_spoiler_failed); - } - }); - } - - public void deleteComment(String fullName, int position) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.delete_this_comment) - .setMessage(R.string.are_you_sure) - .setPositiveButton(R.string.delete, (dialogInterface, i) - -> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() { - @Override - public void deleteSuccess() { - Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); - mAdapter.deleteComment(position); - } - - @Override - public void deleteFailed() { - Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_failed, Toast.LENGTH_SHORT).show(); - } - })) - .setNegativeButton(R.string.cancel, null) - .show(); - } - - public void showRemovedComment(Comment comment, int position) { - Toast.makeText(ViewPostDetailActivity.this, R.string.fetching_removed_comment, Toast.LENGTH_SHORT).show(); - FetchRemovedComment.fetchRemovedComment( - pushshiftRetrofit, - comment, - new FetchRemovedComment.FetchRemovedCommentListener() { - @Override - public void fetchSuccess(Comment comment) { - mAdapter.editComment(comment.getAuthor(), comment.getCommentMarkdown(), position); - } - - @Override - public void fetchFailed() { - Toast.makeText(ViewPostDetailActivity.this, R.string.show_removed_comment_failed, Toast.LENGTH_SHORT).show(); - } - }); - } - - public void changeToNomalThreadMode() { - isSingleCommentThreadMode = false; - mSingleCommentId = null; - mRespectSubredditRecommendedSortType = mSharedPreferences.getBoolean(SharedPreferencesUtils.RESPECT_SUBREDDIT_RECOMMENDED_COMMENT_SORT_TYPE, false); - refresh(false, true); - } - - public void scrollToNextParentComment() { - if (mLinearLayoutManager != null) { - int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - if (mAdapter != null) { - int nextParentPosition = mAdapter.getNextParentCommentPosition(currentPosition); - if (nextParentPosition < 0) { - return; - } - mSmoothScroller.setTargetPosition(nextParentPosition); - if (mLinearLayoutManager != null) { - mIsSmoothScrolling = true; - mLinearLayoutManager.startSmoothScroll(mSmoothScroller); - } - } - } - } - - public void scrollToPreviousParentComment() { - if (mLinearLayoutManager != null) { - int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - if (mAdapter != null) { - int nextParentPosition = mAdapter.getPreviousParentCommentPosition(currentPosition); - if (nextParentPosition < 0) { - return; - } - mSmoothScroller.setTargetPosition(nextParentPosition); - if (mLinearLayoutManager != null) { - mIsSmoothScrolling = true; - mLinearLayoutManager.startSmoothScroll(mSmoothScroller); - } - } - } - } - - public void delayTransition() { - TransitionManager.beginDelayedTransition(mRecyclerView, new AutoTransition()); - } - - @Subscribe - public void onPostUpdateEvent(PostUpdateEventToDetailActivity event) { - if (mPost.getId().equals(event.post.getId())) { - mPost.setVoteType(event.post.getVoteType()); - mPost.setSaved(event.post.isSaved()); - if (mMenu != null) { - if (event.post.isSaved()) { - mMenu.findItem(R.id.action_save_view_post_detail_activity).setIcon(mSavedIcon); - } else { - mMenu.findItem(R.id.action_save_view_post_detail_activity).setIcon(mUnsavedIcon); - } - } - mAdapter.updatePost(mPost); - } - } - - @Subscribe - public void onChangeNSFWBlurEvent(ChangeNSFWBlurEvent event) { - mAdapter.setBlurNSFW(event.needBlurNSFW); - refreshAdapter(); - } - - @Subscribe - public void onChangeSpoilerBlurEvent(ChangeSpoilerBlurEvent event) { - mAdapter.setBlurSpoiler(event.needBlurSpoiler); - refreshAdapter(); - } - - private void refreshAdapter() { - int previousPosition = -1; - if (mLinearLayoutManager != null) { - previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - } - - RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager(); - mRecyclerView.setAdapter(null); - mRecyclerView.setLayoutManager(null); - mRecyclerView.setAdapter(mAdapter); - mRecyclerView.setLayoutManager(layoutManager); - - if (previousPosition > 0) { - mRecyclerView.scrollToPosition(previousPosition); - } - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - if (!getClass().getName().equals(event.excludeActivityClassName)) { - finish(); - } - } - - @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(); - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.view_post_detail_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - if (mPost != null) { - setupMenu(); - } - return true; - } - - public void showRemovedPost() { - Toast.makeText(ViewPostDetailActivity.this, R.string.fetching_removed_post, Toast.LENGTH_SHORT).show(); - FetchRemovedPost.fetchRemovedPost( - pushshiftRetrofit, - mPost, - new FetchRemovedPost.FetchRemovedPostListener() { - @Override - public void fetchSuccess(Post post) { - mPost = post; - mAdapter.updatePost(post); - } - - @Override - public void fetchFailed() { - Toast.makeText(ViewPostDetailActivity.this, R.string.show_removed_post_failed, Toast.LENGTH_SHORT).show(); - } - }); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_refresh_view_post_detail_activity: - refresh(true, true); - return true; - case R.id.action_comment_view_post_detail_activity: - if (mPost != null) { - if (mPost.isArchived()) { - showMessage(R.string.archived_post_reply_unavailable); - return true; - } - - if (mPost.isLocked()) { - showMessage(R.string.locked_post_comment_unavailable); - return true; - } - - if (mAccessToken == null) { - showMessage(R.string.login_first); - return true; - } - - Intent intent = new Intent(this, CommentActivity.class); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, mPost.getTitle()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY, mPost.getSelfText()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_KEY, mPost.getSelfTextPlain()); - intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mPost.getFullName()); - intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, 0); - intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, false); - startActivityForResult(intent, WRITE_COMMENT_REQUEST_CODE); - } - return true; - case R.id.action_save_view_post_detail_activity: - if (mPost != null && mAccessToken != null) { - if (mPost.isSaved()) { - item.setIcon(mUnsavedIcon); - SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - mPost.setSaved(false); - item.setIcon(mUnsavedIcon); - showMessage(R.string.post_unsaved_success); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - - @Override - public void failed() { - mPost.setSaved(true); - item.setIcon(mSavedIcon); - showMessage(R.string.post_unsaved_failed); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - }); - } else { - item.setIcon(mSavedIcon); - SaveThing.saveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - mPost.setSaved(true); - item.setIcon(mSavedIcon); - showMessage(R.string.post_saved_success); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - - @Override - public void failed() { - mPost.setSaved(false); - item.setIcon(mUnsavedIcon); - showMessage(R.string.post_saved_failed); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - }); - } - } - return true; - case R.id.action_sort_view_post_detail_activity: - if (mPost != null) { - mPostCommentSortTypeBottomSheetFragment.show(getSupportFragmentManager(), mPostCommentSortTypeBottomSheetFragment.getTag()); - } - return true; - case R.id.action_view_crosspost_parent_view_post_detail_activity: - Intent crosspostIntent = new Intent(this, ViewPostDetailActivity.class); - crosspostIntent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, mPost.getCrosspostParentId()); - startActivity(crosspostIntent); - return true; - case R.id.action_hide_view_post_detail_activity: - if (mPost != null && mAccessToken != null) { - if (mPost.isHidden()) { - item.setTitle(R.string.action_hide_post); - - HidePost.unhidePost(mOauthRetrofit, mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { - @Override - public void success() { - mPost.setHidden(false); - item.setTitle(R.string.action_hide_post); - showMessage(R.string.post_unhide_success); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - - @Override - public void failed() { - mPost.setHidden(true); - item.setTitle(R.string.action_unhide_post); - showMessage(R.string.post_unhide_failed); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - }); - } else { - item.setTitle(R.string.action_unhide_post); - - HidePost.hidePost(mOauthRetrofit, mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { - @Override - public void success() { - mPost.setHidden(true); - item.setTitle(R.string.action_unhide_post); - showMessage(R.string.post_hide_success); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - - @Override - public void failed() { - mPost.setHidden(false); - item.setTitle(R.string.action_hide_post); - showMessage(R.string.post_hide_failed); - EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); - } - }); - } - } - return true; - case R.id.action_edit_view_post_detail_activity: - Intent editPostIntent = new Intent(this, EditPostActivity.class); - editPostIntent.putExtra(EditPostActivity.EXTRA_ACCESS_TOKEN, mAccessToken); - editPostIntent.putExtra(EditPostActivity.EXTRA_FULLNAME, mPost.getFullName()); - editPostIntent.putExtra(EditPostActivity.EXTRA_TITLE, mPost.getTitle()); - editPostIntent.putExtra(EditPostActivity.EXTRA_CONTENT, mPost.getSelfText()); - startActivityForResult(editPostIntent, EDIT_POST_REQUEST_CODE); - return true; - case R.id.action_delete_view_post_detail_activity: - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.delete_this_post) - .setMessage(R.string.are_you_sure) - .setPositiveButton(R.string.delete, (dialogInterface, i) - -> DeleteThing.delete(mOauthRetrofit, mPost.getFullName(), mAccessToken, new DeleteThing.DeleteThingListener() { - @Override - public void deleteSuccess() { - Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); - finish(); - } - - @Override - public void deleteFailed() { - showMessage(R.string.delete_post_failed); - } - })) - .setNegativeButton(R.string.cancel, null) - .show(); - return true; - case R.id.action_nsfw_view_post_detail_activity: - if (mPost.isNSFW()) { - unmarkNSFW(); - } else { - markNSFW(); - } - return true; - case R.id.action_spoiler_view_post_detail_activity: - if (mPost.isSpoiler()) { - unmarkSpoiler(); - } else { - markSpoiler(); - } - return true; - case R.id.action_edit_flair_view_post_detail_activity: - FlairBottomSheetFragment flairBottomSheetFragment = new FlairBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); - flairBottomSheetFragment.setArguments(bundle); - flairBottomSheetFragment.show(getSupportFragmentManager(), flairBottomSheetFragment.getTag()); - return true; - case R.id.action_give_award_view_post_detail_activity: - if (mAccessToken == null) { - Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); - return true; - } - - Intent giveAwardIntent = new Intent(this, GiveAwardActivity.class); - giveAwardIntent.putExtra(GiveAwardActivity.EXTRA_THING_FULLNAME, mPost.getFullName()); - giveAwardIntent.putExtra(GiveAwardActivity.EXTRA_ITEM_POSITION, 0); - startActivityForResult(giveAwardIntent, GIVE_AWARD_REQUEST_CODE); - return true; - case R.id.action_report_view_post_detail_activity: - if (mAccessToken == null) { - Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); - return true; - } - Intent intent = new Intent(this, ReportActivity.class); - intent.putExtra(ReportActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); - intent.putExtra(ReportActivity.EXTRA_THING_FULLNAME, mPost.getFullName()); - startActivity(intent); - return true; - case R.id.action_see_removed_view_post_detail_activity: - showRemovedPost(); - return true; - case R.id.action_crosspost_view_post_detail_activity: - Intent submitCrosspostIntent = new Intent(this, SubmitCrosspostActivity.class); - submitCrosspostIntent.putExtra(SubmitCrosspostActivity.EXTRA_POST, mPost); - startActivity(submitCrosspostIntent); - return true; - case android.R.id.home: - onBackPressed(); - return true; - } - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == WRITE_COMMENT_REQUEST_CODE) { - if (data != null && resultCode == RESULT_OK) { - if (data.hasExtra(RETURN_EXTRA_COMMENT_DATA_KEY)) { - Comment comment = data.getParcelableExtra(RETURN_EXTRA_COMMENT_DATA_KEY); - if (comment != null && comment.getDepth() == 0) { - mAdapter.addComment(comment); - } else { - String parentFullname = data.getStringExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY); - int parentPosition = data.getIntExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, -1); - if (parentFullname != null && parentPosition >= 0) { - mAdapter.addChildComment(comment, parentFullname, parentPosition); - } - } - } else { - Toast.makeText(this, R.string.send_comment_failed, Toast.LENGTH_SHORT).show(); - } - } - } else if (requestCode == EDIT_POST_REQUEST_CODE) { - if (resultCode == RESULT_OK) { - refresh(true, false); - } - } else if (requestCode == EDIT_COMMENT_REQUEST_CODE) { - if (data != null && resultCode == RESULT_OK) { - mAdapter.editComment(null, - data.getStringExtra(EditCommentActivity.EXTRA_EDITED_COMMENT_CONTENT), - data.getExtras().getInt(EditCommentActivity.EXTRA_EDITED_COMMENT_POSITION)); - } - } else if (requestCode == GIVE_AWARD_REQUEST_CODE) { - if (data != null && resultCode == RESULT_OK) { - Toast.makeText(this, R.string.give_award_success, Toast.LENGTH_SHORT).show(); - int position = data.getIntExtra(GiveAwardActivity.EXTRA_RETURN_ITEM_POSITION, 0); - String newAwardsHTML = data.getStringExtra(GiveAwardActivity.EXTRA_RETURN_NEW_AWARDS); - int newAwardsCount = data.getIntExtra(GiveAwardActivity.EXTRA_RETURN_NEW_AWARDS_COUNT, 0); - if (mAdapter != null) { - mAdapter.giveAward(newAwardsHTML, newAwardsCount, position); - } - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - comments = mAdapter == null ? null : mAdapter.getVisibleComments(); - Bridge.saveInstanceState(this, outState); - } - - @Override - public void onBackPressed() { - if (orientation == getResources().getConfiguration().orientation) { - super.onBackPressed(); - } else { - finish(); - } - } - - @Override - protected void onDestroy() { - EventBus.getDefault().unregister(this); - super.onDestroy(); - Bridge.clear(this); - } - - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - if (mVolumeKeysNavigateComments) { - switch (keyCode) { - case KeyEvent.KEYCODE_VOLUME_UP: - scrollToPreviousParentComment(); - return true; - case KeyEvent.KEYCODE_VOLUME_DOWN: - scrollToNextParentComment(); - return true; - } - } - return super.onKeyDown(keyCode, event); - } - - @Override - public void flairSelected(Flair flair) { - Map params = new HashMap<>(); - params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); - params.put(APIUtils.FLAIR_TEMPLATE_ID_KEY, flair.getId()); - params.put(APIUtils.LINK_KEY, mPost.getFullName()); - params.put(APIUtils.TEXT_KEY, flair.getText()); - - mOauthRetrofit.create(RedditAPI.class).selectFlair(mPost.getSubredditNamePrefixed(), - APIUtils.getOAuthHeader(mAccessToken), params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - refresh(true, false); - showMessage(R.string.update_flair_success); - } else { - showMessage(R.string.update_flair_failed); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - showMessage(R.string.update_flair_failed); - } - }); - } - - @Override - public void sortTypeSelected(SortType sortType) { - mFetchPostInfoLinearLayout.setVisibility(View.GONE); - mGlide.clear(mFetchPostInfoImageView); - mChildrenStartingIndex = 0; - if (children != null) { - children.clear(); - } - this.sortType = sortType.getType().value; - if (!mRespectSubredditRecommendedSortType) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, sortType.getType().name()).apply(); - } - mRespectSubredditRecommendedSortType = false; - fetchCommentsRespectRecommendedSort(false, false, sortType.getType().value); - - mToolbar.setTitle(sortType.getType().fullName); - } - - public void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - public void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } - - @Override - public void onLongPress() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java deleted file mode 100644 index 80cff550..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewPrivateMessagesActivity.java +++ /dev/null @@ -1,331 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Build; -import android.os.Bundle; -import android.view.MenuItem; -import android.view.View; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.Toolbar; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.transition.AutoTransition; -import androidx.transition.TransitionManager; - -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.snackbar.Snackbar; - -import org.greenrobot.eventbus.EventBus; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.Adapter.PrivateMessagesDetailRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadUserDataAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.RepliedToPrivateMessageEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.Message; -import ml.docilealligator.infinityforreddit.Message.ReadMessage; -import ml.docilealligator.infinityforreddit.Message.ReplyMessage; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import retrofit2.Retrofit; - -public class ViewPrivateMessagesActivity extends BaseActivity implements ActivityToolbarInterface { - - public static final String EXTRA_PRIVATE_MESSAGE = "EPM"; - public static final String EXTRA_MESSAGE_POSITION = "EMP"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String USER_AVATAR_STATE = "UAS"; - @BindView(R.id.linear_layout_view_private_messages_activity) - LinearLayout mLinearLayout; - @BindView(R.id.coordinator_layout_view_private_messages_activity) - CoordinatorLayout mCoordinatorLayout; - @BindView(R.id.appbar_layout_view_private_messages_activity) - AppBarLayout mAppBarLayout; - @BindView(R.id.toolbar_view_private_messages_activity) - Toolbar mToolbar; - @BindView(R.id.recycler_view_view_private_messages) - RecyclerView mRecyclerView; - @BindView(R.id.edit_text_divider_view_private_messages_activity) - View mDivider; - @BindView(R.id.edit_text_view_private_messages_activity) - EditText mEditText; - @BindView(R.id.send_image_view_view_private_messages_activity) - ImageView mSendImageView; - @BindView(R.id.edit_text_wrapper_linear_layout_view_private_messages_activity) - LinearLayout mEditTextLinearLayout; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private LinearLayoutManager mLinearLayoutManager; - private PrivateMessagesDetailRecyclerViewAdapter mAdapter; - private Message privateMessage; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String mUserAvatar; - private ArrayList mProvideUserAvatarCallbacks; - private LoadUserDataAsyncTask mLoadUserDataAsyncTask; - private boolean isSendingMessage = false; - private int mSecondaryTextColor; - private int mSendMessageIconColor; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - setImmersiveModeNotApplicable(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_view_private_messages); - - ButterKnife.bind(this); - - applyCustomTheme(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { - addOnOffsetChangedListener(mAppBarLayout); - } - - Intent intent = getIntent(); - privateMessage = intent.getParcelableExtra(EXTRA_PRIVATE_MESSAGE); - - setSupportActionBar(mToolbar); - setToolbarGoToTop(mToolbar); - - mProvideUserAvatarCallbacks = new ArrayList<>(); - - if (savedInstanceState != null) { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - mUserAvatar = savedInstanceState.getString(USER_AVATAR_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - } else { - getCurrentAccountAndBindView(); - } - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - bindView(); - }).execute(); - } - - private void bindView() { - if (privateMessage != null) { - if (privateMessage.getAuthor().equals(mAccountName)) { - mToolbar.setTitle(privateMessage.getDestination()); - mToolbar.setOnClickListener(view -> { - Intent intent = new Intent(this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getDestination()); - startActivity(intent); - }); - } else { - mToolbar.setTitle(privateMessage.getAuthor()); - mToolbar.setOnClickListener(view -> { - Intent intent = new Intent(this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getAuthor()); - startActivity(intent); - }); - } - } - mAdapter = new PrivateMessagesDetailRecyclerViewAdapter(this, mSharedPreferences, - getResources().getConfiguration().locale, privateMessage, mAccountName, mCustomThemeWrapper); - mLinearLayoutManager = new LinearLayoutManager(this); - mLinearLayoutManager.setStackFromEnd(true); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - mRecyclerView.setAdapter(mAdapter); - goToBottom(); - mSendImageView.setOnClickListener(view -> { - if (!isSendingMessage) { - if (!mEditText.getText().toString().equals("")) { - //Send Message - if (privateMessage != null) { - Message replyTo; - ArrayList replies = privateMessage.getReplies(); - if (replies != null && !replies.isEmpty()) { - replyTo = replies.get(replies.size() - 1); - } else { - replyTo = privateMessage; - } - if (replyTo != null) { - isSendingMessage = true; - mSendImageView.setColorFilter(mSecondaryTextColor, android.graphics.PorterDuff.Mode.SRC_IN); - ReplyMessage.replyMessage(mEditText.getText().toString(), replyTo.getFullname(), - getResources().getConfiguration().locale, mOauthRetrofit, mAccessToken, - new ReplyMessage.ReplyMessageListener() { - @Override - public void replyMessageSuccess(Message message) { - if (mAdapter != null) { - mAdapter.addReply(message); - } - goToBottom(); - mEditText.setText(""); - mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - isSendingMessage = false; - EventBus.getDefault().post(new RepliedToPrivateMessageEvent(message, getIntent().getIntExtra(EXTRA_MESSAGE_POSITION, -1))); - } - - @Override - public void replyMessageFailed(String errorMessage) { - if (errorMessage != null && !errorMessage.equals("")) { - Snackbar.make(mCoordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); - } else { - Snackbar.make(mCoordinatorLayout, R.string.reply_message_failed, Snackbar.LENGTH_LONG).show(); - } - mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - isSendingMessage = false; - } - }); - StringBuilder fullnames = new StringBuilder(); - if (privateMessage.isNew()) { - fullnames.append(privateMessage.getFullname()).append(","); - } - if (replies != null && !replies.isEmpty()) { - for (Message m : replies) { - if (m.isNew()) { - fullnames.append(m).append(","); - } - } - } - if (fullnames.length() > 0) { - fullnames.deleteCharAt(fullnames.length() - 1); - ReadMessage.readMessage(mOauthRetrofit, mAccessToken, fullnames.toString(), - new ReadMessage.ReadMessageListener() { - @Override - public void readSuccess() {} - - @Override - public void readFailed() {} - }); - } - } else { - isSendingMessage = false; - Snackbar.make(mCoordinatorLayout, R.string.error_getting_message, Snackbar.LENGTH_LONG).show(); - } - } - } - } - }); - } - - public void fetchUserAvatar(String username, ProvideUserAvatarCallback provideUserAvatarCallback) { - if (mUserAvatar == null) { - mProvideUserAvatarCallbacks.add(provideUserAvatarCallback); - if (mLoadUserDataAsyncTask == null) { - mLoadUserDataAsyncTask = new LoadUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), username, mRetrofit, iconImageUrl -> { - mUserAvatar = iconImageUrl; - for (ProvideUserAvatarCallback provideUserAvatarCallbackInArrayList : mProvideUserAvatarCallbacks) { - provideUserAvatarCallbackInArrayList.fetchAvatarSuccess(iconImageUrl); - } - mProvideUserAvatarCallbacks.clear(); - }); - mLoadUserDataAsyncTask.execute(); - } - } else { - provideUserAvatarCallback.fetchAvatarSuccess(mUserAvatar); - } - } - - public void delayTransition() { - TransitionManager.beginDelayedTransition(mRecyclerView, new AutoTransition()); - } - - private void goToBottom() { - if (mLinearLayoutManager != null && mAdapter != null) { - mLinearLayoutManager.scrollToPositionWithOffset(mAdapter.getItemCount() - 1, 0); - } - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putString(USER_AVATAR_STATE, mUserAvatar); - } - - @Override - protected SharedPreferences getDefaultSharedPreferences() { - return mSharedPreferences; - } - - @Override - protected CustomThemeWrapper getCustomThemeWrapper() { - return mCustomThemeWrapper; - } - - @Override - protected void applyCustomTheme() { - mLinearLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); - mDivider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); - mEditText.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); - mSecondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); - mEditText.setHintTextColor(mSecondaryTextColor); - mEditTextLinearLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); - mSendMessageIconColor = mCustomThemeWrapper.getSendMessageIconColor(); - mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - - @Override - public void onLongPress() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } - - public interface ProvideUserAvatarCallback { - void fetchAvatarSuccess(String userAvatarUrl); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewRedditGalleryActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewRedditGalleryActivity.java deleted file mode 100644 index 6fab69e2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewRedditGalleryActivity.java +++ /dev/null @@ -1,242 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.SharedPreferences; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.viewpager.widget.ViewPager; - -import com.thefuntasty.hauler.DragDirection; -import com.thefuntasty.hauler.HaulerView; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Font.ContentFontFamily; -import ml.docilealligator.infinityforreddit.Font.ContentFontStyle; -import ml.docilealligator.infinityforreddit.Font.FontFamily; -import ml.docilealligator.infinityforreddit.Font.FontStyle; -import ml.docilealligator.infinityforreddit.Font.TitleFontFamily; -import ml.docilealligator.infinityforreddit.Font.TitleFontStyle; -import ml.docilealligator.infinityforreddit.Fragment.ViewRedditGalleryImageOrGifFragment; -import ml.docilealligator.infinityforreddit.Fragment.ViewRedditGalleryVideoFragment; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.WallpaperSetter; - -public class ViewRedditGalleryActivity extends AppCompatActivity implements SetAsWallpaperCallback { - - public static final String EXTRA_REDDIT_GALLERY = "ERG"; - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - - @BindView(R.id.hauler_view_view_reddit_gallery_activity) - HaulerView haulerView; - @BindView(R.id.view_pager_view_reddit_gallery_activity) - ViewPager viewPager; - private SectionsPagerAdapter sectionsPagerAdapter; - private ArrayList gallery; - private String subredditName; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - ((Infinity) getApplication()).getAppComponent().inject(this); - - getTheme().applyStyle(R.style.Theme_Normal, true); - - getTheme().applyStyle(FontStyle.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(TitleFontStyle.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(ContentFontStyle.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); - - getTheme().applyStyle(FontFamily.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(TitleFontFamily.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(ContentFontFamily.valueOf(sharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); - - setContentView(R.layout.activity_view_reddit_gallery); - - ButterKnife.bind(this); - - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); - - setTitle(" "); - - gallery = getIntent().getParcelableArrayListExtra(EXTRA_REDDIT_GALLERY); - if (gallery == null || gallery.isEmpty()) { - finish(); - return; - } - subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); - - haulerView.setOnDragDismissedListener(dragDirection -> { - int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; - finish(); - overridePendingTransition(0, slide); - }); - - setupViewPager(); - } - - private void setupViewPager() { - setToolbarTitle(0); - sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); - viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { - @Override - public void onPageSelected(int position) { - setToolbarTitle(position); - } - }); - viewPager.setAdapter(sectionsPagerAdapter); - } - - private void setToolbarTitle(int position) { - if (gallery != null && position >= 0 && position < gallery.size()) { - if (gallery.get(position).mediaType == Post.Gallery.TYPE_IMAGE) { - setTitle(getString(R.string.view_reddit_gallery_activity_image_label, position + 1, gallery.size())); - } else if (gallery.get(position).mediaType == Post.Gallery.TYPE_GIF) { - setTitle(getString(R.string.view_reddit_gallery_activity_gif_label, position + 1, gallery.size())); - } else { - setTitle(getString(R.string.view_reddit_gallery_activity_video_label, position + 1, gallery.size())); - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == android.R.id.home) { - finish(); - return true; - } - - return false; - } - - @Override - public void setToHomeScreen(int viewPagerPosition) { - if (gallery != null && viewPagerPosition >= 0 && viewPagerPosition < gallery.size()) { - WallpaperSetter.set(gallery.get(viewPagerPosition).url, WallpaperSetter.HOME_SCREEN, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewRedditGalleryActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewRedditGalleryActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } - - @Override - public void setToLockScreen(int viewPagerPosition) { - if (gallery != null && viewPagerPosition >= 0 && viewPagerPosition < gallery.size()) { - WallpaperSetter.set(gallery.get(viewPagerPosition).url, WallpaperSetter.LOCK_SCREEN, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewRedditGalleryActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewRedditGalleryActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } - - @Override - public void setToBoth(int viewPagerPosition) { - if (gallery != null && viewPagerPosition >= 0 && viewPagerPosition < gallery.size()) { - WallpaperSetter.set(gallery.get(viewPagerPosition).url, WallpaperSetter.BOTH_SCREENS, this, - new WallpaperSetter.SetWallpaperListener() { - @Override - public void success() { - Toast.makeText(ViewRedditGalleryActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewRedditGalleryActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); - } - }); - } - } - - public int getCurrentPagePosition() { - return viewPager.getCurrentItem(); - } - - private class SectionsPagerAdapter extends FragmentStatePagerAdapter { - - SectionsPagerAdapter(@NonNull FragmentManager fm) { - super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); - } - - @NonNull - @Override - public Fragment getItem(int position) { - Post.Gallery media = gallery.get(position); - if (media.mediaType == Post.Gallery.TYPE_VIDEO) { - ViewRedditGalleryVideoFragment fragment = new ViewRedditGalleryVideoFragment(); - Bundle bundle = new Bundle(); - bundle.putParcelable(ViewRedditGalleryVideoFragment.EXTRA_REDDIT_GALLERY_VIDEO, media); - bundle.putString(ViewRedditGalleryVideoFragment.EXTRA_SUBREDDIT_NAME, subredditName); - fragment.setArguments(bundle); - return fragment; - } else { - ViewRedditGalleryImageOrGifFragment fragment = new ViewRedditGalleryImageOrGifFragment(); - Bundle bundle = new Bundle(); - bundle.putParcelable(ViewRedditGalleryImageOrGifFragment.EXTRA_REDDIT_GALLERY_MEDIA, media); - bundle.putString(ViewRedditGalleryImageOrGifFragment.EXTRA_SUBREDDIT_NAME, subredditName); - fragment.setArguments(bundle); - return fragment; - } - } - - @Override - public int getCount() { - return gallery.size(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java deleted file mode 100644 index fd7f23a5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java +++ /dev/null @@ -1,1324 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.graphics.Point; -import android.os.Build; -import android.os.Bundle; -import android.view.Display; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewTreeObserver; -import android.view.Window; -import android.view.WindowManager; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -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.FragmentManager; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.ViewModelProvider; -import androidx.viewpager2.adapter.FragmentStateAdapter; -import androidx.viewpager2.widget.ViewPager2; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.bottomappbar.BottomAppBar; -import com.google.android.material.chip.Chip; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import com.google.android.material.snackbar.Snackbar; -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.text.SimpleDateFormat; -import java.util.Locale; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; -import ml.docilealligator.infinityforreddit.AsyncTask.CheckIsSubscribedToSubredditAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertSubredditDataAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SwitchAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FABMoreOptionsBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.RandomBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTimeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; -import ml.docilealligator.infinityforreddit.Event.GoBackToMainPageEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.Fragment.SidebarFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.ReadMessage; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.Subreddit.FetchSubredditData; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditSubscription; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditViewModel; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class ViewSubredditDetailActivity extends BaseActivity implements SortTypeSelectionCallback, - PostTypeBottomSheetFragment.PostTypeSelectionCallback, PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, - ActivityToolbarInterface, FABMoreOptionsBottomSheetFragment.FABOptionSelectionCallback, - RandomBottomSheetFragment.RandomOptionSelectionCallback { - - public static final String EXTRA_SUBREDDIT_NAME_KEY = "ESN"; - public static final String EXTRA_MESSAGE_FULLNAME = "ENF"; - public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; - public static final String EXTRA_VIEW_SIDEBAR = "EVSB"; - - private static final String FETCH_SUBREDDIT_INFO_STATE = "FSIS"; - private static final String CURRENT_ONLINE_SUBSCRIBERS_STATE = "COSS"; - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String MESSAGE_FULLNAME_STATE = "MFS"; - private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; - - @BindView(R.id.coordinator_layout_view_subreddit_detail_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.view_pager_view_subreddit_detail_activity) - ViewPager2 viewPager2; - @BindView(R.id.appbar_layout_view_subreddit_detail_activity) - AppBarLayout appBarLayout; - @BindView(R.id.collapsing_toolbar_layout_view_subreddit_detail_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.toolbar_linear_layout_view_subreddit_detail_activity) - LinearLayout linearLayout; - @BindView(R.id.toolbar) - Toolbar toolbar; - @BindView(R.id.tab_layout_view_subreddit_detail_activity) - TabLayout tabLayout; - @BindView(R.id.banner_image_view_view_subreddit_detail_activity) - GifImageView bannerImageView; - @BindView(R.id.icon_gif_image_view_view_subreddit_detail_activity) - GifImageView iconGifImageView; - @BindView(R.id.subscribe_subreddit_chip_view_subreddit_detail_activity) - Chip subscribeSubredditChip; - @BindView(R.id.subreddit_name_text_view_view_subreddit_detail_activity) - TextView subredditNameTextView; - @BindView(R.id.subscriber_count_text_view_view_subreddit_detail_activity) - TextView nSubscribersTextView; - @BindView(R.id.online_subscriber_count_text_view_view_subreddit_detail_activity) - TextView nOnlineSubscribersTextView; - @BindView(R.id.since_text_view_view_subreddit_detail_activity) - TextView sinceTextView; - @BindView(R.id.creation_time_text_view_view_subreddit_detail_activity) - TextView creationTimeTextView; - @BindView(R.id.description_text_view_view_subreddit_detail_activity) - TextView descriptionTextView; - @BindView(R.id.bottom_navigation_view_subreddit_detail_activity) - BottomAppBar bottomNavigationView; - @BindView(R.id.linear_layout_bottom_app_bar_view_subreddit_detail_activity) - LinearLayout linearLayoutBottomAppBar; - @BindView(R.id.option_1_bottom_app_bar_view_subreddit_detail_activity) - ImageView option1BottomAppBar; - @BindView(R.id.option_2_bottom_app_bar_view_subreddit_detail_activity) - ImageView option2BottomAppBar; - @BindView(R.id.option_3_bottom_app_bar_view_subreddit_detail_activity) - ImageView option3BottomAppBar; - @BindView(R.id.option_4_bottom_app_bar_view_subreddit_detail_activity) - ImageView option4BottomAppBar; - @BindView(R.id.fab_view_subreddit_detail_activity) - FloatingActionButton fab; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences mNsfwAndSpoilerSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - @Named("bottom_app_bar") - SharedPreferences bottomAppBarSharedPreference; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - public SubredditViewModel mSubredditViewModel; - private FragmentManager fragmentManager; - private SectionsPagerAdapter sectionsPagerAdapter; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String subredditName; - private boolean mFetchSubredditInfoSuccess = false; - private int mNCurrentOnlineSubscribers = 0; - private boolean subscriptionReady = false; - private boolean isInLazyMode = false; - private boolean showToast = false; - private boolean showBottomAppBar; - private boolean lockBottomAppBar; - private String mMessageFullname; - private String mNewAccountName; - private RequestManager glide; - private Menu mMenu; - private AppBarLayout.LayoutParams params; - private PostTypeBottomSheetFragment postTypeBottomSheetFragment; - private SortTypeBottomSheetFragment sortTypeBottomSheetFragment; - private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - private FABMoreOptionsBottomSheetFragment fabMoreOptionsBottomSheetFragment; - private int expandedTabTextColor; - private int expandedTabBackgroundColor; - private int expandedTabIndicatorColor; - private int collapsedTabTextColor; - private int collapsedTabBackgroundColor; - private int collapsedTabIndicatorColor; - private int unsubscribedColor; - private int subscribedColor; - private SlidrInterface mSlidrInterface; - private MaterialAlertDialogBuilder nsfwWarningBuilder; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - setTransparentStatusBarAfterToolbarCollapsed(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_view_subreddit_detail); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - showToast = true; - - int navBarHeight = getNavBarHeight(); - if (navBarHeight > 0) { - CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); - params.bottomMargin += navBarHeight; - fab.setLayoutParams(params); - coordinatorLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - coordinatorLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); - - Display display = getWindowManager().getDefaultDisplay(); - Point size = new Point(); - display.getRealSize(size); - if (size.y == coordinatorLayout.getHeight()) { - linearLayoutBottomAppBar.setPadding(0, - linearLayoutBottomAppBar.getPaddingTop(), 0, navBarHeight); - } - } - }); - - showToast = true; - } - } - - View decorView = window.getDecorView(); - if (isChangeStatusBarIconColor()) { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { - if (state == State.COLLAPSED) { - decorView.setSystemUiVisibility(getSystemVisibilityToolbarCollapsed()); - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } else if (state == State.EXPANDED) { - decorView.setSystemUiVisibility(getSystemVisibilityToolbarExpanded()); - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } - } - }); - } else { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, State state) { - if (state == State.COLLAPSED) { - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } else if (state == State.EXPANDED) { - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } - } - }); - } - } else { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, State state) { - if (state == State.EXPANDED) { - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } else if (state == State.COLLAPSED) { - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } - } - }); - } - - showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); - lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); - boolean hideSubredditDescription = mSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_SUBREDDIT_DESCRIPTION, false); - - subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME_KEY); - - fragmentManager = getSupportFragmentManager(); - - if (savedInstanceState == null) { - mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); - mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); - getCurrentAccountAndBindView(); - } else { - mFetchSubredditInfoSuccess = savedInstanceState.getBoolean(FETCH_SUBREDDIT_INFO_STATE); - mNCurrentOnlineSubscribers = savedInstanceState.getInt(CURRENT_ONLINE_SUBSCRIBERS_STATE); - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); - mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(); - } else { - bindView(); - } - - if (mFetchSubredditInfoSuccess) { - nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, mNCurrentOnlineSubscribers)); - } - } - - fetchSubredditData(); - - postTypeBottomSheetFragment = new PostTypeBottomSheetFragment(); - - sortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); - Bundle bottomSheetBundle = new Bundle(); - bottomSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); - sortTypeBottomSheetFragment.setArguments(bottomSheetBundle); - - sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - fabMoreOptionsBottomSheetFragment = new FABMoreOptionsBottomSheetFragment(); - - params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - - String title = "r/" + subredditName; - subredditNameTextView.setText(title); - - toolbar.setTitle(title); - adjustToolbar(toolbar); - setSupportActionBar(toolbar); - setToolbarGoToTop(toolbar); - - glide = Glide.with(this); - Locale locale = getResources().getConfiguration().locale; - - mSubredditViewModel = new ViewModelProvider(this, - new SubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, subredditName)) - .get(SubredditViewModel.class); - mSubredditViewModel.getSubredditLiveData().observe(this, subredditData -> { - if (subredditData != null) { - if (subredditData.getBannerUrl().equals("")) { - iconGifImageView.setOnClickListener(view -> { - //Do nothing as it has no image - }); - } else { - glide.load(subredditData.getBannerUrl()).into(bannerImageView); - bannerImageView.setOnClickListener(view -> { - Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, subredditData.getBannerUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, subredditName + "-banner.jpg"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, subredditName); - startActivity(intent); - }); - } - - if (subredditData.getIconUrl().equals("")) { - glide.load(getDrawable(R.drawable.subreddit_default_icon)) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) - .into(iconGifImageView); - iconGifImageView.setOnClickListener(view -> { - //Do nothing as it is a default icon - }); - } else { - glide.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); - iconGifImageView.setOnClickListener(view -> { - Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, subredditData.getIconUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, subredditName + "-icon.jpg"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, subredditName); - startActivity(intent); - }); - } - - String subredditFullName = "r/" + subredditData.getName(); - if (!title.equals(subredditFullName)) { - getSupportActionBar().setTitle(subredditFullName); - } - subredditNameTextView.setText(subredditFullName); - String nSubscribers = getString(R.string.subscribers_number_detail, subredditData.getNSubscribers()); - nSubscribersTextView.setText(nSubscribers); - creationTimeTextView.setText(new SimpleDateFormat("MMM d, yyyy", - locale).format(subredditData.getCreatedUTC())); - if (hideSubredditDescription || subredditData.getDescription().equals("")) { - descriptionTextView.setVisibility(View.GONE); - } else { - descriptionTextView.setVisibility(View.VISIBLE); - descriptionTextView.setText(subredditData.getDescription()); - } - - if (subredditData.isNSFW()) { - if (nsfwWarningBuilder == null - && !mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)) { - nsfwWarningBuilder = new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.warning) - .setMessage(R.string.this_is_a_nsfw_subreddit) - .setPositiveButton(R.string.leave, (dialogInterface, i) - -> { - finish(); - }) - .setNegativeButton(R.string.dismiss, null); - nsfwWarningBuilder.show(); - } - } - } - }); - } - - @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()); - collapsingToolbarLayout.setContentScrimColor(mCustomThemeWrapper.getColorPrimary()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - expandedTabTextColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTextColor(); - expandedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabIndicator(); - expandedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabBackground(); - collapsedTabTextColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor(); - collapsedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabIndicator(); - collapsedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabBackground(); - linearLayout.setBackgroundColor(expandedTabBackgroundColor); - subredditNameTextView.setTextColor(mCustomThemeWrapper.getSubreddit()); - subscribeSubredditChip.setTextColor(mCustomThemeWrapper.getChipTextColor()); - int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); - nSubscribersTextView.setTextColor(primaryTextColor); - nOnlineSubscribersTextView.setTextColor(primaryTextColor); - sinceTextView.setTextColor(primaryTextColor); - creationTimeTextView.setTextColor(primaryTextColor); - descriptionTextView.setTextColor(primaryTextColor); - bottomNavigationView.setBackgroundTint(ColorStateList.valueOf(mCustomThemeWrapper.getBottomAppBarBackgroundColor())); - int bottomAppBarIconColor = mCustomThemeWrapper.getBottomAppBarIconColor(); - option2BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option1BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option3BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - option4BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - applyTabLayoutTheme(tabLayout); - applyFABTheme(fab); - unsubscribedColor = mCustomThemeWrapper.getUnsubscribed(); - subscribedColor = mCustomThemeWrapper.getSubscribed(); - } - - private void getCurrentAccountAndBindView() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (mNewAccountName != null) { - if (account == null || !account.getUsername().equals(mNewAccountName)) { - new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { - EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); - Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); - - mNewAccountName = null; - if (newAccount == null) { - mNullAccessToken = true; - } else { - mAccessToken = newAccount.getAccessToken(); - mAccountName = newAccount.getUsername(); - } - - bindView(); - }).execute(); - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - bindView(); - } - } else { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - - bindView(); - } - }).execute(); - } - - private void fetchSubredditData() { - if (!mFetchSubredditInfoSuccess) { - FetchSubredditData.fetchSubredditData(mRetrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { - @Override - public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { - mNCurrentOnlineSubscribers = nCurrentOnlineSubscribers; - nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, nCurrentOnlineSubscribers)); - new InsertSubredditDataAsyncTask(mRedditDataRoomDatabase, subredditData, () -> mFetchSubredditInfoSuccess = true).execute(); - } - - @Override - public void onFetchSubredditDataFail() { - makeSnackbar(R.string.cannot_fetch_subreddit_info, true); - mFetchSubredditInfoSuccess = false; - } - }); - } - } - - private void bottomAppBarOptionAction(int option) { - switch (option) { - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME: { - EventBus.getDefault().post(new GoBackToMainPageEvent()); - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: { - Intent intent = new Intent(this, SubscribedThingListingActivity.class); - startActivity(intent); - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX: { - Intent intent = new Intent(this, InboxActivity.class); - startActivity(intent); - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE: { - Intent intent = new Intent(this, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); - startActivity(intent); - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: { - Intent intent = new Intent(this, SubscribedThingListingActivity.class); - intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); - startActivity(intent); - break; - } - } - } - - private int getBottomAppBarOptionDrawableResource(int option) { - switch (option) { - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME: - return R.drawable.ic_home_black_24dp; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: - return R.drawable.ic_subscritptions_bottom_app_bar_24dp; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX: - return R.drawable.ic_inbox_24dp; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: - return R.drawable.ic_multi_reddit_24dp; - default: - return R.drawable.ic_account_circle_24dp; - } - } - - private void bindView() { - if (mAccessToken != null) { - if (mMessageFullname != null) { - ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { - @Override - public void readSuccess() { - mMessageFullname = null; - } - - @Override - public void readFailed() { - - } - }); - } - - if (showBottomAppBar) { - int optionCount = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT, 4); - int option1 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME); - int option2 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS); - - bottomNavigationView.setVisibility(View.VISIBLE); - - if (optionCount == 2) { - linearLayoutBottomAppBar.setWeightSum(3); - option1BottomAppBar.setVisibility(View.GONE); - option3BottomAppBar.setVisibility(View.GONE); - - option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); - option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); - - option2BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option1); - }); - - option4BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option2); - }); - } else { - int option3 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX); - int option4 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE); - - option1BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); - option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); - option3BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option3)); - option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option4)); - - option1BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option1); - }); - - option2BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option2); - }); - - option3BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option3); - }); - - option4BottomAppBar.setOnClickListener(view -> { - bottomAppBarOptionAction(option4); - }); - } - } else { - CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); - lp.setAnchorId(View.NO_ID); - lp.gravity = Gravity.END | Gravity.BOTTOM; - fab.setLayoutParams(lp); - } - - int fabOption = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS); - switch (fabOption) { - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_REFRESH: - fab.setImageResource(R.drawable.ic_refresh_24dp); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: - fab.setImageResource(R.drawable.ic_sort_toolbar_24dp); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: - fab.setImageResource(R.drawable.ic_post_layout_24dp); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SEARCH: - fab.setImageResource(R.drawable.ic_search_black_24dp); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: - fab.setImageResource(R.drawable.ic_subreddit_24dp); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_USER: - fab.setImageResource(R.drawable.ic_user_24dp); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_RANDOM: - fab.setImageResource(R.drawable.ic_random_24dp); - break; - default: - fab.setImageResource(R.drawable.ic_add_day_night_24dp); - break; - } - fab.setOnClickListener(view -> { - switch (fabOption) { - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_REFRESH: { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.refresh(); - } - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: { - sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: { - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SEARCH: { - Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(intent); - break; - } - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: - goToSubreddit(); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_USER: - goToUser(); - break; - case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_RANDOM: - random(); - break; - default: - postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); - break; - } - }); - fab.setOnLongClickListener(view -> { - fabMoreOptionsBottomSheetFragment.show(getSupportFragmentManager(), fabMoreOptionsBottomSheetFragment.getTag()); - return true; - }); - - fab.setVisibility(View.VISIBLE); - } else { - bottomNavigationView.setVisibility(View.GONE); - fab.setVisibility(View.GONE); - } - - subscribeSubredditChip.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(ViewSubredditDetailActivity.this, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (subscriptionReady) { - subscriptionReady = false; - if (subscribeSubredditChip.getText().equals(getResources().getString(R.string.subscribe))) { - SubredditSubscription.subscribeToSubreddit(mOauthRetrofit, mRetrofit, mAccessToken, - subredditName, mAccountName, mRedditDataRoomDatabase, - new SubredditSubscription.SubredditSubscriptionListener() { - @Override - public void onSubredditSubscriptionSuccess() { - subscribeSubredditChip.setText(R.string.unsubscribe); - subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); - makeSnackbar(R.string.subscribed, false); - subscriptionReady = true; - } - - @Override - public void onSubredditSubscriptionFail() { - makeSnackbar(R.string.subscribe_failed, false); - subscriptionReady = true; - } - }); - } else { - SubredditSubscription.unsubscribeToSubreddit(mOauthRetrofit, mAccessToken, - subredditName, mAccountName, mRedditDataRoomDatabase, - new SubredditSubscription.SubredditSubscriptionListener() { - @Override - public void onSubredditSubscriptionSuccess() { - subscribeSubredditChip.setText(R.string.subscribe); - subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); - makeSnackbar(R.string.unsubscribed, false); - subscriptionReady = true; - } - - @Override - public void onSubredditSubscriptionFail() { - makeSnackbar(R.string.unsubscribe_failed, false); - subscriptionReady = true; - } - }); - } - } - }); - - new CheckIsSubscribedToSubredditAsyncTask(mRedditDataRoomDatabase, subredditName, mAccountName, - new CheckIsSubscribedToSubredditAsyncTask.CheckIsSubscribedToSubredditListener() { - @Override - public void isSubscribed() { - subscribeSubredditChip.setText(R.string.unsubscribe); - subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); - subscriptionReady = true; - } - - @Override - public void isNotSubscribed() { - subscribeSubredditChip.setText(R.string.subscribe); - subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); - subscriptionReady = true; - } - }).execute(); - - sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); - viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageSelected(int position) { - if (position == 0) { - unlockSwipeRightToGoBack(); - } else { - lockSwipeRightToGoBack(); - } - - if (mAccessToken != null) { - if (showBottomAppBar) { - bottomNavigationView.performShow(); - } - fab.show(); - } - - sectionsPagerAdapter.displaySortTypeInToolbar(); - } - }); - viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(2); - viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); - new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { - switch (position) { - case 0: - tab.setText(R.string.posts); - break; - case 1: - tab.setText(R.string.sidebar); - } - }).attach(); - fixViewPager2Sensitivity(viewPager2); - - boolean viewSidebar = getIntent().getBooleanExtra(EXTRA_VIEW_SIDEBAR, false); - if (viewSidebar) { - viewPager2.setCurrentItem(1, false); - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.view_subreddit_detail_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_subreddit_detail_activity); - if (isInLazyMode) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } else { - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | - AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_sort_view_subreddit_detail_activity: - sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); - return true; - case R.id.action_search_view_subreddit_detail_activity: - Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(intent); - return true; - case R.id.action_refresh_view_subreddit_detail_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_view_subreddit_detail_activity).setTitle(R.string.action_start_lazy_mode); - } - sectionsPagerAdapter.refresh(); - mFetchSubredditInfoSuccess = false; - fetchSubredditData(); - return true; - case R.id.action_lazy_mode_view_subreddit_detail_activity: - if (sectionsPagerAdapter != null) { - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_subreddit_detail_activity); - if (isInLazyMode) { - isInLazyMode = false; - sectionsPagerAdapter.stopLazyMode(); - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | - AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = true; - if (sectionsPagerAdapter.startLazyMode()) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - appBarLayout.setExpanded(false); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = false; - } - } - } - return true; - case R.id.action_change_post_layout_view_subreddit_detail_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - case R.id.action_select_user_flair_view_subreddit_detail_activity: - if (mAccessToken == null) { - Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); - return true; - } - Intent selectUserFlairIntent = new Intent(this, SelectUserFlairActivity.class); - selectUserFlairIntent.putExtra(SelectUserFlairActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(selectUserFlairIntent); - return true; - case R.id.action_share_view_subreddit_detail_activity: - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.setType("text/plain"); - shareIntent.putExtra(Intent.EXTRA_TEXT, "https://www.reddit.com/r/" + subredditName); - if (shareIntent.resolveActivity(getPackageManager()) != null) { - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } else { - Toast.makeText(this, R.string.no_app, Toast.LENGTH_SHORT).show(); - } - return true; - } - return false; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(FETCH_SUBREDDIT_INFO_STATE, mFetchSubredditInfoSuccess); - outState.putInt(CURRENT_ONLINE_SUBSCRIBERS_STATE, mNCurrentOnlineSubscribers); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); - outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - private void makeSnackbar(int resId, boolean retry) { - if (showToast) { - Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); - } else { - if (retry) { - Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).setAction(R.string.retry, - view -> fetchSubredditData()).show(); - } else { - Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).show(); - } - } - } - - @Override - public void sortTypeSelected(SortType sortType) { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.changeSortType(sortType); - } - } - - @Override - public void sortTypeSelected(String sortType) { - Bundle bundle = new Bundle(); - bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); - sortTimeBottomSheetFragment.setArguments(bundle); - sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); - } - - @Override - public void postTypeSelected(int postType) { - Intent intent; - switch (postType) { - case PostTypeBottomSheetFragment.TYPE_TEXT: - intent = new Intent(this, PostTextActivity.class); - intent.putExtra(PostTextActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(intent); - break; - case PostTypeBottomSheetFragment.TYPE_LINK: - intent = new Intent(this, PostLinkActivity.class); - intent.putExtra(PostLinkActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(intent); - break; - case PostTypeBottomSheetFragment.TYPE_IMAGE: - intent = new Intent(this, PostImageActivity.class); - intent.putExtra(PostImageActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(intent); - break; - case PostTypeBottomSheetFragment.TYPE_VIDEO: - intent = new Intent(this, PostVideoActivity.class); - intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(intent); - } - } - - @Override - public void postLayoutSelected(int postLayout) { - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + subredditName, postLayout).apply(); - sectionsPagerAdapter.changePostLayout(postLayout); - } - - public void contentScrollUp() { - if (mAccessToken != null) { - if (showBottomAppBar && !lockBottomAppBar) { - bottomNavigationView.performShow(); - } - if (!(showBottomAppBar && lockBottomAppBar)) { - fab.show(); - } - } - } - - public void contentScrollDown() { - if (mAccessToken != null) { - if (!(showBottomAppBar && lockBottomAppBar)) { - fab.hide(); - } - if (showBottomAppBar && !lockBottomAppBar) { - bottomNavigationView.performHide(); - } - } - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - if (!getClass().getName().equals(event.excludeActivityClassName)) { - finish(); - } - } - - @Subscribe - public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { - sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); - } - - @Subscribe - public void goBackToMainPageEvent(GoBackToMainPageEvent event) { - finish(); - } - - @Override - public void onLongPress() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.goBackToTop(); - } - } - - @Override - public void displaySortType() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.displaySortTypeInToolbar(); - } - } - - @Override - public void fabOptionSelected(int option) { - switch (option) { - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SUBMIT_POST: - postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_REFRESH: - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.refresh(); - } - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_SORT_TYPE: - sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_POST_LAYOUT: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SEARCH: - Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, subredditName); - startActivity(intent); - break; - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_SUBREDDIT: { - goToSubreddit(); - break; - } - case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_USER: { - goToUser(); - break; - } - case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { - random(); - break; - } - } - } - - private void goToSubreddit() { - EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); - thingEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.go_to_subreddit) - .setView(thingEditText) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); - subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); - startActivity(subredditIntent); - }) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - }) - .show(); - } - - private void goToUser() { - EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); - thingEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.go_to_user) - .setView(thingEditText) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - Intent userIntent = new Intent(this, ViewUserDetailActivity.class); - userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); - startActivity(userIntent); - }) - .setNegativeButton(R.string.cancel, null) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); - } - }) - .show(); - } - - private void random() { - RandomBottomSheetFragment randomBottomSheetFragment = new RandomBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putBoolean(RandomBottomSheetFragment.EXTRA_IS_NSFW, mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)); - randomBottomSheetFragment.setArguments(bundle); - randomBottomSheetFragment.show(getSupportFragmentManager(), randomBottomSheetFragment.getTag()); - } - - @Override - public void randomOptionSelected(int option) { - Intent intent = new Intent(this, FetchRandomSubredditOrPostActivity.class); - intent.putExtra(FetchRandomSubredditOrPostActivity.EXTRA_RANDOM_OPTION, option); - startActivity(intent); - } - - private class SectionsPagerAdapter extends FragmentStateAdapter { - - SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { - super(fm, lifecycle); - } - - @NonNull - @Override - public Fragment createFragment(int position) { - if (position == 0) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putString(PostFragment.EXTRA_NAME, subredditName); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } - SidebarFragment fragment = new SidebarFragment(); - Bundle bundle = new Bundle(); - bundle.putString(SidebarFragment.EXTRA_SUBREDDIT_NAME, subredditName); - fragment.setArguments(bundle); - return fragment; - } - - @Nullable - private Fragment getCurrentFragment() { - if (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 SidebarFragment) { - ((SidebarFragment) fragment).fetchSubredditData(); - } - } - - boolean startLazyMode() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof FragmentCommunicator) { - return ((FragmentCommunicator) fragment).startLazyMode(); - } - return false; - } - - void stopLazyMode() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof FragmentCommunicator) { - ((FragmentCommunicator) fragment).stopLazyMode(); - } - } - - public void changeSortType(SortType sortType) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeSortType(sortType); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } - } - - public void changeNSFW(boolean nsfw) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeNSFW(nsfw); - } - } - - void changePostLayout(int postLayout) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changePostLayout(postLayout); - } - } - - void goBackToTop() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).goBackToTop(); - } else if (fragment instanceof SidebarFragment) { - ((SidebarFragment) fragment).goBackToTop(); - } - } - - void displaySortTypeInToolbar() { - if (fragmentManager != null) { - Fragment fragment = fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); - if (fragment instanceof PostFragment) { - SortType sortType = ((PostFragment) fragment).getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } - } - } - - @Override - public int getItemCount() { - return 2; - } - } - - private void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - private void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewUserDetailActivity.java deleted file mode 100644 index f365dda4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewUserDetailActivity.java +++ /dev/null @@ -1,1025 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Resources; -import android.net.Uri; -import android.os.AsyncTask; -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 android.widget.LinearLayout; -import android.widget.TextView; -import android.widget.Toast; - -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.FragmentManager; -import androidx.lifecycle.Lifecycle; -import androidx.lifecycle.ViewModelProvider; -import androidx.viewpager2.adapter.FragmentStateAdapter; -import androidx.viewpager2.widget.ViewPager2; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; -import com.google.android.material.appbar.AppBarLayout; -import com.google.android.material.appbar.CollapsingToolbarLayout; -import com.google.android.material.chip.Chip; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.snackbar.Snackbar; -import com.google.android.material.tabs.TabLayout; -import com.google.android.material.tabs.TabLayoutMediator; -import com.r0adkll.slidr.Slidr; -import com.r0adkll.slidr.model.SlidrInterface; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import java.text.SimpleDateFormat; -import java.util.Locale; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; -import ml.docilealligator.infinityforreddit.AsyncTask.CheckIsFollowingUserAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SwitchAccountAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.PostLayoutBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SortTimeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.UserThingSortTypeBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.DeleteThing; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; -import ml.docilealligator.infinityforreddit.Event.SwitchAccountEvent; -import ml.docilealligator.infinityforreddit.Fragment.CommentsListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.ReadMessage; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserDao; -import ml.docilealligator.infinityforreddit.User.BlockUser; -import ml.docilealligator.infinityforreddit.User.FetchUserData; -import ml.docilealligator.infinityforreddit.User.UserDao; -import ml.docilealligator.infinityforreddit.User.UserData; -import ml.docilealligator.infinityforreddit.User.UserFollowing; -import ml.docilealligator.infinityforreddit.User.UserViewModel; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class ViewUserDetailActivity extends BaseActivity implements SortTypeSelectionCallback, - PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { - - public static final String EXTRA_USER_NAME_KEY = "EUNK"; - public static final String EXTRA_MESSAGE_FULLNAME = "ENF"; - public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; - public static final int GIVE_AWARD_REQUEST_CODE = 200; - public static final int EDIT_COMMENT_REQUEST_CODE = 300; - - private static final String FETCH_USER_INFO_STATE = "FSIS"; - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - private static final String ACCOUNT_NAME_STATE = "ANS"; - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - private static final String MESSAGE_FULLNAME_STATE = "MFS"; - private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; - - @BindView(R.id.coordinator_layout_view_user_detail_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.view_pager_view_user_detail_activity) - ViewPager2 viewPager2; - @BindView(R.id.appbar_layout_view_user_detail) - AppBarLayout appBarLayout; - @BindView(R.id.toolbar_view_user_detail_activity) - Toolbar toolbar; - @BindView(R.id.toolbar_linear_layout_view_user_detail_activity) - LinearLayout linearLayout; - @BindView(R.id.tab_layout_view_user_detail_activity) - TabLayout tabLayout; - @BindView(R.id.collapsing_toolbar_layout_view_user_detail_activity) - CollapsingToolbarLayout collapsingToolbarLayout; - @BindView(R.id.banner_image_view_view_user_detail_activity) - GifImageView bannerImageView; - @BindView(R.id.icon_gif_image_view_view_user_detail_activity) - GifImageView iconGifImageView; - @BindView(R.id.user_name_text_view_view_user_detail_activity) - TextView userNameTextView; - @BindView(R.id.subscribe_user_chip_view_user_detail_activity) - Chip subscribeUserChip; - @BindView(R.id.karma_text_view_view_user_detail_activity) - TextView karmaTextView; - @BindView(R.id.cakeday_text_view_view_user_detail_activity) - TextView cakedayTextView; - @BindView(R.id.description_text_view_view_user_detail_activity) - TextView descriptionTextView; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences mNsfwAndSpoilerSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - public UserViewModel userViewModel; - private FragmentManager fragmentManager; - private SectionsPagerAdapter sectionsPagerAdapter; - private SubscribedUserDao subscribedUserDao; - private RequestManager glide; - private Menu mMenu; - private AppBarLayout.LayoutParams params; - private UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment; - private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; - private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; - private boolean mNullAccessToken = false; - private String mAccessToken; - private String mAccountName; - private String username; - private boolean subscriptionReady = false; - private boolean mFetchUserInfoSuccess = false; - private boolean isInLazyMode = false; - private int expandedTabTextColor; - private int expandedTabBackgroundColor; - private int expandedTabIndicatorColor; - private int collapsedTabTextColor; - private int collapsedTabBackgroundColor; - private int collapsedTabIndicatorColor; - private int unsubscribedColor; - private int subscribedColor; - private boolean showToast = false; - private String mMessageFullname; - private String mNewAccountName; - private SlidrInterface mSlidrInterface; - private MaterialAlertDialogBuilder nsfwWarningBuilder; - - @Override - protected void onCreate(Bundle savedInstanceState) { - ((Infinity) getApplication()).getAppComponent().inject(this); - setTransparentStatusBarAfterToolbarCollapsed(); - - super.onCreate(savedInstanceState); - - setContentView(R.layout.activity_view_user_detail); - - ButterKnife.bind(this); - - EventBus.getDefault().register(this); - - applyCustomTheme(); - - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { - mSlidrInterface = Slidr.attach(this); - } - - username = getIntent().getStringExtra(EXTRA_USER_NAME_KEY); - - fragmentManager = getSupportFragmentManager(); - - if (savedInstanceState == null) { - mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); - mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); - getCurrentAccountAndInitializeViewPager(); - } else { - mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE); - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); - mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndInitializeViewPager(); - } else { - initializeViewPager(); - } - } - - fetchUserInfo(); - - params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); - - Resources resources = getResources(); - - adjustToolbar(toolbar); - - String title = "u/" + username; - userNameTextView.setText(title); - toolbar.setTitle(title); - - setSupportActionBar(toolbar); - setToolbarGoToTop(toolbar); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Window window = getWindow(); - if (isImmersiveInterface()) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - } else { - window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); - } - showToast = true; - } - - View decorView = window.getDecorView(); - if (isChangeStatusBarIconColor()) { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, State state) { - if (state == State.COLLAPSED) { - decorView.setSystemUiVisibility(getSystemVisibilityToolbarCollapsed()); - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } else if (state == State.EXPANDED) { - decorView.setSystemUiVisibility(getSystemVisibilityToolbarExpanded()); - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } - } - }); - } else { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, State state) { - if (state == State.COLLAPSED) { - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } else if (state == State.EXPANDED) { - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } - } - }); - } - } else { - appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { - @Override - public void onStateChanged(AppBarLayout appBarLayout, State state) { - if (state == State.EXPANDED) { - tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); - tabLayout.setBackgroundColor(expandedTabBackgroundColor); - } else if (state == State.COLLAPSED) { - tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); - tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); - tabLayout.setBackgroundColor(collapsedTabBackgroundColor); - } - } - }); - } - - subscribedUserDao = mRedditDataRoomDatabase.subscribedUserDao(); - glide = Glide.with(this); - Locale locale = getResources().getConfiguration().locale; - - userViewModel = new ViewModelProvider(this, new UserViewModel.Factory(getApplication(), mRedditDataRoomDatabase, username)) - .get(UserViewModel.class); - userViewModel.getUserLiveData().observe(this, userData -> { - if (userData != null) { - if (userData.getBanner().equals("")) { - bannerImageView.setOnClickListener(null); - } else { - glide.load(userData.getBanner()).into(bannerImageView); - bannerImageView.setOnClickListener(view -> { - Intent intent = new Intent(this, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, userData.getBanner()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, username + "-banner.jpg"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, username); - startActivity(intent); - }); - } - - if (userData.getIconUrl().equals("")) { - glide.load(getDrawable(R.drawable.subreddit_default_icon)) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) - .into(iconGifImageView); - iconGifImageView.setOnClickListener(null); - } else { - glide.load(userData.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); - - iconGifImageView.setOnClickListener(view -> { - Intent intent = new Intent(this, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, userData.getIconUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, username + "-icon.jpg"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, username); - startActivity(intent); - }); - } - - if (userData.isCanBeFollowed()) { - subscribeUserChip.setVisibility(View.VISIBLE); - subscribeUserChip.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(ViewUserDetailActivity.this, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (subscriptionReady) { - subscriptionReady = false; - if (subscribeUserChip.getText().equals(resources.getString(R.string.follow))) { - UserFollowing.followUser(mOauthRetrofit, mRetrofit, mAccessToken, - username, mAccountName, subscribedUserDao, new UserFollowing.UserFollowingListener() { - @Override - public void onUserFollowingSuccess() { - subscribeUserChip.setText(R.string.unfollow); - subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); - showMessage(R.string.followed, false); - subscriptionReady = true; - } - - @Override - public void onUserFollowingFail() { - showMessage(R.string.follow_failed, false); - subscriptionReady = true; - } - }); - } else { - UserFollowing.unfollowUser(mOauthRetrofit, mRetrofit, mAccessToken, - username, mAccountName, subscribedUserDao, new UserFollowing.UserFollowingListener() { - @Override - public void onUserFollowingSuccess() { - subscribeUserChip.setText(R.string.follow); - subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); - showMessage(R.string.unfollowed, false); - subscriptionReady = true; - } - - @Override - public void onUserFollowingFail() { - showMessage(R.string.unfollow_failed, false); - subscriptionReady = true; - } - }); - } - } - }); - - new CheckIsFollowingUserAsyncTask(subscribedUserDao, username, mAccountName, new CheckIsFollowingUserAsyncTask.CheckIsFollowingUserListener() { - @Override - public void isSubscribed() { - subscribeUserChip.setText(R.string.unfollow); - subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); - subscriptionReady = true; - } - - @Override - public void isNotSubscribed() { - subscribeUserChip.setText(R.string.follow); - subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); - subscriptionReady = true; - } - }).execute(); - } else { - subscribeUserChip.setVisibility(View.GONE); - } - - String userFullName = "u/" + userData.getName(); - userNameTextView.setText(userFullName); - if (!title.equals(userFullName)) { - getSupportActionBar().setTitle(userFullName); - } - String karma = getString(R.string.karma_info_user_detail, userData.getTotalKarma(), userData.getLinkKarma(), userData.getCommentKarma()); - karmaTextView.setText(karma); - cakedayTextView.setText(getString(R.string.cakeday_info, new SimpleDateFormat("MMM d, yyyy", - locale).format(userData.getCakeday()))); - - if (userData.getDescription() == null || userData.getDescription().equals("")) { - descriptionTextView.setVisibility(View.GONE); - } else { - descriptionTextView.setVisibility(View.VISIBLE); - descriptionTextView.setText(userData.getDescription()); - } - - if (userData.isNSFW()) { - if (nsfwWarningBuilder == null - && !mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)) { - nsfwWarningBuilder = new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.warning) - .setMessage(R.string.this_user_has_nsfw_content) - .setPositiveButton(R.string.leave, (dialogInterface, i) - -> { - finish(); - }) - .setNegativeButton(R.string.dismiss, null); - nsfwWarningBuilder.show(); - } - } - } - }); - - userThingSortTypeBottomSheetFragment = new UserThingSortTypeBottomSheetFragment(); - sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); - postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); - } - - @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()); - collapsingToolbarLayout.setContentScrimColor(mCustomThemeWrapper.getColorPrimary()); - applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); - expandedTabTextColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTextColor(); - expandedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabIndicator(); - expandedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabBackground(); - collapsedTabTextColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor(); - collapsedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabIndicator(); - collapsedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabBackground(); - linearLayout.setBackgroundColor(expandedTabBackgroundColor); - unsubscribedColor = mCustomThemeWrapper.getUnsubscribed(); - subscribedColor = mCustomThemeWrapper.getSubscribed(); - userNameTextView.setTextColor(mCustomThemeWrapper.getUsername()); - karmaTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); - cakedayTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); - descriptionTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); - subscribeUserChip.setTextColor(mCustomThemeWrapper.getChipTextColor()); - applyTabLayoutTheme(tabLayout); - } - - private void getCurrentAccountAndInitializeViewPager() { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (mNewAccountName != null) { - if (account == null || !account.getUsername().equals(mNewAccountName)) { - new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { - EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); - Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); - - mNewAccountName = null; - if (newAccount == null) { - mNullAccessToken = true; - } else { - mAccessToken = newAccount.getAccessToken(); - mAccountName = newAccount.getUsername(); - } - - initializeViewPager(); - }).execute(); - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - initializeViewPager(); - } - } else { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - mAccountName = account.getUsername(); - } - - initializeViewPager(); - } - }).execute(); - } - - private void initializeViewPager() { - sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); - viewPager2.setAdapter(sectionsPagerAdapter); - viewPager2.setOffscreenPageLimit(2); - viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); - new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { - switch (position) { - case 0: - tab.setText(R.string.posts); - break; - case 1: - tab.setText(R.string.comments); - break; - } - }).attach(); - - viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { - @Override - public void onPageSelected(int position) { - if (position == 0) { - unlockSwipeRightToGoBack(); - } else { - lockSwipeRightToGoBack(); - } - sectionsPagerAdapter.displaySortTypeInToolbar(); - } - }); - - fixViewPager2Sensitivity(viewPager2); - - if (mAccessToken != null && mMessageFullname != null) { - ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { - @Override - public void readSuccess() { - mMessageFullname = null; - } - - @Override - public void readFailed() { - - } - }); - } - } - - private void fetchUserInfo() { - if (!mFetchUserInfoSuccess) { - FetchUserData.fetchUserData(mRetrofit, username, new FetchUserData.FetchUserDataListener() { - @Override - public void onFetchUserDataSuccess(UserData userData) { - new ViewUserDetailActivity.InsertUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), userData, - () -> mFetchUserInfoSuccess = true).execute(); - } - - @Override - public void onFetchUserDataFailed() { - showMessage(R.string.cannot_fetch_user_info, true); - mFetchUserInfoSuccess = false; - } - }); - } - } - - public void deleteComment(String fullName) { - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.delete_this_comment) - .setMessage(R.string.are_you_sure) - .setPositiveButton(R.string.delete, (dialogInterface, i) - -> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() { - @Override - public void deleteSuccess() { - Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void deleteFailed() { - Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_failed, Toast.LENGTH_SHORT).show(); - } - })) - .setNegativeButton(R.string.cancel, null) - .show(); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.view_user_detail_activity, menu); - applyMenuItemTheme(menu); - mMenu = menu; - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_user_detail_activity); - if (isInLazyMode) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } else { - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | - AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } - - return true; - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_sort_view_user_detail_activity: - userThingSortTypeBottomSheetFragment.show(getSupportFragmentManager(), userThingSortTypeBottomSheetFragment.getTag()); - return true; - case R.id.action_search_view_user_detail_activity: - Intent intent = new Intent(this, SearchActivity.class); - intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, username); - intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_IS_USER, true); - startActivity(intent); - return true; - case R.id.action_refresh_view_user_detail_activity: - if (mMenu != null) { - mMenu.findItem(R.id.action_lazy_mode_view_user_detail_activity).setTitle(R.string.action_start_lazy_mode); - } - sectionsPagerAdapter.refresh(); - mFetchUserInfoSuccess = false; - fetchUserInfo(); - return true; - case R.id.action_lazy_mode_view_user_detail_activity: - MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_user_detail_activity); - if (isInLazyMode) { - isInLazyMode = false; - sectionsPagerAdapter.stopLazyMode(); - lazyModeItem.setTitle(R.string.action_start_lazy_mode); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | - AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = true; - if (sectionsPagerAdapter.startLazyMode()) { - lazyModeItem.setTitle(R.string.action_stop_lazy_mode); - appBarLayout.setExpanded(false); - params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); - collapsingToolbarLayout.setLayoutParams(params); - } else { - isInLazyMode = false; - } - } - return true; - case R.id.action_change_post_layout_view_user_detail_activity: - postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); - return true; - case R.id.action_share_view_user_detail_activity: - Intent shareIntent = new Intent(Intent.ACTION_SEND); - shareIntent.setType("text/plain"); - shareIntent.putExtra(Intent.EXTRA_TEXT, "https://www.reddit.com/user/" + username); - if (shareIntent.resolveActivity(getPackageManager()) != null) { - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } else { - Toast.makeText(this, R.string.no_app, Toast.LENGTH_SHORT).show(); - } - return true; - case R.id.action_send_private_message_view_user_detail_activity: - if (mAccessToken == null) { - Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); - return true; - } - - Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class); - pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username); - startActivity(pmIntent); - return true; - case R.id.action_report_view_user_detail_activity: - Intent reportIntent = new Intent(this, LinkResolverActivity.class); - reportIntent.setData(Uri.parse("https://www.reddithelp.com/en/categories/rules-reporting/account-and-community-restrictions/what-should-i-do-if-i-see-something-i")); - startActivity(reportIntent); - return true; - case R.id.action_block_user_view_user_detail_activity: - if (mAccessToken == null) { - Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); - return true; - } - - new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.block_user) - .setMessage(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> BlockUser.blockUser(mOauthRetrofit, mAccessToken, username, new BlockUser.BlockUserListener() { - @Override - public void success() { - Toast.makeText(ViewUserDetailActivity.this, R.string.block_user_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - Toast.makeText(ViewUserDetailActivity.this, R.string.block_user_failed, Toast.LENGTH_SHORT).show(); - } - })) - .setNegativeButton(R.string.no, null) - .show(); - return true; - } - return false; - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == RESULT_OK) { - if (requestCode == GIVE_AWARD_REQUEST_CODE) { - Toast.makeText(this, R.string.give_award_success, Toast.LENGTH_SHORT).show(); - int position = data.getIntExtra(GiveAwardActivity.EXTRA_RETURN_ITEM_POSITION, 0); - String newAwardsHTML = data.getStringExtra(GiveAwardActivity.EXTRA_RETURN_NEW_AWARDS); - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.giveAward(newAwardsHTML, position); - } - } else if (requestCode == EDIT_COMMENT_REQUEST_CODE) { - if (data != null) { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.editComment( - data.getStringExtra(EditCommentActivity.EXTRA_EDITED_COMMENT_CONTENT), - data.getExtras().getInt(EditCommentActivity.EXTRA_EDITED_COMMENT_POSITION)); - } - } - } - } - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putString(ACCOUNT_NAME_STATE, mAccountName); - outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); - outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - private void showMessage(int resId, boolean retry) { - if (showToast) { - Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); - } else { - if (retry) { - Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).setAction(R.string.retry, - view -> fetchUserInfo()).show(); - } else { - Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).show(); - } - } - } - - @Override - public void sortTypeSelected(SortType sortType) { - sectionsPagerAdapter.changeSortType(sortType); - } - - @Override - public void sortTypeSelected(String sortType) { - Bundle bundle = new Bundle(); - bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); - sortTimeBottomSheetFragment.setArguments(bundle); - sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); - } - - @Override - public void postLayoutSelected(int postLayout) { - sectionsPagerAdapter.changePostLayout(postLayout); - } - - @Subscribe - public void onAccountSwitchEvent(SwitchAccountEvent event) { - if (!getClass().getName().equals(event.excludeActivityClassName)) { - finish(); - } - } - - @Subscribe - public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { - sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); - } - - @Override - public void onLongPress() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.goBackToTop(); - } - } - - @Override - public void displaySortType() { - if (sectionsPagerAdapter != null) { - sectionsPagerAdapter.displaySortTypeInToolbar(); - } - } - - private static class InsertUserDataAsyncTask extends AsyncTask { - - private UserDao userDao; - private UserData subredditData; - private InsertUserDataAsyncTaskListener insertUserDataAsyncTaskListener; - InsertUserDataAsyncTask(UserDao userDao, UserData userData, - InsertUserDataAsyncTaskListener insertUserDataAsyncTaskListener) { - this.userDao = userDao; - this.subredditData = userData; - this.insertUserDataAsyncTaskListener = insertUserDataAsyncTaskListener; - } - - @Override - protected Void doInBackground(final Void... params) { - userDao.insert(subredditData); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - insertUserDataAsyncTaskListener.insertSuccess(); - } - - interface InsertUserDataAsyncTaskListener { - void insertSuccess(); - } - } - - private class SectionsPagerAdapter extends FragmentStateAdapter { - - SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { - super(fm, lifecycle); - } - - @NonNull - @Override - public Fragment createFragment(int position) { - if (position == 0) { - PostFragment fragment = new PostFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); - bundle.putString(PostFragment.EXTRA_USER_NAME, username); - bundle.putString(PostFragment.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SUBMITTED); - bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); - bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); - fragment.setArguments(bundle); - return fragment; - } - CommentsListingFragment fragment = new CommentsListingFragment(); - Bundle bundle = new Bundle(); - bundle.putString(CommentsListingFragment.EXTRA_USERNAME, username); - bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); - bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, false); - fragment.setArguments(bundle); - return fragment; - } - - @Override - public int getItemCount() { - return 2; - } - - @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(); - } - } - - boolean startLazyMode() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof FragmentCommunicator) { - return ((FragmentCommunicator) fragment).startLazyMode(); - } - return false; - } - - void stopLazyMode() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof FragmentCommunicator) { - ((FragmentCommunicator) fragment).stopLazyMode(); - } - } - - public void changeSortType(SortType sortType) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeSortType(sortType); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } else if (fragment instanceof CommentsListingFragment) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_USER_COMMENT, sortType.getType().name()).apply(); - if(sortType.getTime() != null) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_USER_COMMENT, sortType.getTime().name()).apply(); - } - ((CommentsListingFragment) fragment).changeSortType(sortType); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } - } - - public void changeNSFW(boolean nsfw) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changeNSFW(nsfw); - } - } - - void changePostLayout(int postLayout) { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).changePostLayout(postLayout); - } - } - - void goBackToTop() { - Fragment fragment = getCurrentFragment(); - if (fragment instanceof PostFragment) { - ((PostFragment) fragment).goBackToTop(); - } else if (fragment instanceof CommentsListingFragment) { - ((CommentsListingFragment) fragment).goBackToTop(); - } - } - - void displaySortTypeInToolbar() { - if (fragmentManager != null) { - Fragment fragment = fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); - if (fragment instanceof PostFragment) { - SortType sortType = ((PostFragment) fragment).getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } else if (fragment instanceof CommentsListingFragment) { - SortType sortType = ((CommentsListingFragment) fragment).getSortType(); - Utils.displaySortTypeInToolbar(sortType, toolbar); - } - } - } - - void giveAward(String awardsHTML, int position) { - if (fragmentManager != null) { - Fragment fragment = fragmentManager.findFragmentByTag("f1"); - if (fragment instanceof CommentsListingFragment) { - ((CommentsListingFragment) fragment).giveAward(awardsHTML, position); - } - } - } - - void editComment(String commentMarkdown, int position) { - if (fragmentManager != null) { - Fragment fragment = fragmentManager.findFragmentByTag("f1"); - if (fragment instanceof CommentsListingFragment) { - ((CommentsListingFragment) fragment).editComment(commentMarkdown, position); - } - } - } - } - - private void lockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.lock(); - } - } - - private void unlockSwipeRightToGoBack() { - if (mSlidrInterface != null) { - mSlidrInterface.unlock(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewVideoActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewVideoActivity.java deleted file mode 100644 index 77cdc9e7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewVideoActivity.java +++ /dev/null @@ -1,508 +0,0 @@ -package ml.docilealligator.infinityforreddit.Activity; - -import android.Manifest; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.text.Html; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; - -import com.google.android.exoplayer2.ExoPlayerFactory; -import com.google.android.exoplayer2.Player; -import com.google.android.exoplayer2.SimpleExoPlayer; -import com.google.android.exoplayer2.source.ProgressiveMediaSource; -import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.source.hls.HlsMediaSource; -import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; -import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; -import com.google.android.exoplayer2.trackselection.TrackSelection; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; -import com.google.android.exoplayer2.ui.PlayerView; -import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder; -import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; -import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; -import com.google.android.exoplayer2.util.Util; -import com.google.android.material.snackbar.Snackbar; -import com.thefuntasty.hauler.DragDirection; -import com.thefuntasty.hauler.HaulerView; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; -import ml.docilealligator.infinityforreddit.Font.ContentFontFamily; -import ml.docilealligator.infinityforreddit.Font.FontFamily; -import ml.docilealligator.infinityforreddit.Font.TitleFontFamily; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Service.DownloadMediaService; -import ml.docilealligator.infinityforreddit.Service.DownloadRedditVideoService; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Retrofit; - -public class ViewVideoActivity extends AppCompatActivity { - - 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_PROGRESS_SECONDS = "EPS"; - public static final String EXTRA_VIDEO_TYPE = "EVT"; - public static final String EXTRA_GFYCAT_ID = "EGI"; - public static final String EXTRA_IS_NSFW = "EIN"; - public static final int VIDEO_TYPE_DIRECT = 3; - public static final int VIDEO_TYPE_REDGIFS = 2; - public static final int VIDEO_TYPE_GFYCAT = 1; - private static final int VIDEO_TYPE_NORMAL = 0; - private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; - private static final String IS_MUTE_STATE = "IMS"; - private static final String VIDEO_DOWNLOAD_URL_STATE = "VDUS"; - private static final String VIDEO_URI_STATE = "VUS"; - @BindView(R.id.hauler_view_view_video_activity) - HaulerView haulerView; - @BindView(R.id.coordinator_layout_view_video_activity) - CoordinatorLayout coordinatorLayout; - @BindView(R.id.progress_bar_view_video_activity) - ProgressBar progressBar; - @BindView(R.id.player_view_view_video_activity) - PlayerView videoPlayerView; - @BindView(R.id.mute_exo_playback_control_view) - ImageButton muteButton; - @BindView(R.id.hd_exo_playback_control_view) - ImageButton hdButton; - - private Uri mVideoUri; - private SimpleExoPlayer player; - private DefaultTrackSelector trackSelector; - private DataSource.Factory dataSourceFactory; - - private String videoDownloadUrl; - private String videoFileName; - private String subredditName; - private String id; - private boolean wasPlaying; - private boolean isDownloading = false; - private boolean isMute = false; - private String postTitle; - private boolean isNSFW; - private long resumePosition = -1; - private int videoType; - private boolean isDataSavingMode; - private boolean isHd; - - @Inject - @Named("gfycat") - Retrofit gfycatRetrofit; - - @Inject - @Named("redgifs") - Retrofit redgifsRetrofit; - - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - ((Infinity) getApplication()).getAppComponent().inject(this); - - getTheme().applyStyle(R.style.Theme_Normal, true); - - getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(TitleFontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); - - getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences - .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); - - setContentView(R.layout.activity_view_video); - - ButterKnife.bind(this); - setVolumeControlStream(AudioManager.STREAM_MUSIC); - - ActionBar actionBar = getSupportActionBar(); - Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); - actionBar.setHomeAsUpIndicator(upArrow); - actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); - - String dataSavingModeString = mSharedPreferences.getString(SharedPreferencesUtils.DATA_SAVING_MODE, SharedPreferencesUtils.DATA_SAVING_MODE_OFF); - int networkType = Utils.getConnectedNetwork(this); - if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ALWAYS)) { - isDataSavingMode = true; - } else if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA)) { - isDataSavingMode = networkType == Utils.NETWORK_TYPE_CELLULAR; - } - isHd = !isDataSavingMode; - - if (!mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_IGNORE_NAV_BAR, false)) { - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { - //Set player controller bottom margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); - LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.bottomMargin = getResources().getDimensionPixelSize(resourceId); - } else { - //Set player controller right margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); - LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.rightMargin = getResources().getDimensionPixelSize(resourceId); - } - } - - haulerView.setOnDragDismissedListener(dragDirection -> { - int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; - finish(); - overridePendingTransition(0, slide); - }); - - Intent intent = getIntent(); - mVideoUri = intent.getData(); - postTitle = intent.getStringExtra(EXTRA_POST_TITLE); - isNSFW = intent.getBooleanExtra(EXTRA_IS_NSFW, false); - if (savedInstanceState == null) { - resumePosition = intent.getLongExtra(EXTRA_PROGRESS_SECONDS, -1); - } - - - if (postTitle != null) { - setTitle(Html.fromHtml(String.format("%s", postTitle))); - } else { - setTitle(""); - } - - videoPlayerView.setControllerVisibilityListener(visibility -> { - switch (visibility) { - case View.GONE: - getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE); - break; - case View.VISIBLE: - getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - } - }); - - TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); - trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); - player = ExoPlayerFactory.newSimpleInstance(this, trackSelector); - videoPlayerView.setPlayer(player); - videoType = getIntent().getIntExtra(EXTRA_VIDEO_TYPE, VIDEO_TYPE_NORMAL); - if (videoType == VIDEO_TYPE_GFYCAT || videoType == VIDEO_TYPE_REDGIFS) { - if (savedInstanceState != null) { - String videoUrl = savedInstanceState.getString(VIDEO_URI_STATE); - if (videoUrl != null) { - mVideoUri = Uri.parse(videoUrl); - } - videoDownloadUrl = savedInstanceState.getString(VIDEO_DOWNLOAD_URL_STATE); - } else { - mVideoUri = intent.getData(); - videoDownloadUrl = intent.getStringExtra(EXTRA_VIDEO_DOWNLOAD_URL); - } - - String gfycatId = intent.getStringExtra(EXTRA_GFYCAT_ID); - if (gfycatId != null && gfycatId.contains("-")) { - gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); - } - if (videoType == VIDEO_TYPE_GFYCAT) { - videoFileName = "Gfycat-" + gfycatId + ".mp4"; - } else { - videoFileName = "Redgifs-" + gfycatId + ".mp4"; - } - - if (mVideoUri == null) { - if (videoType == VIDEO_TYPE_GFYCAT) { - loadGfycatOrRedgifsVideo(gfycatRetrofit, gfycatId, savedInstanceState, true); - } else { - loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false); - } - } else { - dataSourceFactory = new DefaultDataSourceFactory(ViewVideoActivity.this, - Util.getUserAgent(ViewVideoActivity.this, "Infinity")); - player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); - preparePlayer(savedInstanceState); - } - } else if (videoType == VIDEO_TYPE_DIRECT) { - videoDownloadUrl = mVideoUri.toString(); - videoFileName = videoDownloadUrl.substring(videoDownloadUrl.lastIndexOf('/') + 1); - // Produces DataSource instances through which media data is loaded. - dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity")); - // Prepare the player with the source. - player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); - } else { - videoDownloadUrl = intent.getStringExtra(EXTRA_VIDEO_DOWNLOAD_URL); - subredditName = intent.getStringExtra(EXTRA_SUBREDDIT); - id = intent.getStringExtra(EXTRA_ID); - videoFileName = subredditName + "-" + id + ".mp4"; - // Produces DataSource instances through which media data is loaded. - dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity")); - // Prepare the player with the source. - player.prepare(new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); - } - - preparePlayer(savedInstanceState); - } - - private void preparePlayer(Bundle savedInstanceState) { - player.setRepeatMode(Player.REPEAT_MODE_ALL); - if (resumePosition > 0) { - player.seekTo(resumePosition); - } - player.setPlayWhenReady(true); - wasPlaying = true; - - boolean muteVideo = mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_VIDEO, false) || - (mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_NSFW_VIDEO, false) && isNSFW); - - if (savedInstanceState != null) { - isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); - if (isMute) { - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } else { - player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } - } else if (muteVideo) { - isMute = true; - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } else { - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } - - player.addListener(new Player.EventListener() { - @Override - public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - if (!trackGroups.isEmpty()) { - if (videoType == VIDEO_TYPE_NORMAL) { - if (isDataSavingMode) { - trackSelector.setParameters( - trackSelector.buildUponParameters() - .setMaxVideoSize(720, 720)); - } - - hdButton.setVisibility(View.VISIBLE); - hdButton.setOnClickListener(view -> { - TrackSelectionDialogBuilder build = new TrackSelectionDialogBuilder(ViewVideoActivity.this, getString(R.string.select_video_quality), trackSelector, 0); - build.setShowDisableOption(true); - build.setAllowAdaptiveSelections(false); - build.build().show(); - }); - } - - for (int i = 0; i < trackGroups.length; i++) { - String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; - if (mimeType != null && mimeType.contains("audio")) { - muteButton.setVisibility(View.VISIBLE); - muteButton.setOnClickListener(view -> { - if (isMute) { - isMute = false; - player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } else { - isMute = true; - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } - }); - break; - } - } - } else { - muteButton.setVisibility(View.GONE); - } - } - }); - } - - private void loadGfycatOrRedgifsVideo(Retrofit retrofit, String gfycatId, Bundle savedInstanceState, boolean needErrorHandling) { - progressBar.setVisibility(View.VISIBLE); - FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinks(retrofit, gfycatId, - new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { - @Override - public void success(String webm, String mp4) { - progressBar.setVisibility(View.GONE); - mVideoUri = Uri.parse(webm); - videoDownloadUrl = mp4; - dataSourceFactory = new DefaultDataSourceFactory(ViewVideoActivity.this, - Util.getUserAgent(ViewVideoActivity.this, "Infinity")); - player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); - preparePlayer(savedInstanceState); - } - - @Override - public void failed(int errorCode) { - progressBar.setVisibility(View.GONE); - if (videoType == VIDEO_TYPE_GFYCAT) { - if (errorCode == 404 && needErrorHandling) { - if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AUTOMATICALLY_TRY_REDGIFS, true)) { - loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false); - } else { - Snackbar.make(coordinatorLayout, R.string.load_video_in_redgifs, Snackbar.LENGTH_INDEFINITE).setAction(R.string.yes, - view -> loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false)).show(); - } - } else { - Toast.makeText(ViewVideoActivity.this, R.string.fetch_gfycat_video_failed, Toast.LENGTH_SHORT).show(); - } - } else { - Toast.makeText(ViewVideoActivity.this, R.string.fetch_redgifs_video_failed, Toast.LENGTH_SHORT).show(); - } - } - }); - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.view_video, menu); - return true; - } - - @Override - protected void onDestroy() { - super.onDestroy(); - player.release(); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case android.R.id.home: - finish(); - return true; - case R.id.action_download_view_video_activity: - if (isDownloading) { - return false; - } - - if (videoDownloadUrl == null) { - Toast.makeText(this, R.string.fetching_video_info_please_wait, Toast.LENGTH_SHORT).show(); - return true; - } - - isDownloading = true; - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(this, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - ActivityCompat.requestPermissions(this, - new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - return true; - } - - return false; - } - - @Override - protected void onStart() { - super.onStart(); - if (wasPlaying) { - player.setPlayWhenReady(true); - } - } - - @Override - protected void onStop() { - super.onStop(); - wasPlaying = player.getPlayWhenReady(); - player.setPlayWhenReady(false); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); - } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { - download(); - } - isDownloading = false; - } - } - - private void download() { - isDownloading = false; - - if (videoType != VIDEO_TYPE_NORMAL) { - Intent intent = new Intent(this, DownloadMediaService.class); - intent.putExtra(DownloadMediaService.EXTRA_URL, videoDownloadUrl); - intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_VIDEO); - intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, videoFileName); - intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, subredditName); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(intent); - } else { - startService(intent); - } - } else { - Intent intent = new Intent(this, DownloadRedditVideoService.class); - intent.putExtra(DownloadRedditVideoService.EXTRA_VIDEO_URL, videoDownloadUrl); - intent.putExtra(DownloadRedditVideoService.EXTRA_POST_ID, id); - intent.putExtra(DownloadRedditVideoService.EXTRA_SUBREDDIT, subredditName); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - startForegroundService(intent); - } else { - startService(intent); - } - } - Toast.makeText(this, R.string.download_started, Toast.LENGTH_SHORT).show(); - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(IS_MUTE_STATE, isMute); - if (mVideoUri != null) { - outState.putString(VIDEO_URI_STATE, mVideoUri.toString()); - outState.putString(VIDEO_DOWNLOAD_URL_STATE, videoDownloadUrl); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AcknowledgementRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AcknowledgementRecyclerViewAdapter.java deleted file mode 100644 index 3958054a..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AcknowledgementRecyclerViewAdapter.java +++ /dev/null @@ -1,70 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.Intent; -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.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Settings.Acknowledgement; - -public class AcknowledgementRecyclerViewAdapter extends RecyclerView.Adapter { - private ArrayList acknowledgements; - private Context context; - - public AcknowledgementRecyclerViewAdapter(Context context, ArrayList acknowledgements) { - this.context = context; - this.acknowledgements = acknowledgements; - } - - @NonNull - @Override - public AcknowledgementViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new AcknowledgementViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_acknowledgement, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull AcknowledgementViewHolder holder, int position) { - Acknowledgement acknowledgement = acknowledgements.get(holder.getAdapterPosition()); - if (acknowledgement != null) { - holder.nameTextView.setText(acknowledgement.getName()); - holder.introductionTextView.setText(acknowledgement.getIntroduction()); - holder.itemView.setOnClickListener(view -> { - if (context != null) { - Intent intent = new Intent(context, LinkResolverActivity.class); - intent.setData(acknowledgement.getLink()); - context.startActivity(intent); - } - }); - } - } - - @Override - public int getItemCount() { - return acknowledgements == null ? 0 : acknowledgements.size(); - } - - class AcknowledgementViewHolder extends RecyclerView.ViewHolder { - View itemView; - @BindView(R.id.name_text_view_item_acknowledgement) - TextView nameTextView; - @BindView(R.id.introduction_text_view_item_acknowledgement) - TextView introductionTextView; - - AcknowledgementViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - this.itemView = itemView; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AwardRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AwardRecyclerViewAdapter.java deleted file mode 100644 index b9cc42d7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/AwardRecyclerViewAdapter.java +++ /dev/null @@ -1,98 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -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 com.bumptech.glide.RequestManager; - -import java.util.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Award.Award; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import pl.droidsonroids.gif.GifImageView; - -public class AwardRecyclerViewAdapter extends RecyclerView.Adapter { - - private ArrayList awards; - private RequestManager glide; - private ItemOnClickListener itemOnClickListener; - private int primaryTextColor; - private int secondaryTextColor; - - public interface ItemOnClickListener { - void onClick(Award award); - } - - public AwardRecyclerViewAdapter(RequestManager glide, CustomThemeWrapper customThemeWrapper, - ItemOnClickListener itemOnClickListener) { - awards = Award.getAvailableAwards(); - this.glide = glide; - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - this.itemOnClickListener = itemOnClickListener; - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new AwardViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_award, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof AwardViewHolder) { - Award award = awards.get(position); - glide.load(award.getIconUrl()).into(((AwardViewHolder) holder).iconImageView); - ((AwardViewHolder) holder).nameTextView.setText(award.getName()); - ((AwardViewHolder) holder).desctiptionTextView.setText(award.getDescription()); - ((AwardViewHolder) holder).coinTextView.setText(Integer.toString(award.getCoinPrice())); - } - } - - @Override - public int getItemCount() { - return awards.size(); - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - super.onViewRecycled(holder); - if (holder instanceof AwardViewHolder) { - glide.clear(((AwardViewHolder) holder).iconImageView); - ((AwardViewHolder) holder).nameTextView.setText(""); - ((AwardViewHolder) holder).desctiptionTextView.setText(""); - } - } - - class AwardViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.icon_image_view_item_award) - GifImageView iconImageView; - @BindView(R.id.name_text_view_item_award) - TextView nameTextView; - @BindView(R.id.description_text_view_item_award) - TextView desctiptionTextView; - @BindView(R.id.coin_text_view_item_award) - TextView coinTextView; - - public AwardViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - nameTextView.setTextColor(primaryTextColor); - desctiptionTextView.setTextColor(secondaryTextColor); - coinTextView.setTextColor(primaryTextColor); - - itemView.setOnClickListener(view -> { - itemOnClickListener.onClick(awards.get(getAdapterPosition())); - }); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java deleted file mode 100644 index 0114560d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentAndPostRecyclerViewAdapter.java +++ /dev/null @@ -1,3887 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Color; -import android.graphics.ColorFilter; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.TextPaint; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -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.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.constraintlayout.widget.ConstraintSet; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.RequestBuilder; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.RequestOptions; -import com.bumptech.glide.request.target.Target; -import com.google.android.exoplayer2.metadata.Metadata; -import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.text.Cue; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; -import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; -import com.google.android.exoplayer2.ui.PlayerView; -import com.libRG.CustomTextView; -import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar; - -import org.commonmark.ext.gfm.tables.TableBlock; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import butterknife.BindView; -import butterknife.ButterKnife; -import im.ene.toro.CacheManager; -import im.ene.toro.ToroPlayer; -import im.ene.toro.ToroUtil; -import im.ene.toro.exoplayer.ExoCreator; -import im.ene.toro.exoplayer.ExoPlayerViewHelper; -import im.ene.toro.exoplayer.Playable; -import im.ene.toro.media.PlaybackInfo; -import im.ene.toro.widget.Container; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.recycler.MarkwonAdapter; -import io.noties.markwon.recycler.table.TableEntry; -import io.noties.markwon.recycler.table.TableEntryPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import jp.wasabeef.glide.transformations.BlurTransformation; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.Activity.CommentActivity; -import ml.docilealligator.infinityforreddit.Activity.FilteredThingActivity; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewImageOrGifActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPostDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewRedditGalleryActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewVideoActivity; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadSubredditIconAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadUserDataAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.CommentMoreBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.CopyTextBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.ShareLinkBottomSheetFragment; -import ml.docilealligator.infinityforreddit.Comment.Comment; -import ml.docilealligator.infinityforreddit.Comment.FetchComment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.CustomView.AspectRatioGifImageView; -import ml.docilealligator.infinityforreddit.CustomView.MarkwonLinearLayoutManager; -import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SaveThing; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import ml.docilealligator.infinityforreddit.VoteThing; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -import static ml.docilealligator.infinityforreddit.Activity.CommentActivity.WRITE_COMMENT_REQUEST_CODE; - -public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter implements CacheManager { - private static final int VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY = 1; - private static final int VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW = 2; - private static final int VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY = 3; - private static final int VIEW_TYPE_POST_DETAIL_LINK = 4; - private static final int VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK = 5; - private static final int VIEW_TYPE_POST_DETAIL_GALLERY = 6; - private static final int VIEW_TYPE_POST_DETAIL_TEXT_TYPE = 7; - private static final int VIEW_TYPE_FIRST_LOADING = 8; - private static final int VIEW_TYPE_FIRST_LOADING_FAILED = 9; - private static final int VIEW_TYPE_NO_COMMENT_PLACEHOLDER = 10; - private static final int VIEW_TYPE_COMMENT = 11; - private static final int VIEW_TYPE_COMMENT_FULLY_COLLAPSED = 12; - private static final int VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS = 13; - private static final int VIEW_TYPE_IS_LOADING_MORE_COMMENTS = 14; - private static final int VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED = 15; - private static final int VIEW_TYPE_VIEW_ALL_COMMENTS = 16; - - private AppCompatActivity mActivity; - private Retrofit mRetrofit; - private Retrofit mOauthRetrofit; - private Retrofit mGfycatRetrofit; - private Retrofit mRedgifsRetrofit; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private RequestManager mGlide; - private Markwon mPostDetailMarkwon; - private Markwon mCommentMarkwon; - private final MarkwonAdapter mMarkwonAdapter; - private int mImageViewWidth; - private String mAccessToken; - private String mAccountName; - private Post mPost; - private ArrayList mVisibleComments; - private String mSubredditNamePrefixed; - private Locale mLocale; - private String mSingleCommentId; - private boolean mIsSingleCommentThreadMode; - private boolean mNeedBlurNsfw; - private boolean mNeedBlurSpoiler; - private boolean mVoteButtonsOnTheRight; - private boolean mShowElapsedTime; - private String mTimeFormatPattern; - private boolean mExpandChildren; - private boolean mCommentToolbarHidden; - private boolean mCommentToolbarHideOnClick; - private boolean mSwapTapAndLong; - private boolean mShowCommentDivider; - private boolean mShowAbsoluteNumberOfVotes; - private boolean mAutoplay = false; - private boolean mAutoplayNsfwVideos; - private boolean mMuteAutoplayingVideos; - private boolean mFullyCollapseComment; - private double mStartAutoplayVisibleAreaOffset; - private boolean mMuteNSFWVideo; - private boolean mAutomaticallyTryRedgifs; - private boolean mDataSavingMode; - private boolean mDisableImagePreview; - private CommentRecyclerViewAdapterCallback mCommentRecyclerViewAdapterCallback; - private boolean isInitiallyLoading; - private boolean isInitiallyLoadingFailed; - private boolean mHasMoreComments; - private boolean loadMoreCommentsFailed; - - private int mColorPrimaryLightTheme; - private int mColorAccent; - private int mCircularProgressBarBackgroundColor; - private int mCardViewColor; - private int mSecondaryTextColor; - private int mPostTitleColor; - private int mPrimaryTextColor; - private int mCommentTextColor; - private int mCommentBackgroundColor; - private int mPostTypeBackgroundColor; - private int mPostTypeTextColor; - private int mDividerColor; - private int mSubredditColor; - private int mUsernameColor; - private int mSubmitterColor; - private int mModeratorColor; - private int mAuthorFlairTextColor; - private int mSpoilerBackgroundColor; - private int mSpoilerTextColor; - private int mFlairBackgroundColor; - private int mFlairTextColor; - private int mNSFWBackgroundColor; - private int mNSFWTextColor; - private int mArchivedTintColor; - private int mLockedTintColor; - private int mCrosspostTintColor; - private int mNoPreviewPostTypeBackgroundColor; - private int mNoPreviewPostTypeIconTint; - private int mUpvotedColor; - private int mDownvotedColor; - private int mCommentVerticalBarColor1; - private int mCommentVerticalBarColor2; - private int mCommentVerticalBarColor3; - private int mCommentVerticalBarColor4; - private int mCommentVerticalBarColor5; - private int mCommentVerticalBarColor6; - private int mCommentVerticalBarColor7; - private int mSingleCommentThreadBackgroundColor; - private int mVoteAndReplyUnavailableVoteButtonColor; - private int mButtonTextColor; - private int mPostIconAndInfoColor; - private int mCommentIconAndInfoColor; - private int mFullyCollapsedCommentBackgroundColor; - private int mAwardedCommentBackgroundColor; - - private Drawable mCommentIcon; - private float mScale; - private ShareLinkBottomSheetFragment mShareLinkBottomSheetFragment; - private CopyTextBottomSheetFragment mCopyTextBottomSheetFragment; - private ExoCreator mExoCreator; - - public CommentAndPostRecyclerViewAdapter(AppCompatActivity activity, CustomThemeWrapper customThemeWrapper, - Retrofit retrofit, Retrofit oauthRetrofit, Retrofit gfycatRetrofit, - Retrofit redgifsRetrofit, - RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide, - int imageViewWidth, String accessToken, String accountName, - Post post, Locale locale, String singleCommentId, - boolean isSingleCommentThreadMode, - SharedPreferences sharedPreferences, - SharedPreferences nsfwAndSpoilerSharedPreferences, ExoCreator exoCreator, - CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) { - mActivity = activity; - mRetrofit = retrofit; - mOauthRetrofit = oauthRetrofit; - mGfycatRetrofit = gfycatRetrofit; - mRedgifsRetrofit = redgifsRetrofit; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mGlide = glide; - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - mCommentTextColor = customThemeWrapper.getCommentColor(); - int commentSpoilerBackgroundColor = mCommentTextColor | 0xFF000000; - int markdownColor = customThemeWrapper.getPostContentColor(); - int postSpoilerBackgroundColor = markdownColor | 0xFF000000; - int linkColor = customThemeWrapper.getLinkColor(); - mPostDetailMarkwon = Markwon.builder(mActivity) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - while (matcher.find()) { - markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); - } - - @Override - public void afterSetText(@NonNull TextView textView) { - textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(markdownColor); - } else { - ds.bgColor = postSpoilerBackgroundColor; - ds.setColor(markdownColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - textView.setTextColor(markdownColor); - textView.setOnLongClickListener(view -> { - Bundle bundle = new Bundle(); - bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, mPost.getSelfTextPlain()); - bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, mPost.getSelfText()); - mCopyTextBottomSheetFragment.setArguments(bundle); - mCopyTextBottomSheetFragment.show(mActivity.getSupportFragmentManager(), mCopyTextBottomSheetFragment.getTag()); - return true; - }); - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .usePlugin(TableEntryPlugin.create(mActivity)) - .build(); - mCommentMarkwon = Markwon.builder(mActivity) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - while (matcher.find()) { - markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); - } - - @Override - public void afterSetText(@NonNull TextView textView) { - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(mCommentTextColor); - } else { - ds.bgColor = commentSpoilerBackgroundColor; - ds.setColor(mCommentTextColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcher.end() - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(linkColor); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .build(); - mMarkwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); - mImageViewWidth = imageViewWidth; - mAccessToken = accessToken; - mAccountName = accountName; - mPost = post; - mVisibleComments = new ArrayList<>(); - mSubredditNamePrefixed = post.getSubredditNamePrefixed(); - mLocale = locale; - mSingleCommentId = singleCommentId; - mIsSingleCommentThreadMode = isSingleCommentThreadMode; - - mNeedBlurNsfw = nsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, true); - mNeedBlurSpoiler = nsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + 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); - mExpandChildren = !sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_TOP_LEVEL_COMMENTS_FIRST, false); - mCommentToolbarHidden = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDDEN, false); - mCommentToolbarHideOnClick = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDE_ON_CLICK, true); - mSwapTapAndLong = sharedPreferences.getBoolean(SharedPreferencesUtils.SWAP_TAP_AND_LONG_COMMENTS, false); - mShowCommentDivider = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_COMMENT_DIVIDER, false); - 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); - mFullyCollapseComment = sharedPreferences.getBoolean(SharedPreferencesUtils.FULLY_COLLAPSE_COMMENT, 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); - - 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); - - mCommentRecyclerViewAdapterCallback = commentRecyclerViewAdapterCallback; - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - mHasMoreComments = false; - loadMoreCommentsFailed = false; - mScale = resources.getDisplayMetrics().density; - - mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); - mColorAccent = customThemeWrapper.getColorAccent(); - mCircularProgressBarBackgroundColor = customThemeWrapper.getCircularProgressBarBackground(); - mCardViewColor = customThemeWrapper.getCardViewBackgroundColor(); - mPostTitleColor = customThemeWrapper.getPostTitleColor(); - mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); - mDividerColor = customThemeWrapper.getDividerColor(); - mCommentBackgroundColor = customThemeWrapper.getCommentBackgroundColor(); - mPostTypeBackgroundColor = customThemeWrapper.getPostTypeBackgroundColor(); - mPostTypeTextColor = customThemeWrapper.getPostTypeTextColor(); - mSubmitterColor = customThemeWrapper.getSubmitter(); - mModeratorColor = customThemeWrapper.getModerator(); - mAuthorFlairTextColor = customThemeWrapper.getAuthorFlairTextColor(); - mSpoilerBackgroundColor = customThemeWrapper.getSpoilerBackgroundColor(); - mSpoilerTextColor = customThemeWrapper.getSpoilerTextColor(); - mNSFWBackgroundColor = customThemeWrapper.getNsfwBackgroundColor(); - mNSFWTextColor = customThemeWrapper.getNsfwTextColor(); - mArchivedTintColor = customThemeWrapper.getArchivedIconTint(); - mLockedTintColor = customThemeWrapper.getLockedIconTint(); - mCrosspostTintColor = customThemeWrapper.getCrosspostIconTint(); - mNoPreviewPostTypeBackgroundColor = customThemeWrapper.getNoPreviewPostTypeBackgroundColor(); - mNoPreviewPostTypeIconTint = customThemeWrapper.getNoPreviewPostTypeIconTint(); - mFlairBackgroundColor = customThemeWrapper.getFlairBackgroundColor(); - mFlairTextColor = customThemeWrapper.getFlairTextColor(); - mSubredditColor = customThemeWrapper.getSubreddit(); - mUsernameColor = customThemeWrapper.getUsername(); - mUpvotedColor = customThemeWrapper.getUpvoted(); - mDownvotedColor = customThemeWrapper.getDownvoted(); - mCommentVerticalBarColor1 = customThemeWrapper.getCommentVerticalBarColor1(); - mCommentVerticalBarColor2 = customThemeWrapper.getCommentVerticalBarColor2(); - mCommentVerticalBarColor3 = customThemeWrapper.getCommentVerticalBarColor3(); - mCommentVerticalBarColor4 = customThemeWrapper.getCommentVerticalBarColor4(); - mCommentVerticalBarColor5 = customThemeWrapper.getCommentVerticalBarColor5(); - mCommentVerticalBarColor6 = customThemeWrapper.getCommentVerticalBarColor6(); - mCommentVerticalBarColor7 = customThemeWrapper.getCommentVerticalBarColor7(); - mSingleCommentThreadBackgroundColor = customThemeWrapper.getSingleCommentThreadBackgroundColor(); - mVoteAndReplyUnavailableVoteButtonColor = customThemeWrapper.getVoteAndReplyUnavailableButtonColor(); - mButtonTextColor = customThemeWrapper.getButtonTextColor(); - mPostIconAndInfoColor = customThemeWrapper.getPostIconAndInfoColor(); - mCommentIconAndInfoColor = customThemeWrapper.getCommentIconAndInfoColor(); - mFullyCollapsedCommentBackgroundColor = customThemeWrapper.getFullyCollapsedCommentBackgroundColor(); - mAwardedCommentBackgroundColor = customThemeWrapper.getAwardedCommentBackgroundColor(); - - mCommentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); - if (mCommentIcon != null) { - DrawableCompat.setTint(mCommentIcon, mPostIconAndInfoColor); - } - - mShareLinkBottomSheetFragment = new ShareLinkBottomSheetFragment(); - mCopyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); - mExoCreator = exoCreator; - } - - @Override - public int getItemViewType(int position) { - if (position == 0) { - switch (mPost.getPostType()) { - case Post.VIDEO_TYPE: - if (mAutoplay) { - if (!mAutoplayNsfwVideos && mPost.isNSFW()) { - return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; - } - return VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY; - } else { - return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; - } - case Post.GIF_TYPE: - if (mAutoplay) { - if (!mAutoplayNsfwVideos && mPost.isNSFW()) { - return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; - } - return VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY; - } else { - return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; - } - case Post.IMAGE_TYPE: - return VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY; - case Post.LINK_TYPE: - return VIEW_TYPE_POST_DETAIL_LINK; - case Post.NO_PREVIEW_LINK_TYPE: - return VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK; - case Post.GALLERY_TYPE: - return VIEW_TYPE_POST_DETAIL_GALLERY; - default: - return VIEW_TYPE_POST_DETAIL_TEXT_TYPE; - } - } - - if (mVisibleComments.size() == 0) { - if (position == 1) { - if (isInitiallyLoading) { - return VIEW_TYPE_FIRST_LOADING; - } else if (isInitiallyLoadingFailed) { - return VIEW_TYPE_FIRST_LOADING_FAILED; - } else { - return VIEW_TYPE_NO_COMMENT_PLACEHOLDER; - } - } - } - - if (mIsSingleCommentThreadMode) { - if (position == 1) { - return VIEW_TYPE_VIEW_ALL_COMMENTS; - } - - if (position == mVisibleComments.size() + 2) { - if (mHasMoreComments) { - return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; - } else { - return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; - } - } - - Comment comment = mVisibleComments.get(position - 2); - if (!comment.isPlaceHolder()) { - if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { - return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; - } - return VIEW_TYPE_COMMENT; - } else { - return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; - } - } else { - if (position == mVisibleComments.size() + 1) { - if (mHasMoreComments) { - return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; - } else { - return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; - } - } - - Comment comment = mVisibleComments.get(position - 1); - if (!comment.isPlaceHolder()) { - if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { - return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; - } - return VIEW_TYPE_COMMENT; - } else { - return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; - } - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - switch (viewType) { - case VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY: - if (mDataSavingMode) { - if (mDisableImagePreview) { - return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); - } - return new PostDetailVideoAndGifPreviewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_video_and_gif_preview, parent, false)); - } - return new PostDetailVideoAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_video_autoplay, parent, false)); - case VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW: - if (mDataSavingMode && mDisableImagePreview) { - return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); - } - return new PostDetailVideoAndGifPreviewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_video_and_gif_preview, parent, false)); - case VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY: - if (mDataSavingMode && mDisableImagePreview) { - return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); - } - return new PostDetailImageAndGifAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_image_and_gif_autoplay, parent, false)); - case VIEW_TYPE_POST_DETAIL_LINK: - if (mDataSavingMode && mDisableImagePreview) { - return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); - } - return new PostDetailLinkViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_link, parent, false)); - case VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK: - return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); - case VIEW_TYPE_POST_DETAIL_GALLERY: - return new PostDetailGalleryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_gallery, parent, false)); - case VIEW_TYPE_POST_DETAIL_TEXT_TYPE: - return new PostDetailTextViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_text, parent, false)); - case VIEW_TYPE_FIRST_LOADING: - return new LoadCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments, parent, false)); - case VIEW_TYPE_FIRST_LOADING_FAILED: - return new LoadCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments_failed_placeholder, parent, false)); - case VIEW_TYPE_NO_COMMENT_PLACEHOLDER: - return new NoCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_no_comment_placeholder, parent, false)); - case VIEW_TYPE_COMMENT: - return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); - case VIEW_TYPE_COMMENT_FULLY_COLLAPSED: - return new CommentFullyCollapsedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_fully_collapsed, parent, false)); - case VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS: - return new LoadMoreChildCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_more_comments_placeholder, parent, false)); - case VIEW_TYPE_IS_LOADING_MORE_COMMENTS: - return new IsLoadingMoreCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_loading, parent, false)); - case VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED: - return new LoadMoreCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_error, parent, false)); - default: - return new ViewAllCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_all_comments, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof PostDetailBaseViewHolder) { - ((PostDetailBaseViewHolder) holder).mTitleTextView.setText(mPost.getTitle()); - if (mPost.getSubredditNamePrefixed().startsWith("u/")) { - if (mPost.getAuthorIconUrl() == null) { - String authorName = mPost.getAuthor().equals("[deleted]") ? mPost.getSubredditNamePrefixed().substring(2) : mPost.getAuthor(); - new LoadUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), authorName, mOauthRetrofit, iconImageUrl -> { - if (mActivity != null && getItemCount() > 0) { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } - - if (holder.getAdapterPosition() >= 0) { - mPost.setAuthorIconUrl(iconImageUrl); - } - } - }).execute(); - } else if (!mPost.getAuthorIconUrl().equals("")) { - mGlide.load(mPost.getAuthorIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } - } else { - if (mPost.getSubredditIconUrl() == null) { - new LoadSubredditIconAsyncTask( - mRedditDataRoomDatabase, mPost.getSubredditNamePrefixed().substring(2), - mRetrofit, iconImageUrl -> { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } - - mPost.setSubredditIconUrl(iconImageUrl); - }).execute(); - } else if (!mPost.getSubredditIconUrl().equals("")) { - mGlide.load(mPost.getSubredditIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); - } - } - - if (mPost.getAuthorFlairHTML() != null && !mPost.getAuthorFlairHTML().equals("")) { - ((PostDetailBaseViewHolder) holder).mAuthorFlairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mAuthorFlairTextView, mPost.getAuthorFlairHTML(), true); - } else if (mPost.getAuthorFlair() != null && !mPost.getAuthorFlair().equals("")) { - ((PostDetailBaseViewHolder) holder).mAuthorFlairTextView.setVisibility(View.VISIBLE); - ((PostDetailBaseViewHolder) holder).mAuthorFlairTextView.setText(mPost.getAuthorFlair()); - } - - switch (mPost.getVoteType()) { - case 1: - //Upvote - ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mUpvotedColor); - break; - case -1: - //Downvote - ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mDownvotedColor); - break; - case 0: - ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mPostIconAndInfoColor); - } - - if (mPost.isArchived()) { - ((PostDetailBaseViewHolder) holder).mUpvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mDownvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (mPost.isCrosspost()) { - ((PostDetailBaseViewHolder) holder).mCrosspostImageView.setVisibility(View.VISIBLE); - } - - ((PostDetailBaseViewHolder) holder).mSubredditTextView.setText(mPost.getSubredditNamePrefixed()); - ((PostDetailBaseViewHolder) holder).mUserTextView.setText(mPost.getAuthorNamePrefixed()); - - if (mShowElapsedTime) { - ((PostDetailBaseViewHolder) holder).mPostTimeTextView.setText( - Utils.getElapsedTime(mActivity, mPost.getPostTimeMillis())); - } else { - ((PostDetailBaseViewHolder) holder).mPostTimeTextView.setText(Utils.getFormattedTime(mLocale, mPost.getPostTimeMillis(), mTimeFormatPattern)); - } - - if (mPost.isArchived()) { - ((PostDetailBaseViewHolder) holder).mArchivedImageView.setVisibility(View.VISIBLE); - } - - if (mPost.isLocked()) { - ((PostDetailBaseViewHolder) holder).mLockedImageView.setVisibility(View.VISIBLE); - } - - if (mPost.isSpoiler()) { - ((PostDetailBaseViewHolder) holder).mSpoilerTextView.setVisibility(View.VISIBLE); - } - - if (mPost.getFlair() != null && !mPost.getFlair().equals("")) { - ((PostDetailBaseViewHolder) holder).mFlairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mFlairTextView, mPost.getFlair(), false); - } - - if (mPost.getAwards() != null && !mPost.getAwards().equals("")) { - ((PostDetailBaseViewHolder) holder).mAwardsTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mAwardsTextView, mPost.getAwards(), true); - } - - if (mPost.isNSFW()) { - ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.VISIBLE); - } else { - ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.GONE); - } - - ((PostDetailBaseViewHolder) holder).mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, mPost.getScore() + mPost.getVoteType())); - - ((PostDetailBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(mPost.getNComments())); - - if (mPost.isSaved()) { - ((PostDetailBaseViewHolder) holder).mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - } else { - ((PostDetailBaseViewHolder) holder).mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - } - - if (holder instanceof PostDetailVideoAutoplayViewHolder) { - ((PostDetailVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); - Post.Preview preview = getSuitablePreview(mPost.getPreviews()); - if (preview != null) { - ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); - if (mImageViewWidth > preview.getPreviewWidth()) { - mGlide.load(preview.getPreviewUrl()).override(Target.SIZE_ORIGINAL).into(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); - } else { - mGlide.load(preview.getPreviewUrl()).into(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); - } - } else { - ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); - } - ((PostDetailVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (mPost.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); - - if (mPost.isGfycat() || mPost.isRedgifs() && !mPost.isLoadGfyOrRedgifsVideoSuccess()) { - ((PostDetailVideoAutoplayViewHolder) holder).mTypeTextView.setText("GFYCAT"); - ((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks = new FetchGfycatOrRedgifsVideoLinks(new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { - @Override - public void success(String webm, String mp4) { - mPost.setVideoDownloadUrl(mp4); - mPost.setVideoUrl(webm); - mPost.setLoadGfyOrRedgifsVideoSuccess(true); - ((PostDetailVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(mPost.getVideoUrl())); - } - - @Override - public void failed(int errorCode) { - ((PostDetailVideoAutoplayViewHolder) holder).mErrorLoadingGfycatImageView.setVisibility(View.VISIBLE); - } - }); - ((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks - .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mGfycatRetrofit, mRedgifsRetrofit, - mPost.getGfycatId(), mPost.isGfycat(), mAutomaticallyTryRedgifs); - } else { - ((PostDetailVideoAutoplayViewHolder) holder).mTypeTextView.setText("VIDEO"); - ((PostDetailVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(mPost.getVideoUrl())); - } - } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { - if (mPost.getPostType() == Post.GIF_TYPE) { - ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.gif)); - } else { - ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.video)); - } - Post.Preview preview = getSuitablePreview(mPost.getPreviews()); - if (preview != null) { - ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / (float) preview.getPreviewWidth()); - loadImage((PostDetailVideoAndGifPreviewHolder) holder, preview); - } - } else if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { - if (mPost.getPostType() == Post.IMAGE_TYPE) { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.image); - } else { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.gif); - } - - Post.Preview preview = getSuitablePreview(mPost.getPreviews()); - if (preview != null) { - if (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0) { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP); - ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.getLayoutParams().height = (int) (400 * mScale); - } else { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / (float) preview.getPreviewWidth()); - } - loadImage((PostDetailImageAndGifAutoplayViewHolder) holder, preview); - } - } else if (holder instanceof PostDetailLinkViewHolder) { - String domain = Uri.parse(mPost.getUrl()).getHost(); - ((PostDetailLinkViewHolder) holder).mLinkTextView.setText(domain); - Post.Preview preview = getSuitablePreview(mPost.getPreviews()); - if (preview != null) { - ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / (float) preview.getPreviewWidth()); - loadImage((PostDetailLinkViewHolder) holder, preview); - } - - } else if (holder instanceof PostDetailNoPreviewViewHolder) { - if (mPost.getPostType() == Post.LINK_TYPE || mPost.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { - String noPreviewLinkDomain = Uri.parse(mPost.getUrl()).getHost(); - ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setVisibility(View.VISIBLE); - ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setText(noPreviewLinkDomain); - } else { - ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setVisibility(View.GONE); - switch (mPost.getPostType()) { - case Post.VIDEO_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.video); - ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_outline_video_24dp); - break; - case Post.IMAGE_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.image); - ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_image_24dp); - break; - case Post.GIF_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gif); - ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_image_24dp); - break; - case Post.LINK_TYPE: - case Post.NO_PREVIEW_LINK_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.link); - break; - case Post.GALLERY_TYPE: - ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gallery); - ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_gallery_24dp); - break; - } - } - - if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) { - ((PostDetailNoPreviewViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); - LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { - @Override - public void onScrolledLeft() { - ((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack(); - } - - @Override - public void onScrolledRight() { - ((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack(); - } - }); - ((PostDetailNoPreviewViewHolder) holder).mContentMarkdownView.setLayoutManager(linearLayoutManager); - ((PostDetailNoPreviewViewHolder) holder).mContentMarkdownView.setAdapter(mMarkwonAdapter); - mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, mPost.getSelfText()); - mMarkwonAdapter.notifyDataSetChanged(); - } - } else if (holder instanceof PostDetailGalleryViewHolder) { - Post.Preview preview = getSuitablePreview(mPost.getPreviews()); - if (preview != null) { - ((PostDetailGalleryViewHolder) holder).mRelativeLayout.setVisibility(View.VISIBLE); - ((PostDetailGalleryViewHolder) holder).mImageView - .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); - - loadImage((PostDetailGalleryViewHolder) holder, preview); - } else { - ((PostDetailGalleryViewHolder) holder).mNoPreviewPostTypeImageView.setVisibility(View.VISIBLE); - } - } else if (holder instanceof PostDetailTextViewHolder) { - if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) { - ((PostDetailTextViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); - LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { - @Override - public void onScrolledLeft() { - ((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack(); - } - - @Override - public void onScrolledRight() { - ((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack(); - } - }); - ((PostDetailTextViewHolder) holder).mContentMarkdownView.setLayoutManager(linearLayoutManager); - ((PostDetailTextViewHolder) holder).mContentMarkdownView.setAdapter(mMarkwonAdapter); - mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, mPost.getSelfText()); - mMarkwonAdapter.notifyDataSetChanged(); - } - } - } else if (holder instanceof CommentViewHolder) { - Comment comment; - if (mIsSingleCommentThreadMode) { - comment = mVisibleComments.get(holder.getAdapterPosition() - 2); - } else { - comment = mVisibleComments.get(holder.getAdapterPosition() - 1); - } - - if (mIsSingleCommentThreadMode && comment.getId().equals(mSingleCommentId)) { - ((CommentViewHolder) holder).itemView.setBackgroundColor(mSingleCommentThreadBackgroundColor); - } else if (comment.getAwards() != null && !comment.getAwards().equals("")) { - ((CommentViewHolder) holder).itemView.setBackgroundColor(mAwardedCommentBackgroundColor); - } - - String authorPrefixed = "u/" + comment.getAuthor(); - ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed); - - if (comment.getAuthorFlairHTML() != null && !comment.getAuthorFlairHTML().equals("")) { - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).authorFlairTextView, comment.getAuthorFlairHTML(), true); - } else if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); - ((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair()); - } - - if (comment.isSubmitter()) { - ((CommentViewHolder) holder).authorTextView.setTextColor(mSubmitterColor); - Drawable submitterDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_mic_14dp, mSubmitterColor); - ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( - submitterDrawable, null, null, null); - } else if (comment.isModerator()) { - ((CommentViewHolder) holder).authorTextView.setTextColor(mModeratorColor); - Drawable moderatorDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_verified_user_14dp, mModeratorColor); - ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( - moderatorDrawable, null, null, null); - } - - if (mShowElapsedTime) { - ((CommentViewHolder) holder).commentTimeTextView.setText( - Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); - } else { - ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); - } - - if (mCommentToolbarHidden) { - ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = 0; - ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.VISIBLE); - } else { - ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; - ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.GONE); - } - - if (comment.getAwards() != null && !comment.getAwards().equals("")) { - ((CommentViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).awardsTextView, comment.getAwards(), true); - } - - mCommentMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentMarkdown()); - ((CommentViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - ((CommentViewHolder) holder).topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - - ((CommentViewHolder) holder).itemView.setPadding(comment.getDepth() * 8, 0, 0, 0); - if (comment.getDepth() > 0) { - switch (comment.getDepth() % 7) { - case 0: - ((CommentViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor7); - break; - case 1: - ((CommentViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor1); - break; - case 2: - ((CommentViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor2); - break; - case 3: - ((CommentViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor3); - break; - case 4: - ((CommentViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor4); - break; - case 5: - ((CommentViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor5); - break; - case 6: - ((CommentViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor6); - break; - } - ViewGroup.LayoutParams params = ((CommentViewHolder) holder).verticalBlock.getLayoutParams(); - params.width = 8; - ((CommentViewHolder) holder).verticalBlock.setLayoutParams(params); - } - - if (comment.hasReply()) { - if (comment.isExpanded()) { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); - } else { - ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); - } - ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); - } - - switch (comment.getVoteType()) { - case Comment.VOTE_TYPE_UPVOTE: - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); - break; - case Comment.VOTE_TYPE_DOWNVOTE: - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); - break; - } - - if (mPost.isArchived()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (mPost.isLocked()) { - ((CommentViewHolder) holder).replyButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, - android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (comment.isSaved()) { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - } else { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - } - } else if (holder instanceof CommentFullyCollapsedViewHolder) { - Comment comment; - if (mIsSingleCommentThreadMode) { - comment = mVisibleComments.get(holder.getAdapterPosition() - 2); - } else { - comment = mVisibleComments.get(holder.getAdapterPosition() - 1); - } - - String authorWithPrefix = "u/" + comment.getAuthor(); - ((CommentFullyCollapsedViewHolder) holder).usernameTextView.setText(authorWithPrefix); - if (mShowElapsedTime) { - ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); - } else { - ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); - } - ((CommentFullyCollapsedViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType()))); - - ((CommentFullyCollapsedViewHolder) holder).itemView.setPadding(comment.getDepth() * 8, 0, 0, 0); - if (comment.getDepth() > 0) { - switch (comment.getDepth() % 7) { - case 0: - ((CommentFullyCollapsedViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor7); - break; - case 1: - ((CommentFullyCollapsedViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor1); - break; - case 2: - ((CommentFullyCollapsedViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor2); - break; - case 3: - ((CommentFullyCollapsedViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor3); - break; - case 4: - ((CommentFullyCollapsedViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor4); - break; - case 5: - ((CommentFullyCollapsedViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor5); - break; - case 6: - ((CommentFullyCollapsedViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor6); - break; - } - ViewGroup.LayoutParams params = ((CommentFullyCollapsedViewHolder) holder).verticalBlock.getLayoutParams(); - params.width = 8; - ((CommentFullyCollapsedViewHolder) holder).verticalBlock.setLayoutParams(params); - } - } else if (holder instanceof LoadMoreChildCommentsViewHolder) { - Comment placeholder; - placeholder = mIsSingleCommentThreadMode ? mVisibleComments.get(holder.getAdapterPosition() - 2) - : mVisibleComments.get(holder.getAdapterPosition() - 1); - - ((LoadMoreChildCommentsViewHolder) holder).itemView.setPadding(placeholder.getDepth() * 8, 0, 0, 0); - if (placeholder.getDepth() > 0) { - switch (placeholder.getDepth() % 7) { - case 0: - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor7); - break; - case 1: - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor1); - break; - case 2: - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor2); - break; - case 3: - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor3); - break; - case 4: - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor4); - break; - case 5: - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor5); - break; - case 6: - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock - .setBackgroundColor(mCommentVerticalBarColor6); - break; - } - - ViewGroup.LayoutParams params = ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.getLayoutParams(); - params.width = 8; - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.setLayoutParams(params); - } - - if (placeholder.isLoadingMoreChildren()) { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); - } else if (placeholder.isLoadMoreChildrenFailed()) { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); - } else { - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); - } - - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { - int commentPosition = mIsSingleCommentThreadMode ? holder.getAdapterPosition() - 2 : holder.getAdapterPosition() - 1; - int parentPosition = getParentPosition(commentPosition); - if (parentPosition >= 0) { - Comment parentComment = mVisibleComments.get(parentPosition); - - mVisibleComments.get(commentPosition).setLoadingMoreChildren(true); - mVisibleComments.get(commentPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); - - Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; - FetchComment.fetchMoreComment(retrofit, mAccessToken, parentComment.getMoreChildrenFullnames(), - parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1, - mExpandChildren, mLocale, - new FetchComment.FetchMoreCommentListener() { - @Override - public void onFetchMoreCommentSuccess(ArrayList expandedComments, - int childrenStartingIndex) { - if (mVisibleComments.size() > parentPosition - && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { - if (mVisibleComments.get(parentPosition).isExpanded()) { - if (mVisibleComments.get(parentPosition).getChildren().size() > childrenStartingIndex) { - mVisibleComments.get(parentPosition).setMoreChildrenStartingIndex(childrenStartingIndex); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadMoreChildrenFailed(false); - - int placeholderPosition = commentPosition; - if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } else { - mVisibleComments.get(parentPosition).getChildren() - .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); - mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); - - int placeholderPosition = commentPosition; - if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.remove(placeholderPosition); - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(placeholderPosition + 2); - } else { - notifyItemRemoved(placeholderPosition + 1); - } - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } - } else { - if (mVisibleComments.get(parentPosition).hasReply() && mVisibleComments.get(parentPosition).getChildren().size() <= childrenStartingIndex) { - mVisibleComments.get(parentPosition).getChildren() - .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); - mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); - } - } - - mVisibleComments.get(parentPosition).addChildren(expandedComments); - } else { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - if (mVisibleComments.get(i).isExpanded()) { - int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); - - if (!mVisibleComments.get(i).getFullName() - .equals(mVisibleComments.get(placeholderPosition).getFullName())) { - for (int j = i + 1; j < mVisibleComments.size(); j++) { - if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { - placeholderPosition = j; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); - - mVisibleComments.addAll(placeholderPosition, expandedComments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); - } else { - notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); - } - } - - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) - .setLoadMoreChildrenFailed(false); - mVisibleComments.get(i).addChildren(expandedComments); - - break; - } - } - } - } - - @Override - public void onFetchMoreCommentFailed() { - if (parentPosition < mVisibleComments.size() - && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { - if (mVisibleComments.get(parentPosition).isExpanded()) { - int commentPosition = mIsSingleCommentThreadMode ? holder.getAdapterPosition() - 2 : holder.getAdapterPosition() - 1; - int placeholderPosition = commentPosition; - if (commentPosition >= mVisibleComments.size() || commentPosition < 0 || !mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { - for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - placeholderPosition = i; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); - } - - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadingMoreChildren(false); - mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) - .setLoadMoreChildrenFailed(true); - } else { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { - if (mVisibleComments.get(i).isExpanded()) { - int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); - if (!mVisibleComments.get(placeholderPosition).getFullName().equals(mVisibleComments.get(i).getFullName())) { - for (int j = i + 1; j < mVisibleComments.size(); j++) { - if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { - placeholderPosition = j; - break; - } - } - } - - mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); - mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); - ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); - } - - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadingMoreChildren(false); - mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadMoreChildrenFailed(true); - - break; - } - } - } - } - }); - } - }); - } - } - - @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() >= 65 * 1000 * 1000) { - for (int i = previews.size() - 1; i >= 1; i--) { - preview = previews.get(i); - if (mImageViewWidth >= preview.getPreviewWidth()) { - if (preview.getPreviewWidth() * preview.getPreviewHeight() <= 75 * 1000 * 1000) { - return preview; - } - } else { - int height = mImageViewWidth / preview.getPreviewWidth() * preview.getPreviewHeight(); - if (mImageViewWidth * height <= 75 * 1000 * 1000) { - return preview; - } - } - } - } - - int divisor = 2; - while (preview.getPreviewWidth() * preview.getPreviewHeight() / divisor / divisor > 75 * 1000 * 1000) { - preview.setPreviewWidth(preview.getPreviewWidth() / divisor); - preview.setPreviewHeight(preview.getPreviewHeight() / divisor); - divisor *= 2; - } - - return preview; - } - - return null; - } - - private void loadImage(PostDetailBaseViewHolder holder, @NonNull Post.Preview preview) { - if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { - String url = mPost.getPostType() == Post.IMAGE_TYPE ? preview.getPreviewUrl() : mPost.getUrl(); - RequestBuilder imageRequestBuilder = mGlide.load(url) - .listener(new RequestListener() { - @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); - loadImage(holder, preview); - }); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); - return false; - } - }); - - if ((mPost.isNSFW() && mNeedBlurNsfw && !(mPost.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { - imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); - } else { - if (mImageViewWidth > preview.getPreviewWidth()) { - imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); - } else { - imageRequestBuilder.into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); - } - } - } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { - RequestBuilder imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) - .listener(new RequestListener() { - @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); - loadImage(holder, preview); - }); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((PostDetailVideoAndGifPreviewHolder) holder).mLoadWrapper.setVisibility(View.GONE); - return false; - } - }); - - if ((mPost.isNSFW() && mNeedBlurNsfw) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { - imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) - .into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); - } else { - if (mImageViewWidth > preview.getPreviewWidth()) { - imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); - } else { - imageRequestBuilder.into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); - } - } - } else if (holder instanceof PostDetailLinkViewHolder) { - RequestBuilder imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) - .listener(new RequestListener() { - @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); - loadImage(holder, preview); - }); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((PostDetailLinkViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); - return false; - } - }); - - if ((mPost.isNSFW() && mNeedBlurNsfw) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { - imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) - .into(((PostDetailLinkViewHolder) holder).mImageView); - } else { - if (mImageViewWidth > preview.getPreviewWidth()) { - imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailLinkViewHolder) holder).mImageView); - } else { - imageRequestBuilder.into(((PostDetailLinkViewHolder) holder).mImageView); - } - } - } else if (holder instanceof PostDetailGalleryViewHolder) { - RequestBuilder imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) - .listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - ((PostDetailGalleryViewHolder) holder).mLoadImageProgressBar.setVisibility(View.GONE); - ((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.VISIBLE); - ((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setOnClickListener(view -> { - ((PostDetailGalleryViewHolder) holder).mLoadImageProgressBar.setVisibility(View.VISIBLE); - ((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.GONE); - loadImage(holder, preview); - }); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((PostDetailGalleryViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); - return false; - } - }); - - if ((mPost.isNSFW() && mNeedBlurNsfw && !(mPost.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { - imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailGalleryViewHolder) holder).mImageView); - } else { - if (mImageViewWidth > preview.getPreviewWidth()) { - imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailGalleryViewHolder) holder).mImageView); - } else { - imageRequestBuilder.into(((PostDetailGalleryViewHolder) holder).mImageView); - } - } - } - } - - public void updatePost(Post post) { - mPost = post; - notifyItemChanged(0); - } - - private int getParentPosition(int position) { - if (position >= 0 && position < mVisibleComments.size()) { - int childDepth = mVisibleComments.get(position).getDepth(); - for (int i = position; i >= 0; i--) { - if (mVisibleComments.get(i).getDepth() < childDepth) { - return i; - } - } - } - return -1; - } - - private void expandChildren(ArrayList comments, ArrayList newList, int position) { - if (comments != null && comments.size() > 0) { - newList.addAll(position, comments); - for (int i = 0; i < comments.size(); i++) { - position++; - if (comments.get(i).getChildren() != null && comments.get(i).getChildren().size() > 0) { - expandChildren(comments.get(i).getChildren(), newList, position); - position = position + comments.get(i).getChildren().size(); - } - comments.get(i).setExpanded(true); - } - } - } - - private void collapseChildren(int position) { - mVisibleComments.get(position).setExpanded(false); - int depth = mVisibleComments.get(position).getDepth(); - int allChildrenSize = 0; - for (int i = position + 1; i < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i).getDepth() > depth) { - allChildrenSize++; - } else { - break; - } - } - - if (allChildrenSize > 0) { - mVisibleComments.subList(position + 1, position + 1 + allChildrenSize).clear(); - } - if (mIsSingleCommentThreadMode) { - if (mFullyCollapseComment) { - notifyItemChanged(position + 2); - } - notifyItemRangeRemoved(position + 3, allChildrenSize); - } else { - if (mFullyCollapseComment) { - notifyItemChanged(position + 1); - } - notifyItemRangeRemoved(position + 2, allChildrenSize); - } - } - - public void addComments(@NonNull ArrayList comments, boolean hasMoreComments) { - if (mVisibleComments.size() == 0) { - isInitiallyLoading = false; - isInitiallyLoadingFailed = false; - if (comments.size() == 0) { - notifyItemChanged(1); - } else { - notifyItemRemoved(1); - } - } - - int sizeBefore = mVisibleComments.size(); - mVisibleComments.addAll(comments); - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(sizeBefore + 2, comments.size()); - } else { - notifyItemRangeInserted(sizeBefore + 1, comments.size()); - } - - if (mHasMoreComments != hasMoreComments) { - if (hasMoreComments) { - if (mIsSingleCommentThreadMode) { - notifyItemInserted(mVisibleComments.size() + 2); - } else { - notifyItemInserted(mVisibleComments.size() + 1); - } - } else { - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(mVisibleComments.size() + 2); - } else { - notifyItemRemoved(mVisibleComments.size() + 1); - } - } - } - mHasMoreComments = hasMoreComments; - } - - public void addComment(Comment comment) { - if (mVisibleComments.size() == 0 || isInitiallyLoadingFailed) { - notifyItemRemoved(1); - } - - mVisibleComments.add(0, comment); - - if (isInitiallyLoading) { - notifyItemInserted(2); - } else { - notifyItemInserted(1); - } - } - - public void addChildComment(Comment comment, String parentFullname, int parentPosition) { - if (!parentFullname.equals(mVisibleComments.get(parentPosition).getFullName())) { - for (int i = 0; i < mVisibleComments.size(); i++) { - if (parentFullname.equals(mVisibleComments.get(i).getFullName())) { - parentPosition = i; - break; - } - } - } - - mVisibleComments.get(parentPosition).addChild(comment); - mVisibleComments.get(parentPosition).setHasReply(true); - if (!mVisibleComments.get(parentPosition).isExpanded()) { - ArrayList newList = new ArrayList<>(); - expandChildren(mVisibleComments.get(parentPosition).getChildren(), newList, 0); - mVisibleComments.get(parentPosition).setExpanded(true); - mVisibleComments.addAll(parentPosition + 1, newList); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(parentPosition + 2); - notifyItemRangeInserted(parentPosition + 3, newList.size()); - } else { - notifyItemChanged(parentPosition + 1); - notifyItemRangeInserted(parentPosition + 2, newList.size()); - } - } else { - mVisibleComments.add(parentPosition + 1, comment); - if (mIsSingleCommentThreadMode) { - notifyItemInserted(parentPosition + 3); - } else { - notifyItemInserted(parentPosition + 2); - } - } - } - - public void setSingleComment(String singleCommentId, boolean isSingleCommentThreadMode) { - mSingleCommentId = singleCommentId; - mIsSingleCommentThreadMode = isSingleCommentThreadMode; - } - - public ArrayList getVisibleComments() { - return mVisibleComments; - } - - public void initiallyLoading() { - if (mVisibleComments.size() != 0) { - int previousSize = mVisibleComments.size(); - mVisibleComments.clear(); - if (mIsSingleCommentThreadMode) { - notifyItemRangeRemoved(1, previousSize + 1); - } else { - notifyItemRangeRemoved(1, previousSize); - } - } - - if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - notifyItemChanged(1); - } else { - isInitiallyLoading = true; - isInitiallyLoadingFailed = false; - notifyItemInserted(1); - } - } - - public void initiallyLoadCommentsFailed() { - isInitiallyLoading = false; - isInitiallyLoadingFailed = true; - notifyItemChanged(1); - } - - public void loadMoreCommentsFailed() { - loadMoreCommentsFailed = true; - if (mIsSingleCommentThreadMode) { - notifyItemChanged(mVisibleComments.size() + 2); - } else { - notifyItemChanged(mVisibleComments.size() + 1); - } - } - - public void editComment(String commentAuthor, String commentContentMarkdown, int position) { - if (commentAuthor != null) - mVisibleComments.get(position).setAuthor(commentAuthor); - - mVisibleComments.get(position).setCommentMarkdown(commentContentMarkdown); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(position + 2); - } else { - notifyItemChanged(position + 1); - } - } - - public void deleteComment(int position) { - if (mVisibleComments != null && position >= 0 && position < mVisibleComments.size()) { - if (mVisibleComments.get(position).hasReply()) { - mVisibleComments.get(position).setAuthor("[deleted]"); - mVisibleComments.get(position).setCommentMarkdown("[deleted]"); - if (mIsSingleCommentThreadMode) { - notifyItemChanged(position + 2); - } else { - notifyItemChanged(position + 1); - } - } else { - mVisibleComments.remove(position); - if (mIsSingleCommentThreadMode) { - notifyItemRemoved(position + 2); - } else { - notifyItemRemoved(position + 1); - } - } - } - } - - public void setBlurNSFW(boolean needBlurNSFW) { - mNeedBlurNsfw = needBlurNSFW; - } - - public void setBlurSpoiler(boolean needBlurSpoiler) { - mNeedBlurSpoiler = needBlurSpoiler; - } - - public int getNextParentCommentPosition(int currentPosition) { - if (mVisibleComments != null && !mVisibleComments.isEmpty()) { - if (mIsSingleCommentThreadMode) { - for (int i = currentPosition + 1; i - 2 < mVisibleComments.size() && i - 2 >= 0; i++) { - if (mVisibleComments.get(i - 2).getDepth() == 0) { - return i; - } - } - } else { - for (int i = currentPosition + 1; i - 1 < mVisibleComments.size(); i++) { - if (mVisibleComments.get(i - 1).getDepth() == 0) { - return i; - } - } - } - } - return -1; - } - - public int getPreviousParentCommentPosition(int currentPosition) { - if (mVisibleComments != null && !mVisibleComments.isEmpty()) { - if (mIsSingleCommentThreadMode) { - for (int i = currentPosition + 1; i - 2 >= 0; i--) { - if (mVisibleComments.get(i - 2).getDepth() == 0) { - return i; - } - } - } else { - for (int i = currentPosition - 1; i - 1 >= 0; i--) { - if (mVisibleComments.get(i - 1).getDepth() == 0) { - return i; - } - } - } - } - return -1; - } - - public void setAutoplay(boolean autoplay) { - mAutoplay = autoplay; - } - - public void setDataSavingMode(boolean dataSavingMode) { - mDataSavingMode = dataSavingMode; - } - - public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) { - if (viewHolder instanceof PostDetailBaseViewHolder) { - if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { - if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((PostDetailBaseViewHolder) viewHolder).mUpvoteButton.performClick(); - } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((PostDetailBaseViewHolder) viewHolder).mDownvoteButton.performClick(); - } - } else { - if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((PostDetailBaseViewHolder) viewHolder).mUpvoteButton.performClick(); - } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((PostDetailBaseViewHolder) viewHolder).mDownvoteButton.performClick(); - } - } - } else if (viewHolder instanceof CommentViewHolder) { - if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { - if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((CommentViewHolder) viewHolder).upvoteButton.performClick(); - } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((CommentViewHolder) viewHolder).downvoteButton.performClick(); - } - } else { - if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((CommentViewHolder) viewHolder).upvoteButton.performClick(); - } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((CommentViewHolder) viewHolder).downvoteButton.performClick(); - } - } - } - } - - public void giveAward(String awardsHTML, int awardCount, int position) { - if (position == 0) { - if (mPost != null) { - mPost.addAwards(awardsHTML); - mPost.addAwards(awardCount); - notifyItemChanged(0); - } - } else { - position = mIsSingleCommentThreadMode ? position + 2 : position + 1; - Comment comment = getCurrentComment(position); - if (comment != null) { - comment.addAwards(awardsHTML); - notifyItemChanged(position); - } - } - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if (holder instanceof CommentViewHolder) { - ((CommentViewHolder) holder).authorTextView.setTextColor(mUsernameColor); - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); - ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); - ((CommentViewHolder) holder).awardsTextView.setText(""); - ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); - ((CommentViewHolder) holder).expandButton.setVisibility(View.GONE); - ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); - ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ViewGroup.LayoutParams params = ((CommentViewHolder) holder).verticalBlock.getLayoutParams(); - params.width = 0; - ((CommentViewHolder) holder).verticalBlock.setLayoutParams(params); - ((CommentViewHolder) holder).itemView.setPadding(0, 0, 0, 0); - ((CommentViewHolder) holder).itemView.setBackgroundColor(mCommentBackgroundColor); - } else if (holder instanceof CommentFullyCollapsedViewHolder) { - ViewGroup.LayoutParams params = ((CommentFullyCollapsedViewHolder) holder).verticalBlock.getLayoutParams(); - params.width = 0; - ((CommentFullyCollapsedViewHolder) holder).verticalBlock.setLayoutParams(params); - ((CommentFullyCollapsedViewHolder) holder).itemView.setPadding(0, 0, 0, 0); - } else if (holder instanceof PostDetailBaseViewHolder) { - ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mPostIconAndInfoColor); - ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostDetailBaseViewHolder) holder).mFlairTextView.setVisibility(View.GONE); - ((PostDetailBaseViewHolder) holder).mSpoilerTextView.setVisibility(View.GONE); - ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.GONE); - - if (holder instanceof PostDetailVideoAutoplayViewHolder) { - if (((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks != null) { - ((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks.cancel(); - } - ((PostDetailVideoAutoplayViewHolder) holder).mErrorLoadingGfycatImageView.setVisibility(View.GONE); - ((PostDetailVideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); - ((PostDetailVideoAutoplayViewHolder) holder).resetVolume(); - mGlide.clear(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); - ((PostDetailVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); - } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { - mGlide.clear(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); - } else if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { - mGlide.clear(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); - } else if (holder instanceof PostDetailLinkViewHolder) { - mGlide.clear(((PostDetailLinkViewHolder) holder).mImageView); - } - } else if (holder instanceof LoadMoreChildCommentsViewHolder) { - ((LoadMoreChildCommentsViewHolder) holder).itemView.setPadding(0, 0, 0, 0); - ViewGroup.LayoutParams params = ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.getLayoutParams(); - params.width = 0; - ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.setLayoutParams(params); - } - } - - @Override - public int getItemCount() { - if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { - return 2; - } - - if (mHasMoreComments || loadMoreCommentsFailed) { - if (mIsSingleCommentThreadMode) { - return mVisibleComments.size() + 3; - } else { - return mVisibleComments.size() + 2; - } - } - - if (mIsSingleCommentThreadMode) { - return mVisibleComments.size() + 2; - } else { - return mVisibleComments.size() + 1; - } - } - - @Nullable - @Override - public Object getKeyForOrder(int order) { - return mPost; - } - - @Nullable - @Override - public Integer getOrderForKey(@NonNull Object key) { - return 0; - } - - public interface CommentRecyclerViewAdapterCallback { - void updatePost(Post post); - - void retryFetchingComments(); - - void retryFetchingMoreComments(); - } - - public class PostDetailBaseViewHolder extends RecyclerView.ViewHolder { - AspectRatioGifImageView mIconGifImageView; - TextView mSubredditTextView; - TextView mUserTextView; - TextView mAuthorFlairTextView; - TextView mPostTimeTextView; - TextView mTitleTextView; - CustomTextView mTypeTextView; - ImageView mCrosspostImageView; - ImageView mArchivedImageView; - ImageView mLockedImageView; - CustomTextView mNSFWTextView; - CustomTextView mSpoilerTextView; - CustomTextView mFlairTextView; - TextView mAwardsTextView; - ConstraintLayout mBottomConstraintLayout; - ImageView mUpvoteButton; - TextView mScoreTextView; - ImageView mDownvoteButton; - TextView commentsCountTextView; - ImageView mSaveButton; - ImageView mShareButton; - - PostDetailBaseViewHolder(@NonNull View itemView) { - super(itemView); - } - - void setBaseView(AspectRatioGifImageView mIconGifImageView, - TextView mSubredditTextView, - TextView mUserTextView, - TextView mAuthorFlairTextView, - TextView mPostTimeTextView, - TextView mTitleTextView, - CustomTextView mTypeTextView, - ImageView mCrosspostImageView, - ImageView mArchivedImageView, - ImageView mLockedImageView, - CustomTextView mNSFWTextView, - CustomTextView mSpoilerTextView, - CustomTextView mFlairTextView, - TextView mAwardsTextView, - ConstraintLayout mBottomConstraintLayout, - ImageView mUpvoteButton, - TextView mScoreTextView, - ImageView mDownvoteButton, - TextView commentsCountTextView, - ImageView mSaveButton, - ImageView mShareButton) { - this.mIconGifImageView = mIconGifImageView; - this.mSubredditTextView = mSubredditTextView; - this.mUserTextView = mUserTextView; - this.mAuthorFlairTextView = mAuthorFlairTextView; - this.mPostTimeTextView = mPostTimeTextView; - this.mTitleTextView = mTitleTextView; - this.mTypeTextView = mTypeTextView; - this.mCrosspostImageView = mCrosspostImageView; - this.mArchivedImageView = mArchivedImageView; - this.mLockedImageView = mLockedImageView; - this.mNSFWTextView = mNSFWTextView; - this.mSpoilerTextView = mSpoilerTextView; - this.mFlairTextView = mFlairTextView; - this.mAwardsTextView = mAwardsTextView; - this.mBottomConstraintLayout = mBottomConstraintLayout; - this.mUpvoteButton = mUpvoteButton; - this.mScoreTextView = mScoreTextView; - this.mDownvoteButton = mDownvoteButton; - this.commentsCountTextView = commentsCountTextView; - this.mSaveButton = mSaveButton; - this.mShareButton = mShareButton; - - mIconGifImageView.setOnClickListener(view -> mSubredditTextView.performClick()); - - mSubredditTextView.setOnClickListener(view -> { - Intent intent; - if (mPost.getSubredditNamePrefixed().equals("u/" + mPost.getAuthor())) { - intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mPost.getAuthor()); - } else { - intent = new Intent(mActivity, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, - mPost.getSubredditNamePrefixed().substring(2)); - } - mActivity.startActivity(intent); - }); - - mUserTextView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mPost.getAuthor()); - mActivity.startActivity(intent); - }); - - mAuthorFlairTextView.setOnClickListener(view -> mUserTextView.performClick()); - - mCrosspostImageView.setOnClickListener(view -> { - Intent crosspostIntent = new Intent(mActivity, ViewPostDetailActivity.class); - crosspostIntent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, mPost.getCrosspostParentId()); - mActivity.startActivity(crosspostIntent); - }); - - mTypeTextView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, mPost.getPostType()); - mActivity.startActivity(intent); - }); - - mNSFWTextView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, Post.NSFW_TYPE); - mActivity.startActivity(intent); - }); - - mUpvoteButton.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter(); - int previousScoreTextViewColor = mScoreTextView.getCurrentTextColor(); - - int previousVoteType = mPost.getVoteType(); - String newVoteType; - - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != 1) { - //Not upvoted before - mPost.setVoteType(1); - newVoteType = APIUtils.DIR_UPVOTE; - mUpvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - mPost.setVoteType(0); - newVoteType = APIUtils.DIR_UNVOTE; - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mPostIconAndInfoColor); - } - - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); - - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingWithoutPositionListener() { - @Override - public void onVoteThingSuccess() { - if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { - mPost.setVoteType(1); - mUpvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mUpvotedColor); - } else { - mPost.setVoteType(0); - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mPostIconAndInfoColor); - } - - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); - - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - - @Override - public void onVoteThingFail() { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - mPost.setVoteType(previousVoteType); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + previousVoteType)); - mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - mScoreTextView.setTextColor(previousScoreTextViewColor); - - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - }, mPost.getFullName(), newVoteType); - }); - - mDownvoteButton.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter(); - int previousScoreTextViewColor = mScoreTextView.getCurrentTextColor(); - - int previousVoteType = mPost.getVoteType(); - String newVoteType; - - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != -1) { - //Not upvoted before - mPost.setVoteType(-1); - newVoteType = APIUtils.DIR_DOWNVOTE; - mDownvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mDownvotedColor); - } else { - //Upvoted before - mPost.setVoteType(0); - newVoteType = APIUtils.DIR_UNVOTE; - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mPostIconAndInfoColor); - } - - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); - - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingWithoutPositionListener() { - @Override - public void onVoteThingSuccess() { - if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { - mPost.setVoteType(-1); - mDownvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mDownvotedColor); - } else { - mPost.setVoteType(0); - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mPostIconAndInfoColor); - } - - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + mPost.getVoteType())); - - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - - @Override - public void onVoteThingFail() { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - mPost.setVoteType(previousVoteType); - mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - mPost.getScore() + previousVoteType)); - mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - mScoreTextView.setTextColor(previousScoreTextViewColor); - - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - }, mPost.getFullName(), newVoteType); - }); - - commentsCountTextView.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_comment_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mPost.isLocked()) { - Toast.makeText(mActivity, R.string.locked_post_comment_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - Intent intent = new Intent(mActivity, CommentActivity.class); - intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mPost.getFullName()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, mPost.getTitle()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY, mPost.getSelfText()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_KEY, mPost.getSelfTextPlain()); - intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, false); - intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, 0); - mActivity.startActivityForResult(intent, WRITE_COMMENT_REQUEST_CODE); - }); - - mSaveButton.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (mPost.isSaved()) { - mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - mPost.setSaved(false); - mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - Toast.makeText(mActivity, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - - @Override - public void failed() { - mPost.setSaved(true); - mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - }); - } else { - mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - SaveThing.saveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - mPost.setSaved(true); - mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - - @Override - public void failed() { - mPost.setSaved(false); - mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - Toast.makeText(mActivity, R.string.post_saved_failed, Toast.LENGTH_SHORT).show(); - mCommentRecyclerViewAdapterCallback.updatePost(mPost); - } - }); - } - }); - - mShareButton.setOnClickListener(view -> { - Bundle bundle = new Bundle(); - bundle.putString(ShareLinkBottomSheetFragment.EXTRA_POST_LINK, mPost.getPermalink()); - if (mPost.getPostType() != Post.TEXT_TYPE) { - bundle.putInt(ShareLinkBottomSheetFragment.EXTRA_MEDIA_TYPE, mPost.getPostType()); - switch (mPost.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, mPost.getUrl()); - break; - case Post.VIDEO_TYPE: - bundle.putString(ShareLinkBottomSheetFragment.EXTRA_MEDIA_LINK, mPost.getVideoDownloadUrl()); - break; - } - } - mShareLinkBottomSheetFragment.setArguments(bundle); - mShareLinkBottomSheetFragment.show(mActivity.getSupportFragmentManager(), mShareLinkBottomSheetFragment.getTag()); - }); - - if (mVoteButtonsOnTheRight) { - ConstraintSet constraintSet = new ConstraintSet(); - constraintSet.clone(mBottomConstraintLayout); - constraintSet.clear(mUpvoteButton.getId(), ConstraintSet.START); - constraintSet.clear(mScoreTextView.getId(), ConstraintSet.START); - constraintSet.clear(mDownvoteButton.getId(), ConstraintSet.START); - constraintSet.clear(mSaveButton.getId(), ConstraintSet.END); - constraintSet.clear(mShareButton.getId(), ConstraintSet.END); - constraintSet.connect(mUpvoteButton.getId(), ConstraintSet.END, mScoreTextView.getId(), ConstraintSet.START); - constraintSet.connect(mScoreTextView.getId(), ConstraintSet.END, mDownvoteButton.getId(), ConstraintSet.START); - constraintSet.connect(mDownvoteButton.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END); - constraintSet.connect(commentsCountTextView.getId(), ConstraintSet.START, mSaveButton.getId(), ConstraintSet.END); - constraintSet.connect(commentsCountTextView.getId(), ConstraintSet.END, mUpvoteButton.getId(), ConstraintSet.START); - constraintSet.connect(mSaveButton.getId(), ConstraintSet.START, mShareButton.getId(), ConstraintSet.END); - constraintSet.connect(mShareButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); - constraintSet.setHorizontalBias(commentsCountTextView.getId(), 0); - constraintSet.applyTo(mBottomConstraintLayout); - } - - itemView.setBackgroundColor(mCardViewColor); - mSubredditTextView.setTextColor(mSubredditColor); - mUserTextView.setTextColor(mUsernameColor); - mAuthorFlairTextView.setTextColor(mAuthorFlairTextColor); - mPostTimeTextView.setTextColor(mSecondaryTextColor); - mTitleTextView.setTextColor(mPostTitleColor); - mTypeTextView.setBackgroundColor(mPostTypeBackgroundColor); - mTypeTextView.setBorderColor(mPostTypeBackgroundColor); - mTypeTextView.setTextColor(mPostTypeTextColor); - mSpoilerTextView.setBackgroundColor(mSpoilerBackgroundColor); - mSpoilerTextView.setBorderColor(mSpoilerBackgroundColor); - mSpoilerTextView.setTextColor(mSpoilerTextColor); - mNSFWTextView.setBackgroundColor(mNSFWBackgroundColor); - mNSFWTextView.setBorderColor(mNSFWBackgroundColor); - mNSFWTextView.setTextColor(mNSFWTextColor); - mFlairTextView.setBackgroundColor(mFlairBackgroundColor); - mFlairTextView.setBorderColor(mFlairBackgroundColor); - mFlairTextView.setTextColor(mFlairTextColor); - mArchivedImageView.setColorFilter(mArchivedTintColor, PorterDuff.Mode.SRC_IN); - mLockedImageView.setColorFilter(mLockedTintColor, PorterDuff.Mode.SRC_IN); - mCrosspostImageView.setColorFilter(mCrosspostTintColor, PorterDuff.Mode.SRC_IN); - mAwardsTextView.setTextColor(mSecondaryTextColor); - mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mScoreTextView.setTextColor(mPostIconAndInfoColor); - mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - commentsCountTextView.setTextColor(mPostIconAndInfoColor); - commentsCountTextView.setCompoundDrawablesWithIntrinsicBounds(mCommentIcon, null, null, null); - mSaveButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - mShareButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - } - - class PostDetailVideoAutoplayViewHolder extends PostDetailBaseViewHolder implements ToroPlayer { - @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.user_text_view_item_post_detail_video_autoplay) - TextView mUserTextView; - @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.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.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.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 - ExoPlayerViewHelper helper; - private Uri mediaUri; - private float volume; - public FetchGfycatOrRedgifsVideoLinks fetchGfycatOrRedgifsVideoLinks; - - public PostDetailVideoAutoplayViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(mIconGifImageView, - mSubredditTextView, - mUserTextView, - mAuthorFlairTextView, - mPostTimeTextView, - mTitleTextView, - mTypeTextView, - mCrosspostImageView, - mArchivedImageView, - mLockedImageView, - mNSFWTextView, - mSpoilerTextView, - mFlairTextView, - mAwardsTextView, - mBottomConstraintLayout, - mUpvoteButton, - mScoreTextView, - mDownvoteButton, - commentsCountTextView, - mSaveButton, - mShareButton); - - aspectRatioFrameLayout.setOnClickListener(null); - - muteButton.setOnClickListener(view -> { - if (helper != null) { - if (helper.getVolume() != 0) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); - helper.setVolume(0f); - volume = 0f; - } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); - helper.setVolume(1f); - volume = 1f; - } - } - }); - - fullscreenButton.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, ViewVideoActivity.class); - if (mPost.isGfycat()) { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); - if (mPost.isLoadGfyOrRedgifsVideoSuccess()) { - intent.setData(Uri.parse(mPost.getVideoUrl())); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); - } - } else if (mPost.isRedgifs()) { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); - if (mPost.isLoadGfyOrRedgifsVideoSuccess()) { - intent.setData(Uri.parse(mPost.getVideoUrl())); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); - } - } else { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); - intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName()); - intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId()); - } - intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, mPost.getTitle()); - if (helper != null) { - intent.putExtra(ViewVideoActivity.EXTRA_PROGRESS_SECONDS, helper.getLatestPlaybackInfo().getResumePosition()); - } - intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - }); - - previewImageView.setOnLongClickListener(view -> fullscreenButton.performClick()); - playerView.setOnLongClickListener(view -> fullscreenButton.performClick()); - } - - void bindVideoUri(Uri videoUri) { - mediaUri = videoUri; - } - - void setVolume(float volume) { - this.volume = volume; - } - - void resetVolume() { - volume = 0f; - } - - @NonNull - @Override - public View getPlayerView() { - return playerView; - } - - @NonNull - @Override - public PlaybackInfo getCurrentPlaybackInfo() { - return helper != null && mediaUri != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo(); - } - - @Override - public void initialize(@NonNull Container container, @NonNull PlaybackInfo playbackInfo) { - if (mediaUri == null) { - return; - } - if (helper == null) { - helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); - helper.addEventListener(new Playable.EventListener() { - @Override - public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - if (!trackGroups.isEmpty()) { - for (int i = 0; i < trackGroups.length; i++) { - String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; - if (mimeType != null && mimeType.contains("audio")) { - helper.setVolume(volume); - muteButton.setVisibility(View.VISIBLE); - if (volume != 0f) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); - } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); - } - break; - } - } - } else { - muteButton.setVisibility(View.GONE); - } - } - - @Override - public void onMetadata(Metadata metadata) { - - } - - @Override - public void onCues(List cues) { - - } - - @Override - public void onRenderedFirstFrame() { - mGlide.clear(previewImageView); - previewImageView.setVisibility(View.GONE); - } - }); - } - helper.initialize(container, playbackInfo); - } - - @Override - public void play() { - if (helper != null && mediaUri != null) helper.play(); - } - - @Override - public void pause() { - if (helper != null) helper.pause(); - } - - @Override - public boolean isPlaying() { - return helper != null && helper.isPlaying(); - } - - @Override - public void release() { - if (helper != null) { - helper.release(); - helper = null; - } - } - - @Override - public boolean wantsToPlay() { - return ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= mStartAutoplayVisibleAreaOffset; - } - - @Override - public int getPlayerOrder() { - return getAdapterPosition(); - } - } - - class PostDetailVideoAndGifPreviewHolder extends PostDetailBaseViewHolder { - @BindView(R.id.icon_gif_image_view_item_post_detail_video_and_gif_preview) - AspectRatioGifImageView mIconGifImageView; - @BindView(R.id.subreddit_text_view_item_post_detail_video_and_gif_preview) - TextView mSubredditTextView; - @BindView(R.id.user_text_view_item_post_detail_video_and_gif_preview) - TextView mUserTextView; - @BindView(R.id.author_flair_text_view_item_post_detail_video_and_gif_preview) - TextView mAuthorFlairTextView; - @BindView(R.id.post_time_text_view_item_post_detail_video_and_gif_preview) - TextView mPostTimeTextView; - @BindView(R.id.title_text_view_item_post_detail_video_and_gif_preview) - TextView mTitleTextView; - @BindView(R.id.type_text_view_item_post_detail_video_and_gif_preview) - CustomTextView mTypeTextView; - @BindView(R.id.crosspost_image_view_item_post_detail_video_and_gif_preview) - ImageView mCrosspostImageView; - @BindView(R.id.archived_image_view_item_post_detail_video_and_gif_preview) - ImageView mArchivedImageView; - @BindView(R.id.locked_image_view_item_post_detail_video_and_gif_preview) - ImageView mLockedImageView; - @BindView(R.id.nsfw_text_view_item_post_detail_video_and_gif_preview) - CustomTextView mNSFWTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_detail_video_and_gif_preview) - CustomTextView mSpoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_detail_video_and_gif_preview) - CustomTextView mFlairTextView; - @BindView(R.id.awards_text_view_item_post_detail_video_and_gif_preview) - TextView mAwardsTextView; - @BindView(R.id.load_wrapper_item_post_detail_video_and_gif_preview) - RelativeLayout mLoadWrapper; - @BindView(R.id.progress_bar_item_post_detail_video_and_gif_preview) - ProgressBar mLoadImageProgressBar; - @BindView(R.id.load_image_error_text_view_item_post_detail_video_and_gif_preview) - TextView mLoadImageErrorTextView; - @BindView(R.id.image_view_item_post_detail_video_and_gif_preview) - AspectRatioGifImageView mImageView; - @BindView(R.id.bottom_constraint_layout_item_post_detail_video_and_gif_preview) - ConstraintLayout mBottomConstraintLayout; - @BindView(R.id.plus_button_item_post_detail_video_and_gif_preview) - ImageView mUpvoteButton; - @BindView(R.id.score_text_view_item_post_detail_video_and_gif_preview) - TextView mScoreTextView; - @BindView(R.id.minus_button_item_post_detail_video_and_gif_preview) - ImageView mDownvoteButton; - @BindView(R.id.comments_count_item_post_detail_video_and_gif_preview) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_detail_video_and_gif_preview) - ImageView mSaveButton; - @BindView(R.id.share_button_item_post_detail_video_and_gif_preview) - ImageView mShareButton; - - PostDetailVideoAndGifPreviewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(mIconGifImageView, - mSubredditTextView, - mUserTextView, - mAuthorFlairTextView, - mPostTimeTextView, - mTitleTextView, - mTypeTextView, - mCrosspostImageView, - mArchivedImageView, - mLockedImageView, - mNSFWTextView, - mSpoilerTextView, - mFlairTextView, - mAwardsTextView, - mBottomConstraintLayout, - mUpvoteButton, - mScoreTextView, - mDownvoteButton, - commentsCountTextView, - mSaveButton, - mShareButton); - - mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); - - mImageView.setOnClickListener(view -> { - if (mPost.getPostType() == Post.VIDEO_TYPE) { - Intent intent = new Intent(mActivity, ViewVideoActivity.class); - if (mPost.isGfycat()) { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); - } else if (mPost.isRedgifs()) { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); - } else { - intent.setData(Uri.parse(mPost.getVideoUrl())); - intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName()); - intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId()); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); - } - intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, mPost.getTitle()); - intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - } else if (mPost.getPostType() == Post.GIF_TYPE) { - Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() - + "-" + mPost.getId() + ".gif"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, mPost.getVideoUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); - mActivity.startActivity(intent); - } - }); - } - } - - class PostDetailImageAndGifAutoplayViewHolder extends PostDetailBaseViewHolder { - @BindView(R.id.icon_gif_image_view_item_post_detail_image_and_gif_autoplay) - AspectRatioGifImageView mIconGifImageView; - @BindView(R.id.subreddit_text_view_item_post_detail_image_and_gif_autoplay) - TextView mSubredditTextView; - @BindView(R.id.user_text_view_item_post_detail_image_and_gif_autoplay) - TextView mUserTextView; - @BindView(R.id.author_flair_text_view_item_post_detail_image_and_gif_autoplay) - TextView mAuthorFlairTextView; - @BindView(R.id.post_time_text_view_item_post_detail_image_and_gif_autoplay) - TextView mPostTimeTextView; - @BindView(R.id.title_text_view_item_post_detail_image_and_gif_autoplay) - TextView mTitleTextView; - @BindView(R.id.type_text_view_item_post_detail_image_and_gif_autoplay) - CustomTextView mTypeTextView; - @BindView(R.id.crosspost_image_view_item_post_detail_image_and_gif_autoplay) - ImageView mCrosspostImageView; - @BindView(R.id.archived_image_view_item_post_detail_image_and_gif_autoplay) - ImageView mArchivedImageView; - @BindView(R.id.locked_image_view_item_post_detail_image_and_gif_autoplay) - ImageView mLockedImageView; - @BindView(R.id.nsfw_text_view_item_post_detail_image_and_gif_autoplay) - CustomTextView mNSFWTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_detail_image_and_gif_autoplay) - CustomTextView mSpoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_detail_image_and_gif_autoplay) - CustomTextView mFlairTextView; - @BindView(R.id.awards_text_view_item_post_detail_image_and_gif_autoplay) - TextView mAwardsTextView; - @BindView(R.id.image_view_wrapper_item_post_detail_image_and_gif_autoplay) - RelativeLayout mRelativeLayout; - @BindView(R.id.load_wrapper_item_post_detail_image_and_gif_autoplay) - RelativeLayout mLoadWrapper; - @BindView(R.id.progress_bar_item_post_detail_image_and_gif_autoplay) - ProgressBar mLoadImageProgressBar; - @BindView(R.id.load_image_error_text_view_item_post_detail_image_and_gif_autoplay) - TextView mLoadImageErrorTextView; - @BindView(R.id.image_view_item_post_detail_image_and_gif_autoplay) - AspectRatioGifImageView mImageView; - @BindView(R.id.bottom_constraint_layout_item_post_detail_image_and_gif_autoplay) - ConstraintLayout mBottomConstraintLayout; - @BindView(R.id.plus_button_item_post_detail_image_and_gif_autoplay) - ImageView mUpvoteButton; - @BindView(R.id.score_text_view_item_post_detail_image_and_gif_autoplay) - TextView mScoreTextView; - @BindView(R.id.minus_button_item_post_detail_image_and_gif_autoplay) - ImageView mDownvoteButton; - @BindView(R.id.comments_count_item_post_detail_image_and_gif_autoplay) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_detail_image_and_gif_autoplay) - ImageView mSaveButton; - @BindView(R.id.share_button_item_post_detail_image_and_gif_autoplay) - ImageView mShareButton; - - PostDetailImageAndGifAutoplayViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(mIconGifImageView, - mSubredditTextView, - mUserTextView, - mAuthorFlairTextView, - mPostTimeTextView, - mTitleTextView, - mTypeTextView, - mCrosspostImageView, - mArchivedImageView, - mLockedImageView, - mNSFWTextView, - mSpoilerTextView, - mFlairTextView, - mAwardsTextView, - mBottomConstraintLayout, - mUpvoteButton, - mScoreTextView, - mDownvoteButton, - commentsCountTextView, - mSaveButton, - mShareButton); - - mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); - - mImageView.setOnClickListener(view -> { - if (mPost.getPostType() == Post.IMAGE_TYPE) { - Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, mPost.getUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditNamePrefixed().substring(2) - + "-" + mPost.getId().substring(3) + ".jpg"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); - mActivity.startActivity(intent); - } else if (mPost.getPostType() == Post.GIF_TYPE) { - Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() - + "-" + mPost.getId() + ".gif"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, mPost.getVideoUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); - mActivity.startActivity(intent); - } - }); - } - } - - class PostDetailLinkViewHolder extends PostDetailBaseViewHolder { - @BindView(R.id.icon_gif_image_view_item_post_detail_link) - AspectRatioGifImageView mIconGifImageView; - @BindView(R.id.subreddit_text_view_item_post_detail_link) - TextView mSubredditTextView; - @BindView(R.id.user_text_view_item_post_detail_link) - TextView mUserTextView; - @BindView(R.id.author_flair_text_view_item_post_detail_link) - TextView mAuthorFlairTextView; - @BindView(R.id.post_time_text_view_item_post_detail_link) - TextView mPostTimeTextView; - @BindView(R.id.title_text_view_item_post_detail_link) - TextView mTitleTextView; - @BindView(R.id.type_text_view_item_post_detail_link) - CustomTextView mTypeTextView; - @BindView(R.id.crosspost_image_view_item_post_detail_link) - ImageView mCrosspostImageView; - @BindView(R.id.archived_image_view_item_post_detail_link) - ImageView mArchivedImageView; - @BindView(R.id.locked_image_view_item_post_detail_link) - ImageView mLockedImageView; - @BindView(R.id.nsfw_text_view_item_post_detail_link) - CustomTextView mNSFWTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_detail_link) - CustomTextView mSpoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_detail_link) - CustomTextView mFlairTextView; - @BindView(R.id.awards_text_view_item_post_detail_link) - TextView mAwardsTextView; - @BindView(R.id.link_text_view_item_post_detail_link) - TextView mLinkTextView; - @BindView(R.id.image_view_wrapper_item_post_detail_link) - RelativeLayout mRelativeLayout; - @BindView(R.id.load_wrapper_item_post_detail_link) - RelativeLayout mLoadWrapper; - @BindView(R.id.progress_bar_item_post_detail_link) - ProgressBar mLoadImageProgressBar; - @BindView(R.id.load_image_error_text_view_item_post_detail_link) - TextView mLoadImageErrorTextView; - @BindView(R.id.image_view_item_post_detail_link) - AspectRatioGifImageView mImageView; - @BindView(R.id.bottom_constraint_layout_item_post_detail_link) - ConstraintLayout mBottomConstraintLayout; - @BindView(R.id.plus_button_item_post_detail_link) - ImageView mUpvoteButton; - @BindView(R.id.score_text_view_item_post_detail_link) - TextView mScoreTextView; - @BindView(R.id.minus_button_item_post_detail_link) - ImageView mDownvoteButton; - @BindView(R.id.comments_count_item_post_detail_link) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_detail_link) - ImageView mSaveButton; - @BindView(R.id.share_button_item_post_detail_link) - ImageView mShareButton; - - PostDetailLinkViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(mIconGifImageView, - mSubredditTextView, - mUserTextView, - mAuthorFlairTextView, - mPostTimeTextView, - mTitleTextView, - mTypeTextView, - mCrosspostImageView, - mArchivedImageView, - mLockedImageView, - mNSFWTextView, - mSpoilerTextView, - mFlairTextView, - mAwardsTextView, - mBottomConstraintLayout, - mUpvoteButton, - mScoreTextView, - mDownvoteButton, - commentsCountTextView, - mSaveButton, - mShareButton); - - mLinkTextView.setTextColor(mSecondaryTextColor); - mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); - - mImageView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(mPost.getUrl()); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(mPost.getUrl())); - } else { - intent.setData(uri); - } - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - }); - } - } - - class PostDetailNoPreviewViewHolder extends PostDetailBaseViewHolder { - @BindView(R.id.icon_gif_image_view_item_post_detail_no_preview_link) - AspectRatioGifImageView mIconGifImageView; - @BindView(R.id.subreddit_text_view_item_post_detail_no_preview_link) - TextView mSubredditTextView; - @BindView(R.id.user_text_view_item_post_detail_no_preview_link) - TextView mUserTextView; - @BindView(R.id.author_flair_text_view_item_post_detail_no_preview_link) - TextView mAuthorFlairTextView; - @BindView(R.id.post_time_text_view_item_post_detail_no_preview_link) - TextView mPostTimeTextView; - @BindView(R.id.title_text_view_item_post_detail_no_preview_link) - TextView mTitleTextView; - @BindView(R.id.content_markdown_view_item_post_detail_no_preview_link) - RecyclerView mContentMarkdownView; - @BindView(R.id.type_text_view_item_post_detail_no_preview_link) - CustomTextView mTypeTextView; - @BindView(R.id.crosspost_image_view_item_post_detail_no_preview_link) - ImageView mCrosspostImageView; - @BindView(R.id.archived_image_view_item_post_detail_no_preview_link) - ImageView mArchivedImageView; - @BindView(R.id.locked_image_view_item_post_detail_no_preview_link) - ImageView mLockedImageView; - @BindView(R.id.nsfw_text_view_item_post_detail_no_preview_link) - CustomTextView mNSFWTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_detail_no_preview_link) - CustomTextView mSpoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_detail_no_preview_link) - CustomTextView mFlairTextView; - @BindView(R.id.awards_text_view_item_post_detail_no_preview_link) - TextView mAwardsTextView; - @BindView(R.id.link_text_view_item_post_detail_no_preview_link) - TextView mLinkTextView; - @BindView(R.id.image_view_no_preview_post_type_item_post_detail_no_preview_link) - ImageView mNoPreviewPostTypeImageView; - @BindView(R.id.bottom_constraint_layout_item_post_detail_no_preview_link) - ConstraintLayout mBottomConstraintLayout; - @BindView(R.id.plus_button_item_post_detail_no_preview_link) - ImageView mUpvoteButton; - @BindView(R.id.score_text_view_item_post_detail_no_preview_link) - TextView mScoreTextView; - @BindView(R.id.minus_button_item_post_detail_no_preview_link) - ImageView mDownvoteButton; - @BindView(R.id.comments_count_item_post_detail_no_preview_link) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_detail_no_preview_link) - ImageView mSaveButton; - @BindView(R.id.share_button_item_post_detail_no_preview_link) - ImageView mShareButton; - - PostDetailNoPreviewViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(mIconGifImageView, - mSubredditTextView, - mUserTextView, - mAuthorFlairTextView, - mPostTimeTextView, - mTitleTextView, - mTypeTextView, - mCrosspostImageView, - mArchivedImageView, - mLockedImageView, - mNSFWTextView, - mSpoilerTextView, - mFlairTextView, - mAwardsTextView, - mBottomConstraintLayout, - mUpvoteButton, - mScoreTextView, - mDownvoteButton, - commentsCountTextView, - mSaveButton, - mShareButton); - - mLinkTextView.setTextColor(mSecondaryTextColor); - mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); - mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); - - mNoPreviewPostTypeImageView.setOnClickListener(view -> { - if (mPost != null) { - if (mPost.getPostType() == Post.VIDEO_TYPE) { - Intent intent = new Intent(mActivity, ViewVideoActivity.class); - if (mPost.isGfycat()) { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); - } else if (mPost.isRedgifs()) { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); - } else { - intent.setData(Uri.parse(mPost.getVideoUrl())); - intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName()); - intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId()); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); - } - intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, mPost.getTitle()); - intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - } else if (mPost.getPostType() == Post.IMAGE_TYPE) { - Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, mPost.getUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() - + "-" + mPost.getId() + ".jpg"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); - mActivity.startActivity(intent); - } else if (mPost.getPostType() == Post.GIF_TYPE){ - Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); - intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() - + "-" + mPost.getId() + ".gif"); - intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, mPost.getVideoUrl()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); - intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); - mActivity.startActivity(intent); - } else if (mPost.getPostType() == Post.LINK_TYPE || mPost.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { - Intent intent = new Intent(mActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(mPost.getUrl()); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(mPost.getUrl())); - } else { - intent.setData(uri); - } - intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); - mActivity.startActivity(intent); - } else if (mPost.getPostType() == Post.GALLERY_TYPE) { - Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class); - intent.putParcelableArrayListExtra(ViewRedditGalleryActivity.EXTRA_REDDIT_GALLERY, mPost.getGallery()); - intent.putExtra(ViewRedditGalleryActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); - mActivity.startActivity(intent); - } - } - }); - } - } - - class PostDetailGalleryViewHolder extends PostDetailBaseViewHolder { - @BindView(R.id.icon_gif_image_view_item_post_detail_gallery) - AspectRatioGifImageView mIconGifImageView; - @BindView(R.id.subreddit_text_view_item_post_detail_gallery) - TextView mSubredditTextView; - @BindView(R.id.user_text_view_item_post_detail_gallery) - TextView mUserTextView; - @BindView(R.id.author_flair_text_view_item_post_detail_gallery) - TextView mAuthorFlairTextView; - @BindView(R.id.post_time_text_view_item_post_detail_gallery) - TextView mPostTimeTextView; - @BindView(R.id.title_text_view_item_post_detail_gallery) - TextView mTitleTextView; - @BindView(R.id.type_text_view_item_post_detail_gallery) - CustomTextView mTypeTextView; - @BindView(R.id.crosspost_image_view_item_post_detail_gallery) - ImageView mCrosspostImageView; - @BindView(R.id.archived_image_view_item_post_detail_gallery) - ImageView mArchivedImageView; - @BindView(R.id.locked_image_view_item_post_detail_gallery) - ImageView mLockedImageView; - @BindView(R.id.nsfw_text_view_item_post_detail_gallery) - CustomTextView mNSFWTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_detail_gallery) - CustomTextView mSpoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_detail_gallery) - CustomTextView mFlairTextView; - @BindView(R.id.awards_text_view_item_post_detail_gallery) - TextView mAwardsTextView; - @BindView(R.id.image_view_wrapper_item_post_detail_gallery) - RelativeLayout mRelativeLayout; - @BindView(R.id.load_wrapper_item_post_detail_gallery) - RelativeLayout mLoadWrapper; - @BindView(R.id.progress_bar_item_post_detail_gallery) - ProgressBar mLoadImageProgressBar; - @BindView(R.id.load_image_error_text_view_item_post_detail_gallery) - TextView mLoadImageErrorTextView; - @BindView(R.id.image_view_item_post_detail_gallery) - AspectRatioGifImageView mImageView; - @BindView(R.id.image_view_no_preview_link_item_post_detail_gallery) - ImageView mNoPreviewPostTypeImageView; - @BindView(R.id.bottom_constraint_layout_item_post_detail_gallery) - ConstraintLayout mBottomConstraintLayout; - @BindView(R.id.plus_button_item_post_detail_gallery) - ImageView mUpvoteButton; - @BindView(R.id.score_text_view_item_post_detail_gallery) - TextView mScoreTextView; - @BindView(R.id.minus_button_item_post_detail_gallery) - ImageView mDownvoteButton; - @BindView(R.id.comments_count_item_post_detail_gallery) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_detail_gallery) - ImageView mSaveButton; - @BindView(R.id.share_button_item_post_detail_gallery) - ImageView mShareButton; - - PostDetailGalleryViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(mIconGifImageView, - mSubredditTextView, - mUserTextView, - mAuthorFlairTextView, - mPostTimeTextView, - mTitleTextView, - mTypeTextView, - mCrosspostImageView, - mArchivedImageView, - mLockedImageView, - mNSFWTextView, - mSpoilerTextView, - mFlairTextView, - mAwardsTextView, - mBottomConstraintLayout, - mUpvoteButton, - mScoreTextView, - mDownvoteButton, - commentsCountTextView, - mSaveButton, - mShareButton); - - mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); - mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); - mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); - - mImageView.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()); - mActivity.startActivity(intent); - }); - - mNoPreviewPostTypeImageView.setOnClickListener(view -> { - mImageView.performClick(); - }); - } - } - - class PostDetailTextViewHolder extends PostDetailBaseViewHolder { - @BindView(R.id.icon_gif_image_view_item_post_detail_text) - AspectRatioGifImageView mIconGifImageView; - @BindView(R.id.subreddit_text_view_item_post_detail_text) - TextView mSubredditTextView; - @BindView(R.id.user_text_view_item_post_detail_text) - TextView mUserTextView; - @BindView(R.id.author_flair_text_view_item_post_detail_text) - TextView mAuthorFlairTextView; - @BindView(R.id.post_time_text_view_item_post_detail_text) - TextView mPostTimeTextView; - @BindView(R.id.title_text_view_item_post_detail_text) - TextView mTitleTextView; - @BindView(R.id.content_markdown_view_item_post_detail_text) - RecyclerView mContentMarkdownView; - @BindView(R.id.type_text_view_item_post_detail_text) - CustomTextView mTypeTextView; - @BindView(R.id.crosspost_image_view_item_post_detail_text) - ImageView mCrosspostImageView; - @BindView(R.id.archived_image_view_item_post_detail_text) - ImageView mArchivedImageView; - @BindView(R.id.locked_image_view_item_post_detail_text) - ImageView mLockedImageView; - @BindView(R.id.nsfw_text_view_item_post_detail_text) - CustomTextView mNSFWTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_detail_text) - CustomTextView mSpoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_detail_text) - CustomTextView mFlairTextView; - @BindView(R.id.awards_text_view_item_post_detail_text) - TextView mAwardsTextView; - @BindView(R.id.bottom_constraint_layout_item_post_detail_text) - ConstraintLayout mBottomConstraintLayout; - @BindView(R.id.plus_button_item_post_detail_text) - ImageView mUpvoteButton; - @BindView(R.id.score_text_view_item_post_detail_text) - TextView mScoreTextView; - @BindView(R.id.minus_button_item_post_detail_text) - ImageView mDownvoteButton; - @BindView(R.id.comments_count_item_post_detail_text) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_detail_text) - ImageView mSaveButton; - @BindView(R.id.share_button_item_post_detail_text) - ImageView mShareButton; - - PostDetailTextViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(mIconGifImageView, - mSubredditTextView, - mUserTextView, - mAuthorFlairTextView, - mPostTimeTextView, - mTitleTextView, - mTypeTextView, - mCrosspostImageView, - mArchivedImageView, - mLockedImageView, - mNSFWTextView, - mSpoilerTextView, - mFlairTextView, - mAwardsTextView, - mBottomConstraintLayout, - mUpvoteButton, - mScoreTextView, - mDownvoteButton, - commentsCountTextView, - mSaveButton, - mShareButton); - } - } - - public class CommentViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.linear_layout_item_comment) - LinearLayout linearLayout; - @BindView(R.id.author_text_view_item_post_comment) - TextView authorTextView; - @BindView(R.id.author_flair_text_view_item_post_comment) - TextView authorFlairTextView; - @BindView(R.id.comment_time_text_view_item_post_comment) - TextView commentTimeTextView; - @BindView(R.id.top_score_text_view_item_post_comment) - TextView topScoreTextView; - @BindView(R.id.awards_text_view_item_comment) - TextView awardsTextView; - @BindView(R.id.comment_markdown_view_item_post_comment) - TextView commentMarkdownView; - @BindView(R.id.bottom_constraint_layout_item_post_comment) - ConstraintLayout bottomConstraintLayout; - @BindView(R.id.up_vote_button_item_post_comment) - ImageView upvoteButton; - @BindView(R.id.score_text_view_item_post_comment) - TextView scoreTextView; - @BindView(R.id.down_vote_button_item_post_comment) - ImageView downvoteButton; - @BindView(R.id.more_button_item_post_comment) - ImageView moreButton; - @BindView(R.id.save_button_item_post_comment) - ImageView saveButton; - @BindView(R.id.expand_button_item_post_comment) - ImageView expandButton; - @BindView(R.id.reply_button_item_post_comment) - ImageView replyButton; - @BindView(R.id.vertical_block_item_post_comment) - View verticalBlock; - @BindView(R.id.divider_item_comment) - View commentDivider; - - CommentViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - 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(expandButton.getId(), ConstraintSet.END); - constraintSet.clear(saveButton.getId(), ConstraintSet.END); - constraintSet.clear(replyButton.getId(), ConstraintSet.END); - constraintSet.clear(moreButton.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(moreButton.getId(), ConstraintSet.START, expandButton.getId(), ConstraintSet.END); - constraintSet.connect(expandButton.getId(), ConstraintSet.START, saveButton.getId(), ConstraintSet.END); - constraintSet.connect(saveButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); - constraintSet.connect(replyButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); - constraintSet.setHorizontalBias(moreButton.getId(), 0); - constraintSet.applyTo(bottomConstraintLayout); - } - - if (mShowCommentDivider) { - commentDivider.setBackgroundColor(mDividerColor); - commentDivider.setVisibility(View.VISIBLE); - } - - itemView.setBackgroundColor(mCommentBackgroundColor); - authorTextView.setTextColor(mUsernameColor); - commentTimeTextView.setTextColor(mSecondaryTextColor); - commentMarkdownView.setTextColor(mCommentTextColor); - authorFlairTextView.setTextColor(mAuthorFlairTextColor); - topScoreTextView.setTextColor(mSecondaryTextColor); - awardsTextView.setTextColor(mSecondaryTextColor); - commentDivider.setBackgroundColor(mDividerColor); - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - authorFlairTextView.setOnClickListener(view -> authorTextView.performClick()); - - moreButton.setOnClickListener(view -> { - Comment comment = getCurrentComment(this); - if (comment != null) { - Bundle bundle = new Bundle(); - if (!mPost.isArchived() && !mPost.isLocked() && comment.getAuthor().equals(mAccountName)) { - bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true); - } - bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putParcelable(CommentMoreBottomSheetFragment.EXTRA_COMMENT, comment); - if (mIsSingleCommentThreadMode) { - bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getAdapterPosition() - 2); - } else { - bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getAdapterPosition() - 1); - } - bundle.putString(CommentMoreBottomSheetFragment.EXTRA_COMMENT_MARKDOWN, comment.getCommentMarkdown()); - bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_IS_NSFW, mPost.isNSFW()); - CommentMoreBottomSheetFragment commentMoreBottomSheetFragment = new CommentMoreBottomSheetFragment(); - commentMoreBottomSheetFragment.setArguments(bundle); - commentMoreBottomSheetFragment.show(mActivity.getSupportFragmentManager(), commentMoreBottomSheetFragment.getTag()); - } - }); - - replyButton.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_reply_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mPost.isLocked()) { - Toast.makeText(mActivity, R.string.locked_post_reply_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - Comment comment = getCurrentComment(this); - if (comment != null) { - Intent intent = new Intent(mActivity, CommentActivity.class); - intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, comment.getDepth() + 1); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, comment.getCommentMarkdown()); - intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, comment.getCommentRawText()); - intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, comment.getFullName()); - intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true); - - int parentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; - intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, parentPosition); - mActivity.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE); - } - }); - - upvoteButton.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - Comment comment = getCurrentComment(this); - if (comment != null) { - int previousVoteType = comment.getVoteType(); - String newVoteType; - - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { - //Not upvoted before - comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); - newVoteType = APIUtils.DIR_UPVOTE; - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - newVoteType = APIUtils.DIR_UNVOTE; - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position) { - if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { - comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - } - - @Override - public void onVoteThingFail(int position) { - } - }, comment.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - downvoteButton.setOnClickListener(view -> { - if (mPost.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - Comment comment = getCurrentComment(this); - if (comment != null) { - int previousVoteType = comment.getVoteType(); - String newVoteType; - - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { - //Not downvoted before - comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); - newVoteType = APIUtils.DIR_DOWNVOTE; - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - //Downvoted before - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - newVoteType = APIUtils.DIR_UNVOTE; - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { - comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - topScoreTextView.setText(mActivity.getString(R.string.top_score, - Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType()))); - } - - @Override - public void onVoteThingFail(int position1) { - } - }, comment.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - saveButton.setOnClickListener(view -> { - Comment comment = getCurrentComment(this); - if (comment != null) { - if (comment.isSaved()) { - comment.setSaved(false); - SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { - @Override - public void success() { - comment.setSaved(false); - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - Toast.makeText(mActivity, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - comment.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show(); - } - }); - } else { - comment.setSaved(true); - SaveThing.saveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { - @Override - public void success() { - comment.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.comment_saved_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - comment.setSaved(false); - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - Toast.makeText(mActivity, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show(); - } - }); - } - } - }); - - authorTextView.setOnClickListener(view -> { - Comment comment = getCurrentComment(this); - if (comment != null) { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, comment.getAuthor()); - mActivity.startActivity(intent); - } - }); - - expandButton.setOnClickListener(view -> { - if (expandButton.getVisibility() == View.VISIBLE) { - int commentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; - if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { - Comment comment = getCurrentComment(this); - if (comment != null) { - if (mVisibleComments.get(commentPosition).isExpanded()) { - collapseChildren(commentPosition); - expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); - } else { - comment.setExpanded(true); - ArrayList newList = new ArrayList<>(); - expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); - mVisibleComments.get(commentPosition).setExpanded(true); - mVisibleComments.addAll(commentPosition + 1, newList); - - if (mIsSingleCommentThreadMode) { - notifyItemRangeInserted(commentPosition + 3, newList.size()); - } else { - notifyItemRangeInserted(commentPosition + 2, newList.size()); - } - expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); - } - } - } - } else if (mFullyCollapseComment) { - int commentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; - if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { - collapseChildren(commentPosition); - } - } - }); - - commentMarkdownView.setMovementMethod(LinkMovementMethod.getInstance()); - - if (mSwapTapAndLong) { - if (mCommentToolbarHideOnClick) { - View.OnLongClickListener hideToolbarOnLongClickListener = view -> hideToolbar(); - linearLayout.setOnLongClickListener(hideToolbarOnLongClickListener); - commentMarkdownView.setOnLongClickListener(hideToolbarOnLongClickListener); - commentTimeTextView.setOnLongClickListener(hideToolbarOnLongClickListener); - } - commentMarkdownView.setOnClickListener(view -> { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - expandComments(); - } - }); - itemView.setOnClickListener(view -> expandComments()); - } else { - if (mCommentToolbarHideOnClick) { - commentMarkdownView.setOnClickListener(view -> { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - hideToolbar(); - } - }); - View.OnClickListener hideToolbarOnClickListener = view -> hideToolbar(); - linearLayout.setOnClickListener(hideToolbarOnClickListener); - commentTimeTextView.setOnClickListener(hideToolbarOnClickListener); - } - View.OnLongClickListener expandsCommentsOnLongClickListener = view -> expandComments(); - commentMarkdownView.setOnLongClickListener(expandsCommentsOnLongClickListener); - itemView.setOnLongClickListener(expandsCommentsOnLongClickListener); - } - commentMarkdownView.setMovementMethod(LinkMovementMethod.getInstance()); - commentMarkdownView.setHighlightColor(Color.TRANSPARENT); - } - - private boolean expandComments() { - expandButton.performClick(); - return true; - } - - private boolean hideToolbar() { - if (bottomConstraintLayout.getLayoutParams().height == 0) { - bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; - topScoreTextView.setVisibility(View.GONE); - ((ViewPostDetailActivity) mActivity).delayTransition(); - } else { - ((ViewPostDetailActivity) mActivity).delayTransition(); - bottomConstraintLayout.getLayoutParams().height = 0; - topScoreTextView.setVisibility(View.VISIBLE); - } - return true; - } - } - - @Nullable - private Comment getCurrentComment(RecyclerView.ViewHolder holder) { - return getCurrentComment(holder.getAdapterPosition()); - } - - @Nullable - private Comment getCurrentComment(int position) { - if (mIsSingleCommentThreadMode) { - if (position - 2 >= 0 && position - 2 < mVisibleComments.size()) { - return mVisibleComments.get(position - 2); - } - } else { - if (position - 1 >= 0 && position - 1 < mVisibleComments.size()) { - return mVisibleComments.get(position - 1); - } - } - - return null; - } - - class CommentFullyCollapsedViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.vertical_block_item_comment_fully_collapsed) - View verticalBlock; - @BindView(R.id.user_name_text_view_item_comment_fully_collapsed) - TextView usernameTextView; - @BindView(R.id.score_text_view_item_comment_fully_collapsed) - TextView scoreTextView; - @BindView(R.id.time_text_view_item_comment_fully_collapsed) - TextView commentTimeTextView; - @BindView(R.id.divider_item_comment_fully_collapsed) - View commentDivider; - - public CommentFullyCollapsedViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - itemView.setBackgroundColor(mFullyCollapsedCommentBackgroundColor); - usernameTextView.setTextColor(mUsernameColor); - scoreTextView.setTextColor(mSecondaryTextColor); - commentTimeTextView.setTextColor(mSecondaryTextColor); - - if (mShowCommentDivider) { - commentDivider.setBackgroundColor(mDividerColor); - commentDivider.setVisibility(View.VISIBLE); - } - - itemView.setOnClickListener(view -> { - int commentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; - if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { - Comment comment = getCurrentComment(this); - if (comment != null) { - comment.setExpanded(true); - ArrayList newList = new ArrayList<>(); - expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); - mVisibleComments.get(commentPosition).setExpanded(true); - mVisibleComments.addAll(commentPosition + 1, newList); - - if (mIsSingleCommentThreadMode) { - notifyItemChanged(commentPosition + 2); - notifyItemRangeInserted(commentPosition + 3, newList.size()); - } else { - notifyItemChanged(commentPosition + 1); - notifyItemRangeInserted(commentPosition + 2, newList.size()); - } - } - } - }); - - itemView.setOnLongClickListener(view -> { - itemView.performClick(); - return true; - }); - } - } - - class LoadMoreChildCommentsViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.vertical_block_item_load_more_comments) - View verticalBlock; - @BindView(R.id.placeholder_text_view_item_load_more_comments) - TextView placeholderTextView; - @BindView(R.id.divider_item_load_more_comments_placeholder) - View commentDivider; - - LoadMoreChildCommentsViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - if (mShowCommentDivider) { - commentDivider.setVisibility(View.VISIBLE); - } - - itemView.setBackgroundColor(mCommentBackgroundColor); - placeholderTextView.setTextColor(mPrimaryTextColor); - commentDivider.setBackgroundColor(mDividerColor); - } - } - - class LoadCommentsViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.comment_progress_bar_item_load_comments) - CircleProgressBar circleProgressBar; - - LoadCommentsViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - circleProgressBar.setBackgroundTintList(ColorStateList.valueOf(mCircularProgressBarBackgroundColor)); - circleProgressBar.setColorSchemeColors(mColorAccent); - } - } - - class LoadCommentsFailedViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_load_comments_failed_placeholder) - TextView errorTextView; - - LoadCommentsFailedViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - itemView.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingComments()); - errorTextView.setTextColor(mSecondaryTextColor); - } - } - - class NoCommentViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_no_comment_placeholder) - TextView errorTextView; - - NoCommentViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - errorTextView.setTextColor(mSecondaryTextColor); - } - } - - class IsLoadingMoreCommentsViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_item_comment_footer_loading) - ProgressBar progressbar; - - IsLoadingMoreCommentsViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - progressbar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - } - } - - class LoadMoreCommentsFailedViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_comment_footer_error) - TextView errorTextView; - @BindView(R.id.retry_button_item_comment_footer_error) - Button retryButton; - - LoadMoreCommentsFailedViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - errorTextView.setText(R.string.load_comments_failed); - retryButton.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingMoreComments()); - errorTextView.setTextColor(mSecondaryTextColor); - retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); - retryButton.setTextColor(mButtonTextColor); - } - } - - class ViewAllCommentsViewHolder extends RecyclerView.ViewHolder { - - ViewAllCommentsViewHolder(@NonNull View itemView) { - super(itemView); - - itemView.setOnClickListener(view -> { - if (mActivity != null && mActivity instanceof ViewPostDetailActivity) { - mIsSingleCommentThreadMode = false; - mSingleCommentId = null; - ((ViewPostDetailActivity) mActivity).changeToNomalThreadMode(); - } - }); - - itemView.setBackgroundTintList(ColorStateList.valueOf(mCommentBackgroundColor)); - ((TextView) itemView).setTextColor(mColorAccent); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentsListingRecyclerViewAdapter.java deleted file mode 100644 index 3ab89e83..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CommentsListingRecyclerViewAdapter.java +++ /dev/null @@ -1,730 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.graphics.Color; -import android.net.Uri; -import android.os.Bundle; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.TextPaint; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -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; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.constraintlayout.widget.ConstraintSet; -import androidx.paging.PagedListAdapter; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.RecyclerView; - -import java.util.Locale; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPostDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.CommentMoreBottomSheetFragment; -import ml.docilealligator.infinityforreddit.Comment.Comment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SaveThing; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import ml.docilealligator.infinityforreddit.VoteThing; -import retrofit2.Retrofit; - -public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { - private static final int VIEW_TYPE_DATA = 0; - private static final int VIEW_TYPE_ERROR = 1; - private static final int VIEW_TYPE_LOADING = 2; - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull Comment comment, @NonNull Comment t1) { - return comment.getId().equals(t1.getId()); - } - - @Override - public boolean areContentsTheSame(@NonNull Comment comment, @NonNull Comment t1) { - return comment.getCommentMarkdown().equals(t1.getCommentMarkdown()); - } - }; - private Context mContext; - private Retrofit mOauthRetrofit; - private Locale mLocale; - private Markwon mMarkwon; - private String mAccessToken; - private String mAccountName; - private int mColorPrimaryLightTheme; - private int mSecondaryTextColor; - private int mCommentBackgroundColor; - private int mCommentColor; - private int mDividerColor; - private int mUsernameColor; - private int mAuthorFlairColor; - private int mSubredditColor; - private int mUpvotedColor; - private int mDownvotedColor; - private int mButtonTextColor; - private int mColorAccent; - private int mCommentIconAndInfoColor; - private boolean mVoteButtonsOnTheRight; - private boolean mShowElapsedTime; - private String mTimeFormatPattern; - private boolean mShowCommentDivider; - private boolean mShowAbsoluteNumberOfVotes; - private NetworkState networkState; - private RetryLoadingMoreCallback mRetryLoadingMoreCallback; - - public CommentsListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, - CustomThemeWrapper customThemeWrapper, Locale locale, - SharedPreferences sharedPreferences, String accessToken, - String accountName, RetryLoadingMoreCallback retryLoadingMoreCallback) { - super(DIFF_CALLBACK); - mContext = context; - mOauthRetrofit = oauthRetrofit; - mCommentColor = customThemeWrapper.getCommentColor(); - int commentSpoilerBackgroundColor = mCommentColor | 0xFF000000; - mMarkwon = Markwon.builder(mContext) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - while (matcher.find()) { - markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); - } - - @Override - public void afterSetText(@NonNull TextView textView) { - textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - int matcherStart = matcher.start(); - int matcherEnd = matcher.end(); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(mCommentColor); - } else { - ds.bgColor = commentSpoilerBackgroundColor; - ds.setColor(mCommentColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcherStart, matcherEnd - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcherEnd - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(customThemeWrapper.getLinkColor()); - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mContext, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - mContext.startActivity(intent); - }); - - } - }) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .build(); - mLocale = locale; - mAccessToken = accessToken; - mAccountName = accountName; - mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); - mShowCommentDivider = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_COMMENT_DIVIDER, false); - mShowAbsoluteNumberOfVotes = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES, true); - mVoteButtonsOnTheRight = sharedPreferences.getBoolean(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY, false); - mTimeFormatPattern = sharedPreferences.getString(SharedPreferencesUtils.TIME_FORMAT_KEY, SharedPreferencesUtils.TIME_FORMAT_DEFAULT_VALUE); - mRetryLoadingMoreCallback = retryLoadingMoreCallback; - mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - mCommentBackgroundColor = customThemeWrapper.getCommentBackgroundColor(); - mCommentColor = customThemeWrapper.getCommentColor(); - mDividerColor = customThemeWrapper.getDividerColor(); - mSubredditColor = customThemeWrapper.getSubreddit(); - mUsernameColor = customThemeWrapper.getUsername(); - mAuthorFlairColor = customThemeWrapper.getAuthorFlairTextColor(); - mUpvotedColor = customThemeWrapper.getUpvoted(); - mDownvotedColor = customThemeWrapper.getDownvoted(); - mButtonTextColor = customThemeWrapper.getButtonTextColor(); - mColorAccent = customThemeWrapper.getColorAccent(); - mCommentIconAndInfoColor = customThemeWrapper.getCommentIconAndInfoColor(); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if (viewType == VIEW_TYPE_DATA) { - return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); - } else if (viewType == VIEW_TYPE_ERROR) { - return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false)); - } else { - return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof CommentViewHolder) { - Comment comment = getItem(holder.getAdapterPosition()); - if (comment != null) { - if (comment.getSubredditName().substring(2).equals(comment.getLinkAuthor())) { - String name = "u/" + comment.getLinkAuthor(); - ((CommentViewHolder) holder).authorTextView.setText(name); - ((CommentViewHolder) holder).authorTextView.setTextColor(mUsernameColor); - } else { - String name = "r/" + comment.getSubredditName(); - ((CommentViewHolder) holder).authorTextView.setText(name); - ((CommentViewHolder) holder).authorTextView.setTextColor(mSubredditColor); - } - - if (comment.getAuthorFlairHTML() != null && !comment.getAuthorFlairHTML().equals("")) { - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).authorFlairTextView, comment.getAuthorFlairHTML(), true); - } else if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); - ((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair()); - } - - if (mShowElapsedTime) { - ((CommentViewHolder) holder).commentTimeTextView.setText( - Utils.getElapsedTime(mContext, comment.getCommentTimeMillis())); - } else { - ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); - } - - if (comment.getAwards() != null && !comment.getAwards().equals("")) { - ((CommentViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).awardsTextView, comment.getAwards(), true); - } - - mMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentMarkdown()); - - ((CommentViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - - switch (comment.getVoteType()) { - case Comment.VOTE_TYPE_UPVOTE: - ((CommentViewHolder) holder).upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); - break; - case Comment.VOTE_TYPE_DOWNVOTE: - ((CommentViewHolder) holder).downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); - break; - } - - ((CommentViewHolder) holder).verticalBlock.setVisibility(View.GONE); - - if (comment.isSaved()) { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - } else { - ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - } - } - } - } - - @Override - public int getItemViewType(int position) { - // Reached at the end - if (hasExtraRow() && position == getItemCount() - 1) { - if (networkState.getStatus() == NetworkState.Status.LOADING) { - return VIEW_TYPE_LOADING; - } else { - return VIEW_TYPE_ERROR; - } - } else { - return VIEW_TYPE_DATA; - } - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if (holder instanceof CommentViewHolder) { - ((CommentViewHolder) holder).authorFlairTextView.setText(""); - ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); - ((CommentViewHolder) holder).awardsTextView.setText(""); - ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); - ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - } - - @Override - public int getItemCount() { - if (hasExtraRow()) { - return super.getItemCount() + 1; - } - return super.getItemCount(); - } - - private boolean hasExtraRow() { - return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; - } - - public void setNetworkState(NetworkState newNetworkState) { - NetworkState previousState = this.networkState; - boolean previousExtraRow = hasExtraRow(); - this.networkState = newNetworkState; - boolean newExtraRow = hasExtraRow(); - if (previousExtraRow != newExtraRow) { - if (previousExtraRow) { - notifyItemRemoved(super.getItemCount()); - } else { - notifyItemInserted(super.getItemCount()); - } - } else if (newExtraRow && !previousState.equals(newNetworkState)) { - notifyItemChanged(getItemCount() - 1); - } - } - - public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) { - if (viewHolder instanceof CommentViewHolder) { - if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { - if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((CommentViewHolder) viewHolder).upvoteButton.performClick(); - } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((CommentViewHolder) viewHolder).downvoteButton.performClick(); - } - } else { - if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - ((CommentViewHolder) viewHolder).upvoteButton.performClick(); - } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - ((CommentViewHolder) viewHolder).downvoteButton.performClick(); - } - } - } - } - - public void giveAward(String awardsHTML, int position) { - if (position >= 0 && position < getItemCount()) { - Comment comment = getItem(position); - if (comment != null) { - comment.addAwards(awardsHTML); - notifyItemChanged(position); - } - } - } - - public void editComment(String commentContentMarkdown, int position) { - Comment comment = getItem(position); - if (comment != null) { - comment.setCommentMarkdown(commentContentMarkdown); - notifyItemChanged(position); - } - } - - public interface RetryLoadingMoreCallback { - void retryLoadingMore(); - } - - public class CommentViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.linear_layout_item_comment) - LinearLayout linearLayout; - @BindView(R.id.vertical_block_item_post_comment) - View verticalBlock; - @BindView(R.id.author_text_view_item_post_comment) - TextView authorTextView; - @BindView(R.id.author_flair_text_view_item_post_comment) - TextView authorFlairTextView; - @BindView(R.id.comment_time_text_view_item_post_comment) - TextView commentTimeTextView; - @BindView(R.id.awards_text_view_item_comment) - TextView awardsTextView; - @BindView(R.id.comment_markdown_view_item_post_comment) - TextView commentMarkdownView; - @BindView(R.id.bottom_constraint_layout_item_post_comment) - ConstraintLayout bottomConstraintLayout; - @BindView(R.id.up_vote_button_item_post_comment) - ImageView upvoteButton; - @BindView(R.id.score_text_view_item_post_comment) - TextView scoreTextView; - @BindView(R.id.down_vote_button_item_post_comment) - ImageView downvoteButton; - @BindView(R.id.more_button_item_post_comment) - ImageView moreButton; - @BindView(R.id.save_button_item_post_comment) - ImageView saveButton; - @BindView(R.id.expand_button_item_post_comment) - ImageView expandButton; - @BindView(R.id.reply_button_item_post_comment) - ImageView replyButton; - @BindView(R.id.divider_item_comment) - View commentDivider; - - CommentViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - replyButton.setVisibility(View.GONE); - - 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(expandButton.getId(), ConstraintSet.END); - constraintSet.clear(replyButton.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(saveButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); - constraintSet.connect(moreButton.getId(), ConstraintSet.START, saveButton.getId(), ConstraintSet.END); - constraintSet.connect(moreButton.getId(), ConstraintSet.END, upvoteButton.getId(), ConstraintSet.END); - constraintSet.connect(expandButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); - constraintSet.connect(replyButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); - constraintSet.setHorizontalBias(moreButton.getId(), 0); - constraintSet.applyTo(bottomConstraintLayout); - } - - if (mShowCommentDivider) { - commentDivider.setVisibility(View.VISIBLE); - } - - itemView.setBackgroundColor(mCommentBackgroundColor); - authorTextView.setTextColor(mUsernameColor); - authorFlairTextView.setTextColor(mAuthorFlairColor); - commentTimeTextView.setTextColor(mSecondaryTextColor); - awardsTextView.setTextColor(mSecondaryTextColor); - commentMarkdownView.setTextColor(mCommentColor); - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - commentDivider.setBackgroundColor(mDividerColor); - - commentMarkdownView.setMovementMethod(LinkMovementMethod.getInstance()); - - authorTextView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Comment comment = getItem(getAdapterPosition()); - if (comment != null) { - if (comment.getSubredditName().substring(2).equals(comment.getLinkAuthor())) { - Intent intent = new Intent(mContext, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, comment.getLinkAuthor()); - mContext.startActivity(intent); - } else { - Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, comment.getSubredditName()); - mContext.startActivity(intent); - } - } - }); - - moreButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Comment comment = getItem(getAdapterPosition()); - if (comment != null) { - Bundle bundle = new Bundle(); - if (comment.getAuthor().equals(mAccountName)) { - bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true); - } - bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); - bundle.putParcelable(CommentMoreBottomSheetFragment.EXTRA_COMMENT, comment); - bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getAdapterPosition()); - bundle.putString(CommentMoreBottomSheetFragment.EXTRA_COMMENT_MARKDOWN, comment.getCommentMarkdown()); - CommentMoreBottomSheetFragment commentMoreBottomSheetFragment = new CommentMoreBottomSheetFragment(); - commentMoreBottomSheetFragment.setArguments(bundle); - commentMoreBottomSheetFragment.show(((AppCompatActivity) mContext).getSupportFragmentManager(), commentMoreBottomSheetFragment.getTag()); - } - }); - - linearLayout.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Comment comment = getItem(getAdapterPosition()); - if (comment != null) { - Intent intent = new Intent(mContext, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getLinkId()); - intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId()); - mContext.startActivity(intent); - } - }); - - commentMarkdownView.setOnClickListener(view -> { - if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { - linearLayout.callOnClick(); - } - }); - - upvoteButton.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Comment comment = getItem(getAdapterPosition()); - if (comment != null) { - int previousVoteType = comment.getVoteType(); - String newVoteType; - - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { - //Not upvoted before - comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); - newVoteType = APIUtils.DIR_UPVOTE; - upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - newVoteType = APIUtils.DIR_UNVOTE; - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - - VoteThing.voteThing(mContext, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position) { - if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { - comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); - upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - } - - @Override - public void onVoteThingFail(int position) { - } - }, comment.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - downvoteButton.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Comment comment = getItem(getAdapterPosition()); - if (comment != null) { - int previousVoteType = comment.getVoteType(); - String newVoteType; - - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { - //Not downvoted before - comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); - newVoteType = APIUtils.DIR_DOWNVOTE; - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - //Downvoted before - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - newVoteType = APIUtils.DIR_UNVOTE; - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - - VoteThing.voteThing(mContext, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { - comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); - downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); - downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mCommentIconAndInfoColor); - } - - upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, - comment.getScore() + comment.getVoteType())); - } - - @Override - public void onVoteThingFail(int position1) { - } - }, comment.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - saveButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Comment comment = getItem(getAdapterPosition()); - if (comment != null) { - if (comment.isSaved()) { - comment.setSaved(false); - SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { - @Override - public void success() { - comment.setSaved(false); - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - Toast.makeText(mContext, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - comment.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mContext, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show(); - } - }); - } else { - comment.setSaved(true); - SaveThing.saveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { - @Override - public void success() { - comment.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mContext, R.string.comment_saved_success, Toast.LENGTH_SHORT).show(); - } - - @Override - public void failed() { - comment.setSaved(false); - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - Toast.makeText(mContext, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show(); - } - }); - } - } - }); - } - } - - class ErrorViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_footer_error) - TextView errorTextView; - @BindView(R.id.retry_button_item_footer_error) - Button retryButton; - - ErrorViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - errorTextView.setText(R.string.load_comments_failed); - retryButton.setOnClickListener(view -> mRetryLoadingMoreCallback.retryLoadingMore()); - errorTextView.setTextColor(mSecondaryTextColor); - retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); - retryButton.setTextColor(mButtonTextColor); - } - } - - class LoadingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_item_footer_loading) - ProgressBar progressBar; - - LoadingViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomThemeListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomThemeListingRecyclerViewAdapter.java deleted file mode 100644 index c4ea3963..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomThemeListingRecyclerViewAdapter.java +++ /dev/null @@ -1,170 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Intent; -import android.content.res.ColorStateList; -import android.os.Bundle; -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.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.RecyclerView; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.CustomThemeListingActivity; -import ml.docilealligator.infinityforreddit.Activity.CustomizeThemeActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.CustomThemeOptionsBottomSheetFragment; -import ml.docilealligator.infinityforreddit.R; - -public class CustomThemeListingRecyclerViewAdapter extends RecyclerView.Adapter { - private static final int VIEW_TYPE_PREDEFINED_THEME = 0; - private static final int VIEW_TYPE_USER_THME = 1; - private static final int VIEW_TYPE_PREDEFINED_THEME_DIVIDER = 2; - private static final int VIEW_TYPE_USER_THEME_DIVIDER = 3; - - private AppCompatActivity activity; - private ArrayList predefinedCustomThemes; - private ArrayList userCustomThemes; - - public CustomThemeListingRecyclerViewAdapter(AppCompatActivity activity, ArrayList predefinedCustomThemes) { - this.activity = activity; - this.predefinedCustomThemes = predefinedCustomThemes; - userCustomThemes = new ArrayList<>(); - } - - @Override - public int getItemViewType(int position) { - if (position == 0) { - return VIEW_TYPE_PREDEFINED_THEME_DIVIDER; - } else if (position < 1 + predefinedCustomThemes.size()) { - return VIEW_TYPE_PREDEFINED_THEME; - } else if (position == 1 + predefinedCustomThemes.size()) { - return VIEW_TYPE_USER_THEME_DIVIDER; - } else { - return VIEW_TYPE_USER_THME; - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - switch (viewType) { - case VIEW_TYPE_PREDEFINED_THEME_DIVIDER: - return new PreDefinedThemeDividerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_theme_type_divider, parent, false)); - case VIEW_TYPE_PREDEFINED_THEME: - return new PredefinedCustomThemeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_predefined_custom_theme, parent, false)); - case VIEW_TYPE_USER_THEME_DIVIDER: - return new UserThemeDividerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_theme_type_divider, parent, false)); - default: - return new UserCustomThemeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_custom_theme, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof PredefinedCustomThemeViewHolder) { - CustomTheme customTheme = predefinedCustomThemes.get(position - 1); - ((PredefinedCustomThemeViewHolder) holder).colorPrimaryView.setBackgroundTintList(ColorStateList.valueOf(customTheme.colorPrimary)); - ((PredefinedCustomThemeViewHolder) holder).nameTextView.setText(customTheme.name); - ((PredefinedCustomThemeViewHolder) holder).itemView.setOnClickListener(view -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, customTheme.name); - intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); - intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); - activity.startActivity(intent); - }); - } else if (holder instanceof UserCustomThemeViewHolder) { - CustomTheme customTheme = userCustomThemes.get(position - predefinedCustomThemes.size() - 2); - ((UserCustomThemeViewHolder) holder).colorPrimaryView.setBackgroundTintList(ColorStateList.valueOf(customTheme.colorPrimary)); - ((UserCustomThemeViewHolder) holder).nameTextView.setText(customTheme.name); - ((UserCustomThemeViewHolder) holder).createThemeImageView.setOnClickListener(view -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, customTheme.name); - intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); - activity.startActivity(intent); - }); - ((UserCustomThemeViewHolder) holder).shareImageView.setOnClickListener(view -> { - ((CustomThemeListingActivity) activity).shareTheme(customTheme); - }); - ((UserCustomThemeViewHolder) holder).itemView.setOnClickListener(view -> { - CustomThemeOptionsBottomSheetFragment customThemeOptionsBottomSheetFragment = new CustomThemeOptionsBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putString(CustomThemeOptionsBottomSheetFragment.EXTRA_THEME_NAME, customTheme.name); - customThemeOptionsBottomSheetFragment.setArguments(bundle); - customThemeOptionsBottomSheetFragment.show(activity.getSupportFragmentManager(), customThemeOptionsBottomSheetFragment.getTag()); - }); - ((UserCustomThemeViewHolder) holder).itemView.setOnLongClickListener(view -> { - ((UserCustomThemeViewHolder) holder).itemView.performClick(); - return true; - }); - } else if (holder instanceof PreDefinedThemeDividerViewHolder) { - ((TextView) ((PreDefinedThemeDividerViewHolder) holder).itemView).setText(R.string.predefined_themes); - } else if (holder instanceof UserThemeDividerViewHolder) { - ((TextView) ((UserThemeDividerViewHolder) holder).itemView).setText(R.string.user_themes); - } - } - - @Override - public int getItemCount() { - return predefinedCustomThemes.size() + userCustomThemes.size() + 2; - } - - public void setUserThemes(List userThemes) { - userCustomThemes = (ArrayList) userThemes; - notifyDataSetChanged(); - } - - class PredefinedCustomThemeViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.color_primary_item_predefined_custom_theme) - View colorPrimaryView; - @BindView(R.id.name_text_view_item_predefined_custom_theme) - TextView nameTextView; - @BindView(R.id.add_image_view_item_predefined_custom_theme) - ImageView createThemeImageView; - - PredefinedCustomThemeViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } - - class UserCustomThemeViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.color_primary_item_user_custom_theme) - View colorPrimaryView; - @BindView(R.id.name_text_view_item_user_custom_theme) - TextView nameTextView; - @BindView(R.id.add_image_view_item_user_custom_theme) - ImageView createThemeImageView; - @BindView(R.id.share_image_view_item_user_custom_theme) - ImageView shareImageView; - - UserCustomThemeViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } - - class PreDefinedThemeDividerViewHolder extends RecyclerView.ViewHolder { - - PreDefinedThemeDividerViewHolder(@NonNull View itemView) { - super(itemView); - } - } - - class UserThemeDividerViewHolder extends RecyclerView.ViewHolder { - - UserThemeDividerViewHolder(@NonNull View itemView) { - super(itemView); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java deleted file mode 100644 index 95833e72..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/CustomizeThemeRecyclerViewAdapter.java +++ /dev/null @@ -1,178 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.Switch; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import java.util.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeSettingsItem; -import ml.docilealligator.infinityforreddit.CustomView.ColorPickerDialog; -import ml.docilealligator.infinityforreddit.R; - -public class CustomizeThemeRecyclerViewAdapter extends RecyclerView.Adapter { - private static final int VIEW_TYPE_COLOR = 1; - private static final int VIEW_TYPE_SWITCH = 2; - private static final int VIEW_TYPE_THEME_NAME = 3; - private AppCompatActivity activity; - private ArrayList customThemeSettingsItems; - private String themeName; - private boolean isPredefinedTheme; - - public CustomizeThemeRecyclerViewAdapter(AppCompatActivity activity, String themeName, - boolean isPredefinedTheme) { - this.activity = activity; - customThemeSettingsItems = new ArrayList<>(); - this.themeName = themeName; - this.isPredefinedTheme = isPredefinedTheme; - } - - @Override - public int getItemViewType(int position) { - if (position == 0) { - return VIEW_TYPE_THEME_NAME; - } else if (position > 3 && position < customThemeSettingsItems.size() - 2) { - return VIEW_TYPE_COLOR; - } - - return VIEW_TYPE_SWITCH; - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if (viewType == VIEW_TYPE_SWITCH) { - return new ThemeSwitchItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_custom_theme_switch_item, parent, false)); - } else if (viewType == VIEW_TYPE_THEME_NAME) { - return new ThemeNameItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_theme_name, parent, false)); - } - - return new ThemeColorItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_custom_theme_color_item, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof ThemeColorItemViewHolder) { - CustomThemeSettingsItem customThemeSettingsItem = customThemeSettingsItems.get(position - 1); - ((ThemeColorItemViewHolder) holder).themeItemNameTextView.setText(customThemeSettingsItem.itemName); - ((ThemeColorItemViewHolder) holder).themeItemInfoTextView.setText(customThemeSettingsItem.itemDetails); - ((ThemeColorItemViewHolder) holder).colorImageView.setBackgroundTintList(ColorStateList.valueOf(customThemeSettingsItem.colorValue)); - holder.itemView.setOnClickListener(view -> { - new ColorPickerDialog(activity, customThemeSettingsItem.colorValue, color -> { - customThemeSettingsItem.colorValue = color; - ((ThemeColorItemViewHolder) holder).colorImageView.setBackgroundTintList(ColorStateList.valueOf(color)); - }).show(); - }); - } else if (holder instanceof ThemeSwitchItemViewHolder) { - CustomThemeSettingsItem customThemeSettingsItem = customThemeSettingsItems.get(position - 1); - ((ThemeSwitchItemViewHolder) holder).themeItemNameTextView.setText(customThemeSettingsItem.itemName); - ((ThemeSwitchItemViewHolder) holder).themeItemInfoTextView.setText(customThemeSettingsItem.itemName); - ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.setChecked(customThemeSettingsItem.isEnabled); - ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.setOnClickListener(view -> customThemeSettingsItem.isEnabled = ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.isChecked()); - holder.itemView.setOnClickListener(view -> ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.performClick()); - } else if (holder instanceof ThemeNameItemViewHolder) { - ((ThemeNameItemViewHolder) holder).themeNameTextView.setText(themeName); - holder.itemView.setOnClickListener(view -> { - View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); - EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); - themeNameEditText.setText(themeName); - themeNameEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.edit_theme_name) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - if (imm != null) { - imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); - } - themeName = themeNameEditText.getText().toString(); - ((ThemeNameItemViewHolder) holder).themeNameTextView.setText(themeName); - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); - } - }) - .setOnDismissListener(dialogInterface -> { - if (imm != null) { - imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); - } - }) - .show(); - }); - } - } - - @Override - public int getItemCount() { - return customThemeSettingsItems.size() + 1; - } - - public void setCustomThemeSettingsItem(ArrayList customThemeSettingsItems) { - this.customThemeSettingsItems.clear(); - notifyDataSetChanged(); - this.customThemeSettingsItems.addAll(customThemeSettingsItems); - notifyDataSetChanged(); - } - - public String getThemeName() { - return themeName; - } - - class ThemeColorItemViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.color_image_view_item_custom_theme_color_item) - View colorImageView; - @BindView(R.id.theme_item_name_text_view_item_custom_theme_color_item) - TextView themeItemNameTextView; - @BindView(R.id.theme_item_info_text_view_item_custom_theme_color_item) - TextView themeItemInfoTextView; - - ThemeColorItemViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } - - class ThemeSwitchItemViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.theme_item_name_text_view_item_custom_theme_switch_item) - TextView themeItemNameTextView; - @BindView(R.id.theme_item_info_text_view_item_custom_theme_switch_item) - TextView themeItemInfoTextView; - @BindView(R.id.theme_item_switch_item_custom_theme_switch_item) - Switch themeItemSwitch; - - ThemeSwitchItemViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } - - class ThemeNameItemViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.theme_name_text_view_item_theme_name) - TextView themeNameTextView; - @BindView(R.id.description_text_view_item_theme_name) - TextView descriptionTextView; - public ThemeNameItemViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FlairBottomSheetRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FlairBottomSheetRecyclerViewAdapter.java deleted file mode 100644 index 0f016b53..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FlairBottomSheetRecyclerViewAdapter.java +++ /dev/null @@ -1,114 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.app.Activity; -import android.content.Context; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.ImageView; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import java.util.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.R; - -public class FlairBottomSheetRecyclerViewAdapter extends RecyclerView.Adapter { - private Context context; - private ArrayList flairs; - private int flairTextColor; - private ItemClickListener itemClickListener; - - public FlairBottomSheetRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper, - ItemClickListener itemClickListener) { - this.context = context; - flairTextColor = customThemeWrapper.getPrimaryTextColor(); - this.itemClickListener = itemClickListener; - } - - @NonNull - @Override - public FlairViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new FlairViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_flair, null, false)); - } - - @Override - public void onBindViewHolder(@NonNull FlairViewHolder holder, int position) { - if (flairs.get(holder.getAdapterPosition()).isEditable()) { - holder.editFlairImageView.setVisibility(View.VISIBLE); - holder.editFlairImageView.setOnClickListener(view -> { - View dialogView = ((Activity) context).getLayoutInflater().inflate(R.layout.dialog_edit_flair, null); - EditText flairEditText = dialogView.findViewById(R.id.flair_edit_text_edit_flair_dialog); - flairEditText.requestFocus(); - InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - new MaterialAlertDialogBuilder(context, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.edit_flair) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - Flair flair = flairs.get(holder.getAdapterPosition()); - flair.setText(flairEditText.getText().toString()); - itemClickListener.onClick(flair); - }) - .setNegativeButton(R.string.cancel, null) - .show(); - }); - } - - if (flairs.get(holder.getAdapterPosition()).isEditable() && flairs.get(holder.getAdapterPosition()).getText().equals("")) { - holder.itemView.setOnClickListener(view -> holder.editFlairImageView.performClick()); - } else { - holder.itemView.setOnClickListener(view -> itemClickListener.onClick(flairs.get(holder.getAdapterPosition()))); - } - - holder.flairTextView.setText(flairs.get(holder.getAdapterPosition()).getText()); - } - - @Override - public int getItemCount() { - return flairs == null ? 0 : flairs.size(); - } - - @Override - public void onViewRecycled(@NonNull FlairViewHolder holder) { - super.onViewRecycled(holder); - holder.editFlairImageView.setVisibility(View.GONE); - } - - public void changeDataset(ArrayList flairs) { - this.flairs = flairs; - notifyDataSetChanged(); - } - - public interface ItemClickListener { - void onClick(Flair flair); - } - - class FlairViewHolder extends RecyclerView.ViewHolder { - View itemView; - @BindView(R.id.flair_text_view_item_flair) - TextView flairTextView; - @BindView(R.id.edit_flair_image_view_item_flair) - ImageView editFlairImageView; - - FlairViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - this.itemView = itemView; - flairTextView.setTextColor(flairTextColor); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FollowedUsersRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FollowedUsersRecyclerViewAdapter.java deleted file mode 100644 index 5e2cf2da..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/FollowedUsersRecyclerViewAdapter.java +++ /dev/null @@ -1,359 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import me.zhanghai.android.fastscroll.PopupTextProvider; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FavoriteThing; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class FollowedUsersRecyclerViewAdapter extends RecyclerView.Adapter implements PopupTextProvider { - private static final int VIEW_TYPE_FAVORITE_USER_DIVIDER = 0; - private static final int VIEW_TYPE_FAVORITE_USER = 1; - private static final int VIEW_TYPE_USER_DIVIDER = 2; - private static final int VIEW_TYPE_USER = 3; - - private List mSubscribedUserData; - private List mFavoriteSubscribedUserData; - private Context mContext; - private Retrofit mOauthRetrofit; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private String mAccessToken; - private RequestManager glide; - private int mPrimaryTextColor; - private int mSecondaryTextColor; - - public FollowedUsersRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, - RedditDataRoomDatabase redditDataRoomDatabase, - CustomThemeWrapper customThemeWrapper, - String accessToken) { - mContext = context; - mOauthRetrofit = oauthRetrofit; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mAccessToken = accessToken; - glide = Glide.with(context); - mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - } - - @Override - public int getItemViewType(int position) { - if (mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) { - if (position == 0) { - return VIEW_TYPE_FAVORITE_USER_DIVIDER; - } else if (position == mFavoriteSubscribedUserData.size() + 1) { - return VIEW_TYPE_USER_DIVIDER; - } else if (position <= mFavoriteSubscribedUserData.size()) { - return VIEW_TYPE_FAVORITE_USER; - } else { - return VIEW_TYPE_USER; - } - } else { - return VIEW_TYPE_USER; - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { - switch (i) { - case VIEW_TYPE_FAVORITE_USER_DIVIDER: - return new FavoriteUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); - case VIEW_TYPE_FAVORITE_USER: - return new FavoriteUserViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_subscribed_thing, viewGroup, false)); - case VIEW_TYPE_USER_DIVIDER: - return new AllUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); - default: - return new UserViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_subscribed_thing, viewGroup, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) { - if (viewHolder instanceof UserViewHolder) { - int offset = (mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) ? - mFavoriteSubscribedUserData.size() + 2 : 0; - - viewHolder.itemView.setOnClickListener(view -> { - Intent intent = new Intent(mContext, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getName()); - mContext.startActivity(intent); - }); - if (!mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getIconUrl().equals("")) { - glide.load(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((UserViewHolder) viewHolder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((UserViewHolder) viewHolder).iconGifImageView); - } - ((UserViewHolder) viewHolder).userNameTextView.setText(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getName()); - - if(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } else { - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - ((UserViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { - if(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).setFavorite(false); - FavoriteThing.unfavoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, - mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(false); - } - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(true); - } - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - }); - } else { - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).setFavorite(true); - FavoriteThing.favoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, - mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(true); - } - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(false); - } - ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - }); - } - }); - } else if (viewHolder instanceof FavoriteUserViewHolder) { - viewHolder.itemView.setOnClickListener(view -> { - Intent intent = new Intent(mContext, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getName()); - mContext.startActivity(intent); - }); - if (!mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getIconUrl().equals("")) { - glide.load(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((FavoriteUserViewHolder) viewHolder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((FavoriteUserViewHolder) viewHolder).iconGifImageView); - } - ((FavoriteUserViewHolder) viewHolder).userNameTextView.setText(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getName()); - - if(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).isFavorite()) { - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } else { - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { - if(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).isFavorite()) { - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).setFavorite(false); - FavoriteThing.unfavoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, - mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(false); - } - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(true); - } - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - }); - } else { - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).setFavorite(true); - FavoriteThing.favoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, - mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(true); - } - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { - mFavoriteSubscribedUserData.get(position).setFavorite(false); - } - ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - }); - } - }); - } - } - - @Override - public int getItemCount() { - if (mSubscribedUserData != null && mSubscribedUserData.size() > 0) { - if(mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) { - return mSubscribedUserData.size() + mFavoriteSubscribedUserData.size() + 2; - } - return mSubscribedUserData.size(); - } - return 0; - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if(holder instanceof UserViewHolder) { - glide.clear(((UserViewHolder) holder).iconGifImageView); - } else if (holder instanceof FavoriteUserViewHolder) { - glide.clear(((FavoriteUserViewHolder) holder).iconGifImageView); - } - } - - public void setSubscribedUsers(List subscribedUsers) { - mSubscribedUserData = subscribedUsers; - notifyDataSetChanged(); - } - - public void setFavoriteSubscribedUsers(List favoriteSubscribedUsers) { - mFavoriteSubscribedUserData = favoriteSubscribedUsers; - notifyDataSetChanged(); - } - - @NonNull - @Override - public String getPopupText(int position) { - switch (getItemViewType(position)) { - case VIEW_TYPE_USER: - int offset = (mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) ? - mFavoriteSubscribedUserData.size() + 2 : 0; - return mSubscribedUserData.get(position - offset).getName().substring(0, 1).toUpperCase(); - case VIEW_TYPE_FAVORITE_USER: - return mFavoriteSubscribedUserData.get(position - 1).getName().substring(0, 1).toUpperCase(); - default: - return ""; - } - } - - class FavoriteUserViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) - GifImageView iconGifImageView; - @BindView(R.id.thing_name_text_view_item_subscribed_thing) - TextView userNameTextView; - @BindView(R.id.favorite_image_view_item_subscribed_thing) - ImageView favoriteImageView; - - FavoriteUserViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - userNameTextView.setTextColor(mPrimaryTextColor); - } - } - - class UserViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) - GifImageView iconGifImageView; - @BindView(R.id.thing_name_text_view_item_subscribed_thing) - TextView userNameTextView; - @BindView(R.id.favorite_image_view_item_subscribed_thing) - ImageView favoriteImageView; - - UserViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - userNameTextView.setTextColor(mPrimaryTextColor); - } - } - - class FavoriteUsersDividerViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; - - FavoriteUsersDividerViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - dividerTextView.setText(R.string.favorites); - dividerTextView.setTextColor(mSecondaryTextColor); - } - } - - class AllUsersDividerViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; - - AllUsersDividerViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - dividerTextView.setText(R.string.all); - dividerTextView.setTextColor(mSecondaryTextColor); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MarkdownBottomBarRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MarkdownBottomBarRecyclerViewAdapter.java deleted file mode 100644 index e8d2362a..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MarkdownBottomBarRecyclerViewAdapter.java +++ /dev/null @@ -1,260 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.app.Activity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.EditText; -import android.widget.ImageView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.slider.Slider; - -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; - -public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter { - - public static final int BOLD = 0; - public static final int ITALIC = 1; - public static final int LINK = 2; - public static final int STRIKE_THROUGH = 3; - public static final int HEADER = 4; - public static final int ORDERED_LIST = 5; - public static final int UNORDERED_LIST = 6; - public static final int SPOILER = 7; - - private static final int ITEM_COUNT = 8; - - private CustomThemeWrapper customThemeWrapper; - private ItemClickListener itemClickListener; - - public interface ItemClickListener { - void onClick(int item); - } - - public MarkdownBottomBarRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, - ItemClickListener itemClickListener) { - this.customThemeWrapper = customThemeWrapper; - this.itemClickListener = itemClickListener; - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new MarkdownBottomBarItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_markdown_bottom_bar, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof MarkdownBottomBarItemViewHolder) { - switch (position) { - case BOLD: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_bold_black_24dp); - break; - case ITALIC: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_italic_black_24dp); - break; - case LINK: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_link_round_black_24dp); - break; - case STRIKE_THROUGH: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_strikethrough_black_24dp); - break; - case HEADER: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_title_24dp); - break; - case ORDERED_LIST: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_ordered_list_black_24dp); - break; - case UNORDERED_LIST: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_unordered_list_black_24dp); - break; - case SPOILER: - ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_spoiler_black_24dp); - break; - } - } - } - - @Override - public int getItemCount() { - return ITEM_COUNT; - } - - public static void bindEditTextWithItemClickListener(Activity activity, EditText commentEditText, int item) { - switch (item) { - case MarkdownBottomBarRecyclerViewAdapter.BOLD: { - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - "**" + currentSelection + "**", 0, "****".length() + currentSelection.length()); - } else { - commentEditText.getText().replace(start, end, - "****", 0, "****".length()); - commentEditText.setSelection(start + "**".length()); - } - break; - } - case MarkdownBottomBarRecyclerViewAdapter.ITALIC: { - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - "*" + currentSelection + "*", 0, "**".length() + currentSelection.length()); - } else { - commentEditText.getText().replace(start, end, - "**", 0, "**".length()); - commentEditText.setSelection(start + "*".length()); - } - break; - } - case MarkdownBottomBarRecyclerViewAdapter.LINK: { - View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_insert_link, null); - EditText textEditText = dialogView.findViewById(R.id.edit_text_insert_link_dialog); - EditText linkEditText = dialogView.findViewById(R.id.edit_link_insert_link_dialog); - - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - textEditText.setText(currentSelection); - } - - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.insert_link) - .setView(dialogView) - .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) - -> { - String text = textEditText.getText().toString(); - String link = linkEditText.getText().toString(); - if (text.equals("")) { - text = link; - } - - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - "[" + text + "](" + link + ")", 0, "[]()".length() + text.length() + link.length()); - }) - .setNegativeButton(R.string.cancel, null) - .show(); - break; - } - case MarkdownBottomBarRecyclerViewAdapter.STRIKE_THROUGH: { - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - "~~" + currentSelection + "~~", 0, "~~~~".length() + currentSelection.length()); - } else { - commentEditText.getText().replace(start, end, - "~~~~", 0, "~~~~".length()); - commentEditText.setSelection(start + "~~".length()); - } - break; - } - case MarkdownBottomBarRecyclerViewAdapter.HEADER: { - View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_select_header, null); - Slider seekBar = dialogView.findViewById(R.id.seek_bar_dialog_select_header); - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.select_header_size) - .setView(dialogView) - .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) - -> { - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - String hashTags; - switch ((int) seekBar.getValue()) { - case 0: - hashTags = "###### "; - break; - case 1: - hashTags = "##### "; - break; - case 2: - hashTags = "#### "; - break; - case 3: - hashTags = "### "; - break; - case 4: - hashTags = "## "; - break; - default: - hashTags = "# "; - break; - } - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - hashTags + currentSelection, 0, hashTags.length() + currentSelection.length()); - } else { - commentEditText.getText().replace(start, end, - hashTags, 0, hashTags.length()); - } - }) - .setNegativeButton(R.string.cancel, null) - .show(); - break; - } - case MarkdownBottomBarRecyclerViewAdapter.ORDERED_LIST: { - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - "1. " + currentSelection, 0, "1. ".length() + currentSelection.length()); - } else { - commentEditText.getText().replace(start, end, - "1. ", 0, "1. ".length()); - } - break; - } - case MarkdownBottomBarRecyclerViewAdapter.UNORDERED_LIST: { - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - "* " + currentSelection, 0, "* ".length() + currentSelection.length()); - } else { - commentEditText.getText().replace(start, end, - "* ", 0, "* ".length()); - } - break; - } - case MarkdownBottomBarRecyclerViewAdapter.SPOILER: { - int start = Math.max(commentEditText.getSelectionStart(), 0); - int end = Math.max(commentEditText.getSelectionEnd(), 0); - if (end != start) { - String currentSelection = commentEditText.getText().subSequence(start, end).toString(); - commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), - ">!" + currentSelection + "!<", 0, ">!!<".length() + currentSelection.length()); - } else { - commentEditText.getText().replace(start, end, - ">!!<", 0, ">!!<".length()); - commentEditText.setSelection(start + ">!".length()); - } - break; - } - } - } - - class MarkdownBottomBarItemViewHolder extends RecyclerView.ViewHolder { - ImageView imageView; - - public MarkdownBottomBarItemViewHolder(@NonNull View itemView) { - super(itemView); - imageView = (ImageView) itemView; - itemView.setOnClickListener(view -> itemClickListener.onClick(getAdapterPosition())); - - imageView.setColorFilter(customThemeWrapper.getPrimaryIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java deleted file mode 100644 index 58604abd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MessageRecyclerViewAdapter.java +++ /dev/null @@ -1,396 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.content.res.ColorStateList; -import android.graphics.Color; -import android.net.Uri; -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.TextPaint; -import android.text.method.LinkMovementMethod; -import android.text.style.ClickableSpan; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ProgressBar; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.paging.PagedListAdapter; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.RecyclerView; - -import java.util.ArrayList; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPrivateMessagesActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Message.FetchMessage; -import ml.docilealligator.infinityforreddit.Message.Message; -import ml.docilealligator.infinityforreddit.Message.ReadMessage; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import retrofit2.Retrofit; - -public class MessageRecyclerViewAdapter extends PagedListAdapter { - private static final int VIEW_TYPE_DATA = 0; - private static final int VIEW_TYPE_ERROR = 1; - private static final int VIEW_TYPE_LOADING = 2; - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull Message message, @NonNull Message t1) { - return message.getId().equals(t1.getId()); - } - - @Override - public boolean areContentsTheSame(@NonNull Message message, @NonNull Message t1) { - return message.getBody().equals(t1.getBody()); - } - }; - private Context mContext; - private Retrofit mOauthRetrofit; - private Markwon mMarkwon; - private String mAccessToken; - private int mMessageType; - private NetworkState networkState; - private RetryLoadingMoreCallback mRetryLoadingMoreCallback; - private int mColorAccent; - private int mMessageBackgroundColor; - private int mUsernameColor; - private int mPrimaryTextColor; - private int mSecondaryTextColor; - private int mUnreadMessageBackgroundColor; - private int mColorPrimaryLightTheme; - private int mButtonTextColor; - - public MessageRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, - CustomThemeWrapper customThemeWrapper, - String accessToken, String where, - RetryLoadingMoreCallback retryLoadingMoreCallback) { - super(DIFF_CALLBACK); - mContext = context; - mOauthRetrofit = oauthRetrofit; - mRetryLoadingMoreCallback = retryLoadingMoreCallback; - - mColorAccent = customThemeWrapper.getColorAccent(); - mMessageBackgroundColor = customThemeWrapper.getCardViewBackgroundColor(); - mUsernameColor = customThemeWrapper.getUsername(); - mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - int spoilerBackgroundColor = mSecondaryTextColor | 0xFF000000; - mUnreadMessageBackgroundColor = customThemeWrapper.getUnreadMessageBackgroundColor(); - mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); - mButtonTextColor = customThemeWrapper.getButtonTextColor(); - - mMarkwon = Markwon.builder(mContext) - .usePlugin(new AbstractMarkwonPlugin() { - @NonNull - @Override - public String processMarkdown(@NonNull String markdown) { - StringBuilder markdownStringBuilder = new StringBuilder(markdown); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - while (matcher.find()) { - markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); - } - return super.processMarkdown(markdownStringBuilder.toString()); - } - - @Override - public void afterSetText(@NonNull TextView textView) { - textView.setHighlightColor(Color.TRANSPARENT); - SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); - Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); - Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); - int start = 0; - boolean find = false; - while (matcher.find(start)) { - find = true; - markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); - markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); - int matcherStart = matcher.start(); - int matcherEnd = matcher.end(); - ClickableSpan clickableSpan = new ClickableSpan() { - private boolean isShowing = false; - @Override - public void updateDrawState(@NonNull TextPaint ds) { - if (isShowing) { - super.updateDrawState(ds); - ds.setColor(mSecondaryTextColor); - } else { - ds.bgColor = spoilerBackgroundColor; - ds.setColor(mSecondaryTextColor); - } - ds.setUnderlineText(false); - } - - @Override - public void onClick(@NonNull View view) { - isShowing = !isShowing; - view.invalidate(); - } - }; - markdownStringBuilder.setSpan(clickableSpan, matcherStart, matcherEnd - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - start = matcherEnd - 4; - } - if (find) { - textView.setText(markdownStringBuilder); - } - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(mContext, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - mContext.startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(customThemeWrapper.getLinkColor()); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .build(); - mAccessToken = accessToken; - if (where.equals(FetchMessage.WHERE_MESSAGES)) { - mMessageType = FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE; - } else { - mMessageType = FetchMessage.MESSAGE_TYPE_INBOX; - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if (viewType == VIEW_TYPE_DATA) { - return new DataViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message, parent, false)); - } else if (viewType == VIEW_TYPE_ERROR) { - return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false)); - } else { - return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof DataViewHolder) { - Message message = getItem(holder.getAdapterPosition()); - if (message != null) { - ArrayList replies = message.getReplies(); - Message displayedMessage; - if (replies != null && !replies.isEmpty() && replies.get(replies.size() - 1) != null) { - displayedMessage = replies.get(replies.size() - 1); - } else { - displayedMessage = message; - } - if (message.isNew()) { - ((DataViewHolder) holder).itemView.setBackgroundColor( - mUnreadMessageBackgroundColor); - } - - if (message.wasComment()) { - ((DataViewHolder) holder).titleTextView.setText(message.getTitle()); - } else { - ((DataViewHolder) holder).titleTextView.setVisibility(View.GONE); - } - - ((DataViewHolder) holder).authorTextView.setText(displayedMessage.getAuthor()); - String subject = displayedMessage.getSubject().substring(0, 1).toUpperCase() + displayedMessage.getSubject().substring(1); - ((DataViewHolder) holder).subjectTextView.setText(subject); - mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, displayedMessage.getBody()); - - ((DataViewHolder) holder).itemView.setOnClickListener(view -> { - if (mMessageType == FetchMessage.MESSAGE_TYPE_INBOX - && message.getContext() != null && !message.getContext().equals("")) { - Uri uri = LinkResolverActivity.getRedditUriByPath(message.getContext()); - Intent intent = new Intent(mContext, LinkResolverActivity.class); - intent.setData(uri); - mContext.startActivity(intent); - } else if (mMessageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE) { - Intent intent = new Intent(mContext, ViewPrivateMessagesActivity.class); - intent.putExtra(ViewPrivateMessagesActivity.EXTRA_PRIVATE_MESSAGE, message); - intent.putExtra(ViewPrivateMessagesActivity.EXTRA_MESSAGE_POSITION, holder.getAdapterPosition()); - mContext.startActivity(intent); - } - - if (displayedMessage.isNew()) { - ((DataViewHolder) holder).itemView.setBackgroundColor(mMessageBackgroundColor); - message.setNew(false); - - ReadMessage.readMessage(mOauthRetrofit, mAccessToken, message.getFullname(), - new ReadMessage.ReadMessageListener() { - @Override - public void readSuccess() { - } - - @Override - public void readFailed() { - message.setNew(true); - ((DataViewHolder) holder).itemView.setBackgroundColor(mUnreadMessageBackgroundColor); - } - }); - } - }); - - ((DataViewHolder) holder).authorTextView.setOnClickListener(view -> { - Intent intent = new Intent(mContext, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor()); - mContext.startActivity(intent); - }); - - ((DataViewHolder) holder).contentCustomMarkwonView.setOnClickListener(view -> { - if (((DataViewHolder) holder).contentCustomMarkwonView.getSelectionStart() == -1 && ((DataViewHolder) holder).contentCustomMarkwonView.getSelectionEnd() == -1) { - ((DataViewHolder) holder).itemView.performClick(); - } - }); - } - } - } - - @Override - public int getItemViewType(int position) { - // Reached at the end - if (hasExtraRow() && position == getItemCount() - 1) { - if (networkState.getStatus() == NetworkState.Status.LOADING) { - return VIEW_TYPE_LOADING; - } else { - return VIEW_TYPE_ERROR; - } - } else { - return VIEW_TYPE_DATA; - } - } - - @Override - public int getItemCount() { - if (hasExtraRow()) { - return super.getItemCount() + 1; - } - return super.getItemCount(); - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - super.onViewRecycled(holder); - if (holder instanceof DataViewHolder) { - ((DataViewHolder) holder).itemView.setBackgroundColor(mMessageBackgroundColor); - ((DataViewHolder) holder).titleTextView.setVisibility(View.VISIBLE); - } - } - - private boolean hasExtraRow() { - return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; - } - - public void setNetworkState(NetworkState newNetworkState) { - NetworkState previousState = this.networkState; - boolean previousExtraRow = hasExtraRow(); - this.networkState = newNetworkState; - boolean newExtraRow = hasExtraRow(); - if (previousExtraRow != newExtraRow) { - if (previousExtraRow) { - notifyItemRemoved(super.getItemCount()); - } else { - notifyItemInserted(super.getItemCount()); - } - } else if (newExtraRow && !previousState.equals(newNetworkState)) { - notifyItemChanged(getItemCount() - 1); - } - } - - public void updateMessageReply(Message newReply, int position) { - if (position >= 0 && position < super.getItemCount()) { - Message message = getItem(position); - if (message != null) { - message.addReply(newReply); - notifyItemChanged(position); - } - } - } - - public interface RetryLoadingMoreCallback { - void retryLoadingMore(); - } - - class DataViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.author_text_view_item_message) - TextView authorTextView; - @BindView(R.id.subject_text_view_item_message) - TextView subjectTextView; - @BindView(R.id.title_text_view_item_message) - TextView titleTextView; - @BindView(R.id.content_custom_markwon_view_item_message) - TextView contentCustomMarkwonView; - - DataViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - itemView.setBackgroundColor(mMessageBackgroundColor); - authorTextView.setTextColor(mUsernameColor); - subjectTextView.setTextColor(mPrimaryTextColor); - titleTextView.setTextColor(mPrimaryTextColor); - contentCustomMarkwonView.setTextColor(mSecondaryTextColor); - - contentCustomMarkwonView.setMovementMethod(LinkMovementMethod.getInstance()); - } - } - - class ErrorViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_footer_error) - TextView errorTextView; - @BindView(R.id.retry_button_item_footer_error) - Button retryButton; - - ErrorViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - errorTextView.setText(R.string.load_comments_failed); - errorTextView.setTextColor(mSecondaryTextColor); - retryButton.setOnClickListener(view -> mRetryLoadingMoreCallback.retryLoadingMore()); - retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); - retryButton.setTextColor(mButtonTextColor); - } - } - - class LoadingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_item_footer_loading) - ProgressBar progressBar; - - LoadingViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MultiRedditListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MultiRedditListingRecyclerViewAdapter.java deleted file mode 100644 index 51939d7f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/MultiRedditListingRecyclerViewAdapter.java +++ /dev/null @@ -1,398 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import me.zhanghai.android.fastscroll.PopupTextProvider; -import ml.docilealligator.infinityforreddit.Activity.ViewMultiRedditDetailActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.MultiRedditOptionsBottomSheetFragment; -import ml.docilealligator.infinityforreddit.MultiReddit.FavoriteMultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiReddit; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class MultiRedditListingRecyclerViewAdapter extends RecyclerView.Adapter implements PopupTextProvider { - - private static final int VIEW_TYPE_FAVORITE_MULTI_REDDIT_DIVIDER = 0; - private static final int VIEW_TYPE_FAVORITE_MULTI_REDDIT = 1; - private static final int VIEW_TYPE_MULTI_REDDIT_DIVIDER = 2; - private static final int VIEW_TYPE_MULTI_REDDIT = 3; - - private AppCompatActivity mActivity; - private Retrofit mOauthRetrofit; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private RequestManager mGlide; - - private String mAccessToken; - private String mAccountName; - private List mMultiReddits; - private List mFavoriteMultiReddits; - private int mPrimaryTextColor; - private int mSecondaryTextColor; - - public MultiRedditListingRecyclerViewAdapter(AppCompatActivity activity, Retrofit oauthRetrofit, - RedditDataRoomDatabase redditDataRoomDatabase, - CustomThemeWrapper customThemeWrapper, - String accessToken, String accountName) { - mActivity = activity; - mGlide = Glide.with(activity); - mOauthRetrofit = oauthRetrofit; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mAccessToken = accessToken; - mAccountName = accountName; - mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - } - - @Override - public int getItemViewType(int position) { - if (mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) { - if (position == 0) { - return VIEW_TYPE_FAVORITE_MULTI_REDDIT_DIVIDER; - } else if (position == mFavoriteMultiReddits.size() + 1) { - return VIEW_TYPE_MULTI_REDDIT_DIVIDER; - } else if (position <= mFavoriteMultiReddits.size()) { - return VIEW_TYPE_FAVORITE_MULTI_REDDIT; - } else { - return VIEW_TYPE_MULTI_REDDIT; - } - } else { - return VIEW_TYPE_MULTI_REDDIT; - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - switch (viewType) { - case VIEW_TYPE_FAVORITE_MULTI_REDDIT_DIVIDER: - return new FavoriteMultiRedditsDividerViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_favorite_thing_divider, parent, false)); - case VIEW_TYPE_FAVORITE_MULTI_REDDIT: - return new FavoriteMultiRedditViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_multi_reddit, parent, false)); - case VIEW_TYPE_MULTI_REDDIT_DIVIDER: - return new AllMultiRedditsDividerViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_favorite_thing_divider, parent, false)); - default: - return new MultiRedditViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_multi_reddit, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof MultiRedditViewHolder) { - String name; - String iconUrl; - - int offset = (mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) ? - mFavoriteMultiReddits.size() + 2 : 0; - - MultiReddit multiReddit = mMultiReddits.get(holder.getAdapterPosition() - offset); - name = multiReddit.getDisplayName(); - iconUrl = multiReddit.getIconUrl(); - if(multiReddit.isFavorite()) { - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } else { - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - ((MultiRedditViewHolder) holder).favoriteImageView.setOnClickListener(view -> { - if(multiReddit.isFavorite()) { - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - multiReddit.setFavorite(false); - FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, - mAccessToken, false, multiReddit, - new FavoriteMultiReddit.FavoriteMultiRedditListener() { - @Override - public void success() { - int position = holder.getAdapterPosition() - offset; - if(position >= 0 && mMultiReddits.size() > position) { - mMultiReddits.get(position).setFavorite(false); - } - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - @Override - public void failed() { - Toast.makeText(mActivity, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); - int position = holder.getAdapterPosition() - offset; - if(position >= 0 && mMultiReddits.size() > position) { - mMultiReddits.get(position).setFavorite(true); - } - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - } - ); - } else { - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - multiReddit.setFavorite(true); - FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, - mAccessToken, true, multiReddit, - new FavoriteMultiReddit.FavoriteMultiRedditListener() { - @Override - public void success() { - int position = holder.getAdapterPosition() - offset; - if(position >= 0 && mMultiReddits.size() > position) { - mMultiReddits.get(position).setFavorite(true); - } - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - - @Override - public void failed() { - Toast.makeText(mActivity, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); - int position = holder.getAdapterPosition() - offset; - if(position >= 0 && mMultiReddits.size() > position) { - mMultiReddits.get(position).setFavorite(false); - } - ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - } - ); - } - }); - holder.itemView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, ViewMultiRedditDetailActivity.class); - intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_DATA, multiReddit); - mActivity.startActivity(intent); - }); - - holder.itemView.setOnLongClickListener(view -> { - showOptionsBottomSheetFragment(multiReddit); - return true; - }); - - if (iconUrl != null && !iconUrl.equals("")) { - 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(((MultiRedditViewHolder) holder).iconImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((MultiRedditViewHolder) holder).iconImageView); - } - ((MultiRedditViewHolder) holder).multiRedditNameTextView.setText(name); - } else if (holder instanceof FavoriteMultiRedditViewHolder) { - MultiReddit multiReddit = mFavoriteMultiReddits.get(holder.getAdapterPosition() - 1); - String name = multiReddit.getDisplayName(); - String iconUrl = multiReddit.getIconUrl(); - if(multiReddit.isFavorite()) { - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } else { - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setOnClickListener(view -> { - if(multiReddit.isFavorite()) { - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - multiReddit.setFavorite(false); - FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, - mAccessToken, false, multiReddit, - new FavoriteMultiReddit.FavoriteMultiRedditListener() { - @Override - public void success() { - int position = holder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteMultiReddits.size() > position) { - mFavoriteMultiReddits.get(position).setFavorite(false); - } - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - @Override - public void failed() { - Toast.makeText(mActivity, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); - int position = holder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteMultiReddits.size() > position) { - mFavoriteMultiReddits.get(position).setFavorite(true); - } - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - } - ); - } else { - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - multiReddit.setFavorite(true); - FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, - mAccessToken, true, multiReddit, - new FavoriteMultiReddit.FavoriteMultiRedditListener() { - @Override - public void success() { - int position = holder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteMultiReddits.size() > position) { - mFavoriteMultiReddits.get(position).setFavorite(true); - } - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - - @Override - public void failed() { - Toast.makeText(mActivity, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); - int position = holder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteMultiReddits.size() > position) { - mFavoriteMultiReddits.get(position).setFavorite(false); - } - ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - } - ); - } - }); - holder.itemView.setOnClickListener(view -> { - Intent intent = new Intent(mActivity, ViewMultiRedditDetailActivity.class); - intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_DATA, multiReddit); - mActivity.startActivity(intent); - }); - - holder.itemView.setOnLongClickListener(view -> { - showOptionsBottomSheetFragment(multiReddit); - return true; - }); - - if (iconUrl != null && !iconUrl.equals("")) { - 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(((FavoriteMultiRedditViewHolder) holder).iconImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((FavoriteMultiRedditViewHolder) holder).iconImageView); - } - ((FavoriteMultiRedditViewHolder) holder).multiRedditNameTextView.setText(name); - } - } - - @Override - public int getItemCount() { - if (mMultiReddits != null) { - if(mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) { - return mMultiReddits.size() > 0 ? - mFavoriteMultiReddits.size() + mMultiReddits.size() + 2 : 0; - } - - return mMultiReddits.size(); - } - return 0; - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if(holder instanceof MultiRedditViewHolder) { - mGlide.clear(((MultiRedditViewHolder) holder).iconImageView); - } else if (holder instanceof FavoriteMultiRedditViewHolder) { - mGlide.clear(((FavoriteMultiRedditViewHolder) holder).iconImageView); - } - } - - private void showOptionsBottomSheetFragment(MultiReddit multiReddit) { - MultiRedditOptionsBottomSheetFragment fragment = new MultiRedditOptionsBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putParcelable(MultiRedditOptionsBottomSheetFragment.EXTRA_MULTI_REDDIT, multiReddit); - fragment.setArguments(bundle); - fragment.show(mActivity.getSupportFragmentManager(), fragment.getTag()); - } - - public void setMultiReddits(List multiReddits) { - mMultiReddits = multiReddits; - notifyDataSetChanged(); - } - - public void setFavoriteMultiReddits(List favoriteMultiReddits) { - mFavoriteMultiReddits = favoriteMultiReddits; - notifyDataSetChanged(); - } - - @NonNull - @Override - public String getPopupText(int position) { - switch (getItemViewType(position)) { - case VIEW_TYPE_MULTI_REDDIT: - int offset = (mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) ? - mFavoriteMultiReddits.size() + 2 : 0; - return mMultiReddits.get(position - offset).getDisplayName().substring(0, 1).toUpperCase(); - case VIEW_TYPE_FAVORITE_MULTI_REDDIT: - return mFavoriteMultiReddits.get(position - 1).getDisplayName().substring(0, 1).toUpperCase(); - default: - return ""; - } - } - - class MultiRedditViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.multi_reddit_icon_gif_image_view_item_multi_reddit) - GifImageView iconImageView; - @BindView(R.id.multi_reddit_name_text_view_item_multi_reddit) - TextView multiRedditNameTextView; - @BindView(R.id.favorite_image_view_item_multi_reddit) - ImageView favoriteImageView; - - MultiRedditViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - multiRedditNameTextView.setTextColor(mPrimaryTextColor); - } - } - - class FavoriteMultiRedditViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.multi_reddit_icon_gif_image_view_item_multi_reddit) - GifImageView iconImageView; - @BindView(R.id.multi_reddit_name_text_view_item_multi_reddit) - TextView multiRedditNameTextView; - @BindView(R.id.favorite_image_view_item_multi_reddit) - ImageView favoriteImageView; - - FavoriteMultiRedditViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - multiRedditNameTextView.setTextColor(mPrimaryTextColor); - } - } - - class FavoriteMultiRedditsDividerViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; - - FavoriteMultiRedditsDividerViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - dividerTextView.setText(R.string.favorites); - dividerTextView.setTextColor(mSecondaryTextColor); - } - } - - class AllMultiRedditsDividerViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; - - AllMultiRedditsDividerViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - dividerTextView.setText(R.string.all); - dividerTextView.setTextColor(mSecondaryTextColor); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java deleted file mode 100644 index cdb73759..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/NavigationDrawerRecyclerViewAdapter.java +++ /dev/null @@ -1,657 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.content.res.Resources; -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.appcompat.app.AppCompatActivity; -import androidx.biometric.BiometricManager; -import androidx.biometric.BiometricPrompt; -import androidx.core.content.ContextCompat; -import androidx.core.content.res.ResourcesCompat; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.Account.Account; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import pl.droidsonroids.gif.GifImageView; - -import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; -import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; - -public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter { - - public interface ItemClickListener { - void onMenuClick(int stringId); - void onSubscribedSubredditClick(String subredditName); - void onAccountClick(String accountName); - } - - private static final int VIEW_TYPE_NAV_HEADER = 0; - private static final int VIEW_TYPE_MENU_GROUP_TITLE = 1; - private static final int VIEW_TYPE_MENU_ITEM = 2; - private static final int VIEW_TYPE_DIVIDER = 3; - private static final int VIEW_TYPE_FAVORITE_SUBSCRIBED_SUBREDDIT = 4; - private static final int VIEW_TYPE_SUBSCRIBED_SUBREDDIT = 5; - private static final int VIEW_TYPE_ACCOUNT = 6; - private static final int CURRENT_MENU_ITEMS = 17; - - private AppCompatActivity appCompatActivity; - private Resources resources; - private RequestManager glide; - private String accountName; - private String userIconUrl; - private String userBannerUrl; - private int karma; - private boolean isNSFWEnabled; - private boolean requireAuthToAccountSection; - private ItemClickListener itemClickListener; - private boolean isLoggedIn; - private boolean isInMainPage = true; - private ArrayList favoriteSubscribedSubreddits; - private ArrayList subscribedSubreddits; - private ArrayList accounts; - private int primaryTextColor; - private int secondaryTextColor; - private int dividerColor; - private int primaryIconColor; - - public NavigationDrawerRecyclerViewAdapter(AppCompatActivity appCompatActivity, SharedPreferences sharedPreferences, - SharedPreferences nsfwAndSpoilerSharedPreferences, - CustomThemeWrapper customThemeWrapper, - String accountName, String userIconUrl, - String userBannerUrl, int karma, - ItemClickListener itemClickListener) { - this.appCompatActivity = appCompatActivity; - resources = appCompatActivity.getResources(); - glide = Glide.with(appCompatActivity); - this.accountName = accountName; - this.userIconUrl = userIconUrl; - this.userBannerUrl = userBannerUrl; - this.karma = karma; - isNSFWEnabled = nsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); - requireAuthToAccountSection = sharedPreferences.getBoolean(SharedPreferencesUtils.REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER, false); - isLoggedIn = accountName != null; - this.itemClickListener = itemClickListener; - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - dividerColor = customThemeWrapper.getDividerColor(); - primaryIconColor = customThemeWrapper.getPrimaryIconColor(); - favoriteSubscribedSubreddits = new ArrayList<>(); - subscribedSubreddits = new ArrayList<>(); - } - - @Override - public int getItemViewType(int position) { - if (isInMainPage) { - if (isLoggedIn) { - if (position == CURRENT_MENU_ITEMS) { - return VIEW_TYPE_MENU_GROUP_TITLE; - } else if (!favoriteSubscribedSubreddits.isEmpty() && position == CURRENT_MENU_ITEMS + favoriteSubscribedSubreddits.size() + 1) { - return VIEW_TYPE_MENU_GROUP_TITLE; - } else if (position > CURRENT_MENU_ITEMS) { - if (!favoriteSubscribedSubreddits.isEmpty() && position <= CURRENT_MENU_ITEMS + favoriteSubscribedSubreddits.size()) { - return VIEW_TYPE_FAVORITE_SUBSCRIBED_SUBREDDIT; - } else { - return VIEW_TYPE_SUBSCRIBED_SUBREDDIT; - } - } else if (position == 0) { - return VIEW_TYPE_NAV_HEADER; - } else if (position == 1 || position == 6 || position == 12) { - return VIEW_TYPE_MENU_GROUP_TITLE; - } else if (position == 16) { - return VIEW_TYPE_DIVIDER; - } else { - return VIEW_TYPE_MENU_ITEM; - } - } else { - if (position == 0) { - return VIEW_TYPE_NAV_HEADER; - } else { - return VIEW_TYPE_MENU_ITEM; - } - } - } else { - if (position == 0) { - return VIEW_TYPE_NAV_HEADER; - } - if (accounts != null) { - if (position > accounts.size()) { - return VIEW_TYPE_MENU_ITEM; - } else { - return VIEW_TYPE_ACCOUNT; - } - } else { - return VIEW_TYPE_MENU_ITEM; - } - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - switch (viewType) { - case VIEW_TYPE_NAV_HEADER: - return new NavHeaderViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.nav_header_main, parent, false)); - case VIEW_TYPE_MENU_GROUP_TITLE: - return new MenuGroupTitleViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_nav_drawer_menu_group_title, parent, false)); - case VIEW_TYPE_MENU_ITEM: - return new MenuItemViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_nav_drawer_menu_item, parent, false)); - case VIEW_TYPE_DIVIDER: - return new DividerViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_nav_drawer_divider, parent, false)); - case VIEW_TYPE_ACCOUNT: - return new AccountViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_nav_drawer_account, parent, false)); - case VIEW_TYPE_FAVORITE_SUBSCRIBED_SUBREDDIT: - return new FavoriteSubscribedThingViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_nav_drawer_subscribed_thing, parent, false)); - default: - return new SubscribedThingViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_nav_drawer_subscribed_thing, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof NavHeaderViewHolder) { - if (isLoggedIn) { - ((NavHeaderViewHolder) holder).karmaTextView.setText(appCompatActivity.getString(R.string.karma_info, karma)); - ((NavHeaderViewHolder) holder).accountNameTextView.setText(accountName); - if (userIconUrl != null && !userIconUrl.equals("")) { - glide.load(userIconUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0)))) - .into(((NavHeaderViewHolder) holder).profileImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0))) - .into(((NavHeaderViewHolder) holder).profileImageView); - } - - if (userBannerUrl != null && !userBannerUrl.equals("")) { - glide.load(userBannerUrl).into(((NavHeaderViewHolder) holder).bannerImageView); - } - } else { - ((NavHeaderViewHolder) holder).karmaTextView.setText(R.string.press_here_to_login); - ((NavHeaderViewHolder) holder).accountNameTextView.setText(R.string.anonymous_account); - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0))) - .into(((NavHeaderViewHolder) holder).profileImageView); - } - - if (isInMainPage) { - ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_down_24px)); - } else { - ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_up_24px)); - } - - ((NavHeaderViewHolder) holder).itemView.setOnClickListener(view -> { - if (isInMainPage) { - if (requireAuthToAccountSection) { - BiometricManager biometricManager = BiometricManager.from(appCompatActivity); - if (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) { - Executor executor = ContextCompat.getMainExecutor(appCompatActivity); - BiometricPrompt biometricPrompt = new BiometricPrompt(appCompatActivity, - executor, new BiometricPrompt.AuthenticationCallback() { - @Override - public void onAuthenticationSucceeded( - @NonNull BiometricPrompt.AuthenticationResult result) { - super.onAuthenticationSucceeded(result); - openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); - } - }); - - BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() - .setTitle(appCompatActivity.getString(R.string.unlock_account_section)) - .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) - .build(); - - biometricPrompt.authenticate(promptInfo); - } else { - openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); - } - } else { - openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); - } - } else { - ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_arrow_drop_down_24px, null)); - closeAccountSectionWithoutChangeIconResource(false); - } - }); - } else if (holder instanceof MenuGroupTitleViewHolder) { - if (position == 1) { - ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_account); - } else if (position == 6) { - ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_post); - } else if (position == 12) { - ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_preferences); - } else { - if (!favoriteSubscribedSubreddits.isEmpty() && position == CURRENT_MENU_ITEMS) { - ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.favorites); - } else { - ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.subscriptions); - } - } - } else if (holder instanceof MenuItemViewHolder) { - int stringId = 0; - int drawableId = 0; - boolean setOnClickListener = true; - - if (isInMainPage) { - if (isLoggedIn) { - switch (position) { - case 2: - stringId = R.string.profile; - drawableId = R.drawable.ic_account_circle_24dp; - break; - case 3: - stringId = R.string.subscriptions; - drawableId = R.drawable.ic_subscritptions_bottom_app_bar_24dp; - break; - case 4: - stringId = R.string.multi_reddit; - drawableId = R.drawable.ic_multi_reddit_24dp; - break; - case 5: - stringId = R.string.inbox; - drawableId = R.drawable.ic_inbox_24dp; - break; - case 7: - stringId = R.string.upvoted; - drawableId = R.drawable.ic_arrow_upward_black_24dp; - break; - case 8: - stringId = R.string.downvoted; - drawableId = R.drawable.ic_arrow_downward_black_24dp; - break; - case 9: - stringId = R.string.hidden; - drawableId = R.drawable.ic_outline_lock_24dp; - break; - case 10: - stringId = R.string.saved; - drawableId = R.drawable.ic_outline_bookmarks_24dp; - break; - case 11: - stringId = R.string.gilded; - drawableId = R.drawable.ic_star_border_24dp; - break; - case 13: - if ((resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - stringId = R.string.dark_theme; - drawableId = R.drawable.ic_dark_theme_24dp; - } else { - stringId = R.string.light_theme; - drawableId = R.drawable.ic_light_theme_24dp; - } - break; - case 14: - setOnClickListener = false; - if (isNSFWEnabled) { - stringId = R.string.disable_nsfw; - drawableId = R.drawable.ic_nsfw_off_24dp; - } else { - stringId = R.string.enable_nsfw; - drawableId = R.drawable.ic_nsfw_on_24dp; - } - - ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> { - if (isNSFWEnabled) { - isNSFWEnabled = false; - ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); - itemClickListener.onMenuClick(R.string.disable_nsfw); - } else { - isNSFWEnabled = true; - ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); - itemClickListener.onMenuClick(R.string.enable_nsfw); - } - }); - break; - case 15: - stringId = R.string.settings; - drawableId = R.drawable.ic_settings_24dp; - } - } else { - switch (position) { - case 1: - if ((resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - stringId = R.string.dark_theme; - drawableId = R.drawable.ic_dark_theme_24dp; - } else { - stringId = R.string.light_theme; - drawableId = R.drawable.ic_light_theme_24dp; - } - break; - case 2: - setOnClickListener = false; - if (isNSFWEnabled) { - stringId = R.string.disable_nsfw; - drawableId = R.drawable.ic_nsfw_off_24dp; - } else { - stringId = R.string.enable_nsfw; - drawableId = R.drawable.ic_nsfw_on_24dp; - } - - ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> { - if (isNSFWEnabled) { - isNSFWEnabled = false; - ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); - itemClickListener.onMenuClick(R.string.disable_nsfw); - } else { - isNSFWEnabled = true; - ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); - itemClickListener.onMenuClick(R.string.enable_nsfw); - } - }); - break; - case 3: - stringId = R.string.settings; - drawableId = R.drawable.ic_settings_24dp; - } - } - } else { - if (isLoggedIn) { - int offset = accounts == null ? 0 : accounts.size(); - if (position == offset + 1) { - stringId = R.string.add_account; - drawableId = R.drawable.ic_outline_add_circle_outline_24dp; - } else if (position == offset + 2) { - stringId = R.string.anonymous_account; - drawableId = R.drawable.ic_anonymous_24dp; - } else if (position == offset + 3) { - stringId = R.string.log_out; - drawableId = R.drawable.ic_log_out_24dp; - } - } else { - stringId = R.string.add_account; - drawableId = R.drawable.ic_outline_add_circle_outline_24dp; - } - } - - if (stringId != 0) { - ((MenuItemViewHolder) holder).menuTextView.setText(stringId); - ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(drawableId)); - if (setOnClickListener) { - int finalStringId = stringId; - ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> itemClickListener.onMenuClick(finalStringId)); - } - } - } else if (holder instanceof FavoriteSubscribedThingViewHolder) { - SubscribedSubredditData subreddit = favoriteSubscribedSubreddits.get(position - CURRENT_MENU_ITEMS - 1); - String subredditName = subreddit.getName(); - String iconUrl = subreddit.getIconUrl(); - ((FavoriteSubscribedThingViewHolder) holder).subredditNameTextView.setText(subredditName); - if (iconUrl != null && !iconUrl.equals("")) { - glide.load(iconUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((FavoriteSubscribedThingViewHolder) holder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((FavoriteSubscribedThingViewHolder) holder).iconGifImageView); - } - - ((FavoriteSubscribedThingViewHolder) holder).itemView.setOnClickListener(view -> { - itemClickListener.onSubscribedSubredditClick(subredditName); - }); - } else if (holder instanceof SubscribedThingViewHolder) { - SubscribedSubredditData subreddit = favoriteSubscribedSubreddits.isEmpty() ? subscribedSubreddits.get(position - CURRENT_MENU_ITEMS - 1) - : subscribedSubreddits.get(position - CURRENT_MENU_ITEMS - favoriteSubscribedSubreddits.size() - 2); - String subredditName = subreddit.getName(); - String iconUrl = subreddit.getIconUrl(); - ((SubscribedThingViewHolder) holder).subredditNameTextView.setText(subredditName); - if (iconUrl != null && !iconUrl.equals("")) { - glide.load(iconUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((SubscribedThingViewHolder) holder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((SubscribedThingViewHolder) holder).iconGifImageView); - } - - ((SubscribedThingViewHolder) holder).itemView.setOnClickListener(view -> { - itemClickListener.onSubscribedSubredditClick(subredditName); - }); - } else if (holder instanceof AccountViewHolder) { - glide.load(accounts.get(position - 1).getProfileImageUrl()) - .error(glide.load(R.drawable.subreddit_default_icon)) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(128, 0))) - .into(((AccountViewHolder) holder).profileImageGifImageView); - ((AccountViewHolder) holder).usernameTextView.setText(accounts.get(position - 1).getUsername()); - ((AccountViewHolder) holder).itemView.setOnClickListener(view -> - itemClickListener.onAccountClick(accounts.get(position - 1).getUsername())); - } - } - - public boolean closeAccountSectionWithoutChangeIconResource(boolean checkIsInMainPage) { - if (!(checkIsInMainPage && isInMainPage)) { - notifyItemRangeRemoved(1, getItemCount() - 1); - if (isLoggedIn) { - notifyItemRangeInserted(1, (favoriteSubscribedSubreddits.isEmpty() ? 0 : favoriteSubscribedSubreddits.size() + 1) - + (subscribedSubreddits.isEmpty() ? 0 : subscribedSubreddits.size() + 1) + CURRENT_MENU_ITEMS - 1); - } else { - notifyItemRangeInserted(1, 2); - } - isInMainPage = true; - - return true; - } - - return false; - } - - private void openAccountSection(ImageView dropIconImageView) { - dropIconImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_arrow_drop_up_24px, null)); - notifyItemRangeRemoved(1, getItemCount() - 1); - if (accounts != null) { - notifyItemRangeInserted(1, accounts.size() + 3); - } else { - if (isLoggedIn) { - notifyItemRangeInserted(1, 3); - } else { - notifyItemInserted(1); - } - } - isInMainPage = false; - } - - @Override - public int getItemCount() { - if (isInMainPage) { - if (isLoggedIn) { - if (!(favoriteSubscribedSubreddits.isEmpty() && subscribedSubreddits.isEmpty())) { - return CURRENT_MENU_ITEMS + (favoriteSubscribedSubreddits.isEmpty() ? 0 : favoriteSubscribedSubreddits.size() + 1) - + (subscribedSubreddits.isEmpty() ? 0 : subscribedSubreddits.size() + 1); - } - return CURRENT_MENU_ITEMS - 1; - } else { - return 4; - } - } else { - if (isLoggedIn) { - if (accounts != null && !accounts.isEmpty()) { - return 4 + accounts.size(); - } else { - return 4; - } - } else { - if (accounts != null && !accounts.isEmpty()) { - return 2 + accounts.size(); - } else { - return 2; - } - } - } - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - super.onViewRecycled(holder); - if (holder instanceof SubscribedThingViewHolder) { - glide.clear(((SubscribedThingViewHolder) holder).iconGifImageView); - } - } - - public void setFavoriteSubscribedSubreddits(List favoriteSubscribedSubreddits) { - this.favoriteSubscribedSubreddits = (ArrayList) favoriteSubscribedSubreddits; - if (isInMainPage) { - notifyDataSetChanged(); - } - } - - public void setSubscribedSubreddits(List subscribedSubreddits) { - this.subscribedSubreddits = (ArrayList) subscribedSubreddits; - if (isInMainPage) { - notifyDataSetChanged(); - } - } - - public void changeAccountsDataset(List accounts) { - this.accounts = (ArrayList) accounts; - if (!isInMainPage) { - notifyDataSetChanged(); - } - } - - public void updateKarma(int karma) { - this.karma = karma; - notifyItemChanged(0); - } - - public void setNSFWEnabled(boolean isNSFWEnabled) { - this.isNSFWEnabled = isNSFWEnabled; - if (isInMainPage) { - if (isLoggedIn) { - notifyItemChanged(CURRENT_MENU_ITEMS - 3); - } else { - notifyItemChanged(2); - } - } - } - - public void setRequireAuthToAccountSection(boolean requireAuthToAccountSection) { - this.requireAuthToAccountSection = requireAuthToAccountSection; - } - - class NavHeaderViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.name_text_view_nav_header_main) - TextView accountNameTextView; - @BindView(R.id.karma_text_view_nav_header_main) - TextView karmaTextView; - @BindView(R.id.profile_image_view_nav_header_main) - GifImageView profileImageView; - @BindView(R.id.banner_image_view_nav_header_main) - ImageView bannerImageView; - @BindView(R.id.account_switcher_image_view_nav_header_main) - ImageView dropIconImageView; - - NavHeaderViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - } - } - - class MenuGroupTitleViewHolder extends RecyclerView.ViewHolder { - TextView titleTextView; - - MenuGroupTitleViewHolder(@NonNull View itemView) { - super(itemView); - titleTextView = (TextView) itemView; - titleTextView.setTextColor(secondaryTextColor); - } - } - - class MenuItemViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.image_view_item_nav_drawer_menu_item) - ImageView imageView; - @BindView(R.id.text_view_item_nav_drawer_menu_item) - TextView menuTextView; - - MenuItemViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - menuTextView.setTextColor(primaryTextColor); - imageView.setColorFilter(primaryIconColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - } - - class DividerViewHolder extends RecyclerView.ViewHolder { - - DividerViewHolder(@NonNull View itemView) { - super(itemView); - itemView.setBackgroundColor(dividerColor); - } - } - - class FavoriteSubscribedThingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.thing_icon_gif_image_view_item_nav_drawer_subscribed_thing) - GifImageView iconGifImageView; - @BindView(R.id.thing_name_text_view_item_nav_drawer_subscribed_thing) - TextView subredditNameTextView; - - FavoriteSubscribedThingViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - subredditNameTextView.setTextColor(primaryTextColor); - } - } - - class SubscribedThingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.thing_icon_gif_image_view_item_nav_drawer_subscribed_thing) - GifImageView iconGifImageView; - @BindView(R.id.thing_name_text_view_item_nav_drawer_subscribed_thing) - TextView subredditNameTextView; - - SubscribedThingViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - subredditNameTextView.setTextColor(primaryTextColor); - } - } - - class AccountViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.profile_image_item_account) - GifImageView profileImageGifImageView; - @BindView(R.id.username_text_view_item_account) - TextView usernameTextView; - - AccountViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - usernameTextView.setTextColor(primaryTextColor); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java deleted file mode 100644 index 1928febf..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PostRecyclerViewAdapter.java +++ /dev/null @@ -1,3008 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.ColorStateList; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.ColorFilter; -import android.graphics.PorterDuff; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.constraintlayout.widget.Barrier; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.constraintlayout.widget.ConstraintSet; -import androidx.core.graphics.drawable.DrawableCompat; -import androidx.paging.PagedListAdapter; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestBuilder; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.RequestOptions; -import com.bumptech.glide.request.target.Target; -import com.google.android.exoplayer2.metadata.Metadata; -import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.text.Cue; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; -import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; -import com.google.android.exoplayer2.ui.PlayerView; -import com.google.android.material.card.MaterialCardView; -import com.libRG.CustomTextView; - -import org.greenrobot.eventbus.EventBus; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import butterknife.BindView; -import butterknife.ButterKnife; -import im.ene.toro.CacheManager; -import im.ene.toro.ToroPlayer; -import im.ene.toro.ToroUtil; -import im.ene.toro.exoplayer.ExoCreator; -import im.ene.toro.exoplayer.ExoPlayerViewHelper; -import im.ene.toro.exoplayer.Playable; -import im.ene.toro.media.PlaybackInfo; -import im.ene.toro.widget.Container; -import jp.wasabeef.glide.transformations.BlurTransformation; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.Activity.FilteredThingActivity; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewImageOrGifActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPostDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewRedditGalleryActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewVideoActivity; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadSubredditIconAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.LoadUserDataAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.ShareLinkBottomSheetFragment; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.CustomView.AspectRatioGifImageView; -import ml.docilealligator.infinityforreddit.Event.PostUpdateEventToDetailActivity; -import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SaveThing; -import ml.docilealligator.infinityforreddit.User.UserDao; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import ml.docilealligator.infinityforreddit.VoteThing; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -/** - * Created by alex on 2/25/18. - */ - -public class PostRecyclerViewAdapter extends PagedListAdapter implements CacheManager { - private static final int VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE = 1; - private static final int VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE = 2; - private static final int VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE = 3; - private static final int VIEW_TYPE_POST_CARD_LINK_TYPE = 4; - private static final int VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE = 5; - private static final int VIEW_TYPE_POST_CARD_TEXT_TYPE = 6; - private static final int VIEW_TYPE_POST_CARD_GALLERY_TYPE = 7; - private static final int VIEW_TYPE_POST_COMPACT = 8; - private static final int VIEW_TYPE_ERROR = 9; - private static final int VIEW_TYPE_LOADING = 10; - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull Post post, @NonNull Post t1) { - return post.getId().equals(t1.getId()); - } - - @Override - public boolean areContentsTheSame(@NonNull Post post, @NonNull Post t1) { - return false; - } - }; - private AppCompatActivity mActivity; - private Retrofit mOauthRetrofit; - private Retrofit mRetrofit; - private Retrofit mGfycatRetrofit; - private Retrofit mRedgifsRetrofit; - private int mImageViewWidth; - private String mAccessToken; - private RequestManager mGlide; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private Locale mLocale; - private UserDao mUserDao; - private boolean canStartActivity = true; - private int mPostType; - private int mPostLayout; - private int mColorPrimaryLightTheme; - private int mColorAccent; - private int mCardViewBackgroundColor; - private int mPrimaryTextColor; - private int mSecondaryTextColor; - private int mPostTitleColor; - private int mPostContentColor; - private int mStickiedPostIconTint; - private int mPostTypeBackgroundColor; - private int mPostTypeTextColor; - private int mSubredditColor; - private int mUsernameColor; - private int mSpoilerBackgroundColor; - private int mSpoilerTextColor; - private int mFlairBackgroundColor; - private int mFlairTextColor; - private int mAwardsBackgroundColor; - private int mAwardsTextColor; - private int mNSFWBackgroundColor; - private int mNSFWTextColor; - private int mArchivedIconTint; - private int mLockedIconTint; - private int mCrosspostIconTint; - private int mNoPreviewPostTypeBackgroundColor; - private int mNoPreviewPostTypeIconTint; - private int mUpvotedColor; - private int mDownvotedColor; - private int mVoteAndReplyUnavailableVoteButtonColor; - private int mButtonTextColor; - 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 = false; - private Drawable mCommentIcon; - private NetworkState networkState; - private ExoCreator mExoCreator; - private Callback mCallback; - private ShareLinkBottomSheetFragment mShareLinkBottomSheetFragment; - - public PostRecyclerViewAdapter(AppCompatActivity activity, Retrofit oauthRetrofit, Retrofit retrofit, - Retrofit gfycatRetrofit, Retrofit redgifsRetrofit, - RedditDataRoomDatabase redditDataRoomDatabase, - CustomThemeWrapper customThemeWrapper, Locale locale, int imageViewWidth, - 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; - mOauthRetrofit = oauthRetrofit; - mRetrofit = retrofit; - mGfycatRetrofit = gfycatRetrofit; - mRedgifsRetrofit = redgifsRetrofit; - mImageViewWidth = imageViewWidth; - 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); - - mPostLayout = postLayout; - - mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); - mColorAccent = customThemeWrapper.getColorAccent(); - mCardViewBackgroundColor = customThemeWrapper.getCardViewBackgroundColor(); - mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - mPostTitleColor = customThemeWrapper.getPostTitleColor(); - mPostContentColor = customThemeWrapper.getPostContentColor(); - mStickiedPostIconTint = customThemeWrapper.getStickiedPostIconTint(); - mPostTypeBackgroundColor = customThemeWrapper.getPostTypeBackgroundColor(); - mPostTypeTextColor = customThemeWrapper.getPostTypeTextColor(); - mSubredditColor = customThemeWrapper.getSubreddit(); - mUsernameColor = customThemeWrapper.getUsername(); - mSpoilerBackgroundColor = customThemeWrapper.getSpoilerBackgroundColor(); - mSpoilerTextColor = customThemeWrapper.getSpoilerTextColor(); - mFlairBackgroundColor = customThemeWrapper.getFlairBackgroundColor(); - mFlairTextColor = customThemeWrapper.getFlairTextColor(); - mAwardsBackgroundColor = customThemeWrapper.getAwardsBackgroundColor(); - mAwardsTextColor = customThemeWrapper.getAwardsTextColor(); - mNSFWBackgroundColor = customThemeWrapper.getNsfwBackgroundColor(); - mNSFWTextColor = customThemeWrapper.getNsfwTextColor(); - mArchivedIconTint = customThemeWrapper.getArchivedIconTint(); - mLockedIconTint = customThemeWrapper.getLockedIconTint(); - mCrosspostIconTint = customThemeWrapper.getCrosspostIconTint(); - mNoPreviewPostTypeBackgroundColor = customThemeWrapper.getNoPreviewPostTypeBackgroundColor(); - mNoPreviewPostTypeIconTint = customThemeWrapper.getNoPreviewPostTypeIconTint(); - mUpvotedColor = customThemeWrapper.getUpvoted(); - mDownvotedColor = customThemeWrapper.getDownvoted(); - mVoteAndReplyUnavailableVoteButtonColor = customThemeWrapper.getVoteAndReplyUnavailableButtonColor(); - mButtonTextColor = customThemeWrapper.getButtonTextColor(); - mPostIconAndInfoColor = customThemeWrapper.getPostIconAndInfoColor(); - mDividerColor = customThemeWrapper.getDividerColor(); - - mCommentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); - if (mCommentIcon != null) { - DrawableCompat.setTint(mCommentIcon, mPostIconAndInfoColor); - } - - mScale = resources.getDisplayMetrics().density; - mGlide = Glide.with(mActivity); - mRedditDataRoomDatabase = redditDataRoomDatabase; - mLocale = locale; - mUserDao = redditDataRoomDatabase.userDao(); - mExoCreator = exoCreator; - mCallback = callback; - mShareLinkBottomSheetFragment = new ShareLinkBottomSheetFragment(); - } - } - - public void setCanStartActivity(boolean canStartActivity) { - this.canStartActivity = canStartActivity; - } - - @Override - public int getItemViewType(int position) { - // Reached at the end - if (hasExtraRow() && position == getItemCount() - 1) { - if (networkState.getStatus() == NetworkState.Status.LOADING) { - return VIEW_TYPE_LOADING; - } else { - return VIEW_TYPE_ERROR; - } - } else { - 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_VIDEO_AND_GIF_PREVIEW_TYPE; - } - return VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE; - } - return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; - case Post.GIF_TYPE: - if (mAutoplay) { - if (!mAutoplayNsfwVideos && post.isNSFW()) { - return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; - } - return VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE; - } - return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; - case Post.IMAGE_TYPE: - return VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE; - case Post.LINK_TYPE: - return VIEW_TYPE_POST_CARD_LINK_TYPE; - case Post.NO_PREVIEW_LINK_TYPE: - return VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE; - case Post.GALLERY_TYPE: - return VIEW_TYPE_POST_CARD_GALLERY_TYPE; - default: - return VIEW_TYPE_POST_CARD_TEXT_TYPE; - } - } - return VIEW_TYPE_POST_CARD_TEXT_TYPE; - } else { - return VIEW_TYPE_POST_COMPACT; - } - } - } - - @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(R.layout.item_post_video_type_autoplay, parent, false)); - } else if (viewType == VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE - || viewType == VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE - || viewType == VIEW_TYPE_POST_CARD_LINK_TYPE - || viewType == VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE - || viewType == VIEW_TYPE_POST_CARD_GALLERY_TYPE) { - return new PostWithPreviewTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_with_preview, parent, false)); - } else if (viewType == VIEW_TYPE_POST_CARD_TEXT_TYPE) { - return new PostTextTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_text, parent, false)); - } else if (viewType == VIEW_TYPE_POST_COMPACT) { - if (mShowThumbnailOnTheRightInCompactLayout) { - return new PostCompactRightThumbnailViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_compact_right_thumbnail, parent, false)); - } else { - return new PostCompactLeftThumbnailViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_compact, parent, false)); - } - } else if (viewType == VIEW_TYPE_ERROR) { - return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false)); - } else { - return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { - if (holder instanceof PostBaseViewHolder) { - Post post = getItem(position); - if (post != null) { - String subredditNamePrefixed = post.getSubredditNamePrefixed(); - String subredditName = subredditNamePrefixed.substring(2); - String authorPrefixed = "u/" + post.getAuthor(); - String flair = post.getFlair(); - int nAwards = post.getnAwards(); - - ((PostBaseViewHolder) holder).subredditTextView.setText(subredditNamePrefixed); - ((PostBaseViewHolder) holder).userTextView.setText(authorPrefixed); - - if (mDisplaySubredditName) { - if (authorPrefixed.equals(subredditNamePrefixed)) { - if (post.getAuthorIconUrl() == null) { - new LoadUserDataAsyncTask(mUserDao, post.getAuthor(), mRetrofit, iconImageUrl -> { - if (mActivity != null && getItemCount() > 0) { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } - - if (holder.getAdapterPosition() >= 0) { - post.setAuthorIconUrl(iconImageUrl); - } - } - }).execute(); - } else if (!post.getAuthorIconUrl().equals("")) { - mGlide.load(post.getAuthorIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((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) { - new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, - iconImageUrl -> { - if (mActivity != null && getItemCount() > 0) { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } - - if (holder.getAdapterPosition() >= 0) { - post.setSubredditIconUrl(iconImageUrl); - } - } - }).execute(); - } else if (!post.getSubredditIconUrl().equals("")) { - mGlide.load(post.getSubredditIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } - } - } else { - if (post.getAuthorIconUrl() == null) { - String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditNamePrefixed().substring(2) : post.getAuthor(); - new LoadUserDataAsyncTask(mUserDao, authorName, mRetrofit, iconImageUrl -> { - if (mActivity != null && getItemCount() > 0) { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostBaseViewHolder) holder).iconGifImageView); - } - - if (holder.getAdapterPosition() >= 0) { - post.setAuthorIconUrl(iconImageUrl); - } - } - }).execute(); - } else if (!post.getAuthorIconUrl().equals("")) { - mGlide.load(post.getAuthorIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((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()); - ((PostBaseViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - if (post.isLocked()) { - ((PostBaseViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); - } - - if (post.isNSFW()) { - ((PostBaseViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); - } - - if (post.isSpoiler()) { - ((PostBaseViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE); - } - - if (flair != null && !flair.equals("")) { - ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((PostBaseViewHolder) holder).flairTextView, flair, false); - } - - if (nAwards > 0) { - ((PostBaseViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); - if (nAwards == 1) { - ((PostBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.one_award)); - } else { - ((PostBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.n_awards, nAwards)); - } - } - - 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 == PostDataSource.TYPE_SUBREDDIT && !mDisplaySubredditName && post.isStickied()) { - ((PostBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostBaseViewHolder) holder).stickiedPostImageView); - } - - if (post.isArchived()) { - ((PostBaseViewHolder) holder).archivedImageView.setVisibility(View.VISIBLE); - - ((PostBaseViewHolder) holder).upvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostBaseViewHolder) holder).downvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (post.isCrosspost()) { - ((PostBaseViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); - } - - ((PostBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(post.getNComments())); - - 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 (holder instanceof PostVideoAutoplayViewHolder) { - ((PostVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); - Post.Preview preview = getSuitablePreview(post.getPreviews()); - if (preview != null) { - ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); - if (mImageViewWidth > preview.getPreviewWidth()) { - mGlide.load(preview.getPreviewUrl()).override(Target.SIZE_ORIGINAL).into(((PostVideoAutoplayViewHolder) holder).previewImageView); - } else { - mGlide.load(preview.getPreviewUrl()).into(((PostVideoAutoplayViewHolder) holder).previewImageView); - } - } else { - ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); - } - ((PostVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); - - if (post.isGfycat() || post.isRedgifs() && !post.isLoadGfyOrRedgifsVideoSuccess()) { - ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks = new FetchGfycatOrRedgifsVideoLinks(new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { - @Override - public void success(String webm, String mp4) { - post.setVideoDownloadUrl(mp4); - post.setVideoUrl(webm); - post.setLoadGfyOrRedgifsVideoSuccess(true); - if (position == holder.getAdapterPosition()) { - ((PostVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); - } - } - - @Override - public void failed(int errorCode) { - if (position == holder.getAdapterPosition()) { - ((PostVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); - } - } - }); - ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks - .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mGfycatRetrofit, mRedgifsRetrofit, - post.getGfycatId(), post.isGfycat(), mAutomaticallyTryRedgifs); - } 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).typeTextView.setText(mActivity.getString(R.string.video)); - } else if (post.getPostType() == Post.GIF_TYPE) { - if (!mAutoplay) { - ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); - } - ((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); - } else if (post.getPostType() == Post.GALLERY_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gallery)); - } - - if (post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - } - - if (mDataSavingMode && mDisableImagePreview) { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); - if (post.getPostType() == Post.VIDEO_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_outline_video_24dp); - ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); - } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); - ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); - } else if (post.getPostType() == Post.LINK_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); - } else if (post.getPostType() == Post.GALLERY_TYPE) { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); - } - } else { - Post.Preview preview = getSuitablePreview(post.getPreviews()); - if (preview != null) { - ((PostWithPreviewTypeViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.VISIBLE); - if (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0) { - ((PostWithPreviewTypeViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); - ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = (int) (400 * mScale); - } else { - ((PostWithPreviewTypeViewHolder) holder).imageView - .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); - } - loadImage(holder, post, preview); - } else { - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); - } - } - } else if (holder instanceof PostTextTypeViewHolder) { - if (!post.isSpoiler() && post.getSelfTextPlainTrimmed() != null && !post.getSelfTextPlainTrimmed().equals("")) { - ((PostTextTypeViewHolder) holder).contentTextView.setVisibility(View.VISIBLE); - ((PostTextTypeViewHolder) holder).contentTextView.setText(post.getSelfTextPlainTrimmed()); - } - } - mCallback.currentlyBindItem(holder.getAdapterPosition()); - } - } else if (holder instanceof PostCompactBaseViewHolder) { - Post post = getItem(position); - if (post != null) { - final String subredditNamePrefixed = post.getSubredditNamePrefixed(); - String subredditName = subredditNamePrefixed.substring(2); - String authorPrefixed = "u/" + post.getAuthor(); - final String title = post.getTitle(); - int voteType = post.getVoteType(); - boolean nsfw = post.isNSFW(); - boolean spoiler = post.isSpoiler(); - String flair = post.getFlair(); - int nAwards = post.getnAwards(); - boolean isArchived = post.isArchived(); - - if (mDisplaySubredditName) { - if (authorPrefixed.equals(subredditNamePrefixed)) { - if (post.getAuthorIconUrl() == null) { - new LoadUserDataAsyncTask(mUserDao, post.getAuthor(), mRetrofit, iconImageUrl -> { - if (mActivity != null && getItemCount() > 0) { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } - - if (holder.getAdapterPosition() >= 0) { - post.setAuthorIconUrl(iconImageUrl); - } - } - }).execute(); - } else if (!post.getAuthorIconUrl().equals("")) { - mGlide.load(post.getAuthorIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((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) { - new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, - iconImageUrl -> { - if (mActivity != null && getItemCount() > 0) { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } - - if (holder.getAdapterPosition() >= 0) { - post.setSubredditIconUrl(iconImageUrl); - } - } - }).execute(); - } else if (!post.getSubredditIconUrl().equals("")) { - mGlide.load(post.getSubredditIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((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); - ((PostCompactBaseViewHolder) holder).nameTextView.setText(subredditNamePrefixed); - } else { - if (post.getAuthorIconUrl() == null) { - String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditNamePrefixed().substring(2) : post.getAuthor(); - new LoadUserDataAsyncTask(mUserDao, authorName, mRetrofit, iconImageUrl -> { - if (mActivity != null && getItemCount() > 0) { - if (iconImageUrl == null || iconImageUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(iconImageUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } - - if (holder.getAdapterPosition() >= 0) { - post.setAuthorIconUrl(iconImageUrl); - } - } - }).execute(); - } else if (!post.getAuthorIconUrl().equals("")) { - mGlide.load(post.getAuthorIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } else { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((PostCompactBaseViewHolder) holder).iconGifImageView); - } - - ((PostCompactBaseViewHolder) holder).nameTextView.setTextColor(mUsernameColor); - ((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); - ((PostCompactBaseViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - if (post.isLocked()) { - ((PostCompactBaseViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); - } - - if (nsfw) { - ((PostCompactBaseViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); - } - - if (spoiler) { - ((PostCompactBaseViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE); - } - - if (flair != null && !flair.equals("")) { - ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); - Utils.setHTMLWithImageToTextView(((PostCompactBaseViewHolder) holder).flairTextView, flair, false); - } - - if (nAwards > 0) { - ((PostCompactBaseViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); - if (nAwards == 1) { - ((PostCompactBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.one_award)); - } else { - ((PostCompactBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.n_awards, nAwards)); - } - } - - switch (voteType) { - case 1: - //Upvoted - ((PostCompactBaseViewHolder) holder).upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostCompactBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); - break; - case -1: - //Downvoted - ((PostCompactBaseViewHolder) holder).downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostCompactBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); - break; - } - - if (post.getPostType() != Post.TEXT_TYPE && post.getPostType() != Post.NO_PREVIEW_LINK_TYPE && !(mDataSavingMode && mDisableImagePreview)) { - ((PostCompactBaseViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); - if (post.getPostType() != Post.GIF_TYPE && post.getPostType() != Post.VIDEO_TYPE) { - ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - } - if (post.getPostType() == Post.GALLERY_TYPE && post.getPreviews().isEmpty()) { - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); - } else { - ((PostCompactBaseViewHolder) holder).imageView.setVisibility(View.VISIBLE); - } - ArrayList previews = post.getPreviews(); - if (previews != null && !previews.isEmpty()) { - loadImage(holder, post, previews.get(0)); - } - } - - if (mPostType == PostDataSource.TYPE_SUBREDDIT && !mDisplaySubredditName && post.isStickied()) { - ((PostCompactBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostCompactBaseViewHolder) holder).stickiedPostImageView); - } - - if (isArchived) { - ((PostCompactBaseViewHolder) holder).archivedImageView.setVisibility(View.VISIBLE); - - ((PostCompactBaseViewHolder) holder).upvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); - ((PostCompactBaseViewHolder) holder).downvoteButton - .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - - if (post.isCrosspost()) { - ((PostCompactBaseViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); - } - - switch (post.getPostType()) { - case Post.IMAGE_TYPE: - ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.image); - if (mDataSavingMode && mDisableImagePreview) { - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); - } - break; - case Post.LINK_TYPE: - ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.link); - if (mDataSavingMode && mDisableImagePreview) { - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.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) { - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); - } else { - ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.VISIBLE); - } - - break; - case Post.VIDEO_TYPE: - ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.video); - if (mDataSavingMode && mDisableImagePreview) { - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_outline_video_24dp); - } else { - ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.VISIBLE); - } - - 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).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); - break; - case Post.GALLERY_TYPE: - ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.gallery); - if (mDataSavingMode && mDisableImagePreview) { - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); - ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); - } - break; - case Post.TEXT_TYPE: - ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.text); - break; - } - - ((PostCompactBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(post.getNComments())); - - 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.getAdapterPosition()); - } - } - } - - @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() >= 75_000_000) { - for (int i = previews.size() - 1; i >= 1; i--) { - preview = previews.get(i); - if (mImageViewWidth >= preview.getPreviewWidth()) { - if (preview.getPreviewWidth() * preview.getPreviewHeight() <= 75_000_000) { - return preview; - } - } else { - int height = mImageViewWidth / preview.getPreviewWidth() * preview.getPreviewHeight(); - if (mImageViewWidth * height <= 75_000_000) { - return preview; - } - } - } - } - - int divisor = 2; - while (preview.getPreviewWidth() * preview.getPreviewHeight() / divisor / divisor > 75_000_000) { - preview.setPreviewWidth(preview.getPreviewWidth() / divisor); - preview.setPreviewHeight(preview.getPreviewHeight() / divisor); - divisor *= 2; - } - - return preview; - } - - return null; - } - - private void loadImage(final RecyclerView.ViewHolder holder, final Post post, @NonNull Post.Preview preview) { - if (preview != null) { - if (holder instanceof PostWithPreviewTypeViewHolder) { - String url; - if (post.getPostType() == Post.GIF_TYPE && mAutoplay) { - url = post.getUrl(); - } else { - url = preview.getPreviewUrl(); - } - RequestBuilder imageRequestBuilder = mGlide.load(url).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.VISIBLE); - ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setOnClickListener(view -> { - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); - ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); - loadImage(holder, post, preview); - }); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; - } - }); - - if ((post.isNSFW() && mNeedBlurNSFW && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler) { - imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) - .into(((PostWithPreviewTypeViewHolder) holder).imageView); - } else { - if (mImageViewWidth > preview.getPreviewWidth()) { - imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostWithPreviewTypeViewHolder) holder).imageView); - } else { - imageRequestBuilder.into(((PostWithPreviewTypeViewHolder) holder).imageView); - } - } - } else if (holder instanceof PostCompactBaseViewHolder) { - String postCompactThumbnailPreviewUrl; - ArrayList previews = post.getPreviews(); - if (previews != null && !previews.isEmpty()) { - if (previews.size() >= 2) { - postCompactThumbnailPreviewUrl = previews.get(1).getPreviewUrl(); - } else { - postCompactThumbnailPreviewUrl = preview.getPreviewUrl(); - } - - RequestBuilder imageRequestBuilder = mGlide.load(postCompactThumbnailPreviewUrl) - .error(R.drawable.ic_error_outline_black_24dp).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; - } - - @Override - public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.GONE); - return false; - } - }); - if ((post.isNSFW() && mNeedBlurNSFW) || post.isSpoiler() && mNeedBlurSpoiler) { - imageRequestBuilder - .transform(new BlurTransformation(50, 2)).into(((PostCompactBaseViewHolder) holder).imageView); - } else { - imageRequestBuilder.into(((PostCompactBaseViewHolder) 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; - } - } - mShareLinkBottomSheetFragment.setArguments(bundle); - mShareLinkBottomSheetFragment.show(mActivity.getSupportFragmentManager(), mShareLinkBottomSheetFragment.getTag()); - } - - @Override - public int getItemCount() { - if (hasExtraRow()) { - return super.getItemCount() + 1; - } - return super.getItemCount(); - } - - @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 setBlurNSFW(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; - } - - private boolean hasExtraRow() { - return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; - } - - public void setNetworkState(NetworkState newNetworkState) { - NetworkState previousState = this.networkState; - boolean previousExtraRow = hasExtraRow(); - this.networkState = newNetworkState; - boolean newExtraRow = hasExtraRow(); - if (previousExtraRow != newExtraRow) { - if (previousExtraRow) { - notifyItemRemoved(getItemCount() - 1); - } else { - notifyItemInserted(super.getItemCount()); - } - } else if (newExtraRow && !previousState.equals(newNetworkState)) { - notifyItemChanged(getItemCount() - 1); - } - } - - public void removeFooter() { - if (hasExtraRow()) { - notifyItemRemoved(getItemCount() - 1); - } - - networkState = null; - } - - 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; - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - super.onViewRecycled(holder); - if (holder instanceof PostBaseViewHolder) { - if (holder instanceof PostVideoAutoplayViewHolder) { - ((PostVideoAutoplayViewHolder) holder).mediaUri = null; - if (((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks != null) { - ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks.cancel(); - } - ((PostVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.GONE); - ((PostVideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); - ((PostVideoAutoplayViewHolder) holder).resetVolume(); - mGlide.clear(((PostVideoAutoplayViewHolder) holder).previewImageView); - ((PostVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); - } else if (holder instanceof PostWithPreviewTypeViewHolder) { - mGlide.clear(((PostWithPreviewTypeViewHolder) holder).imageView); - ((PostWithPreviewTypeViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); - ((PostWithPreviewTypeViewHolder) holder).linkTextView.setVisibility(View.GONE); - } else if (holder instanceof PostTextTypeViewHolder) { - ((PostTextTypeViewHolder) holder).contentTextView.setText(""); - ((PostTextTypeViewHolder) holder).contentTextView.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) { - 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).noPreviewLinkImageFrameLayout.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); - } - } - - @Nullable - @Override - public Object getKeyForOrder(int order) { - if (super.getItemCount() <= 0 || order >= super.getItemCount()) { - return null; - } - return getItem(order); - } - - @Nullable - @Override - public Integer getOrderForKey(@NonNull Object key) { - if (getCurrentList() != null && key instanceof Post) { - return getCurrentList().indexOf(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 retryLoadingMore(); - - void typeChipClicked(int filter); - - void currentlyBindItem(int position); - - void delayTransition(); - } - - public class PostBaseViewHolder extends RecyclerView.ViewHolder { - MaterialCardView cardView; - 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; - - PostBaseViewHolder(@NonNull View itemView) { - super(itemView); - } - - void setBaseView(MaterialCardView cardView, - 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.cardView = cardView; - 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); - } - - itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); - 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); - - cardView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position >= 0 && canStartActivity) { - canStartActivity = false; - - Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, getItem(position)); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_LIST_POSITION, getAdapterPosition()); - mActivity.startActivity(intent); - } - }); - - userTextView.setOnClickListener(view -> { - if (canStartActivity) { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - canStartActivity = false; - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); - mActivity.startActivity(intent); - } - } - }); - - if (mDisplaySubredditName) { - subredditTextView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (canStartActivity) { - canStartActivity = false; - if (post.getSubredditNamePrefixed().startsWith("u/")) { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, - post.getSubredditNamePrefixed().substring(2)); - mActivity.startActivity(intent); - } else { - 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 = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (canStartActivity) { - canStartActivity = false; - if (post.getSubredditNamePrefixed().startsWith("u/")) { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); - mActivity.startActivity(intent); - } else { - 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 FilteredThingActivity)) { - nsfwTextView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - Intent intent = new Intent(mActivity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, post.getSubredditNamePrefixed().substring(2)); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, Post.NSFW_TYPE); - mActivity.startActivity(intent); - } - }); - typeTextView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - mCallback.typeChipClicked(post.getPostType()); - } - }); - } - - upvoteButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (post.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); - int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); - - int previousVoteType = post.getVoteType(); - String newVoteType; - - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != 1) { - //Not upvoted before - post.setVoteType(1); - newVoteType = APIUtils.DIR_UPVOTE; - upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - post.setVoteType(0); - newVoteType = APIUtils.DIR_UNVOTE; - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { - post.setVoteType(1); - upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - post.setVoteType(0); - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - - @Override - public void onVoteThingFail(int position1) { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - post.setVoteType(previousVoteType); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); - upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - scoreTextView.setTextColor(previousScoreTextViewColor); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - }, post.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - downvoteButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (post.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); - int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); - - int previousVoteType = post.getVoteType(); - String newVoteType; - - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != -1) { - //Not downvoted before - post.setVoteType(-1); - newVoteType = APIUtils.DIR_DOWNVOTE; - downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - //Downvoted before - post.setVoteType(0); - newVoteType = APIUtils.DIR_UNVOTE; - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { - post.setVoteType(-1); - downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - post.setVoteType(0); - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - - @Override - public void onVoteThingFail(int position1) { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - post.setVoteType(previousVoteType); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); - upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - scoreTextView.setTextColor(previousScoreTextViewColor); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - }, post.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - saveButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - if (post.isSaved()) { - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, post.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - post.setSaved(false); - 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 PostUpdateEventToDetailActivity(post)); - } - - @Override - public void failed() { - post.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - }); - } else { - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - SaveThing.saveThing(mOauthRetrofit, mAccessToken, post.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - post.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - - @Override - public void failed() { - post.setSaved(false); - 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 PostUpdateEventToDetailActivity(post)); - } - }); - } - } - }); - - shareButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - shareLink(post); - } - }); - } - } - - class PostVideoAutoplayViewHolder extends PostBaseViewHolder implements ToroPlayer { - @BindView(R.id.card_view_item_post_video_type_autoplay) - MaterialCardView cardView; - @BindView(R.id.icon_gif_image_view_item_post_video_type_autoplay) - AspectRatioGifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_item_post_video_type_autoplay) - TextView subredditTextView; - @BindView(R.id.user_text_view_item_post_video_type_autoplay) - TextView userTextView; - @BindView(R.id.stickied_post_image_view_item_post_video_type_autoplay) - ImageView stickiedPostImageView; - @BindView(R.id.post_time_text_view_item_post_video_type_autoplay) - TextView postTimeTextView; - @BindView(R.id.title_text_view_item_post_video_type_autoplay) - TextView titleTextView; - @BindView(R.id.type_text_view_item_post_video_type_autoplay) - CustomTextView typeTextView; - @BindView(R.id.archived_image_view_item_post_video_type_autoplay) - ImageView archivedImageView; - @BindView(R.id.locked_image_view_item_post_video_type_autoplay) - ImageView lockedImageView; - @BindView(R.id.crosspost_image_view_item_post_video_type_autoplay) - ImageView crosspostImageView; - @BindView(R.id.nsfw_text_view_item_post_video_type_autoplay) - CustomTextView nsfwTextView; - @BindView(R.id.spoiler_custom_text_view_item_post_video_type_autoplay) - CustomTextView spoilerTextView; - @BindView(R.id.flair_custom_text_view_item_post_video_type_autoplay) - CustomTextView flairTextView; - @BindView(R.id.awards_text_view_item_post_video_type_autoplay) - CustomTextView awardsTextView; - @BindView(R.id.aspect_ratio_frame_layout_item_post_video_type_autoplay) - AspectRatioFrameLayout aspectRatioFrameLayout; - @BindView(R.id.preview_image_view_item_post_video_type_autoplay) - GifImageView previewImageView; - @BindView(R.id.error_loading_gfycat_image_view_item_post_video_type_autoplay) - ImageView errorLoadingGfycatImageView; - @BindView(R.id.player_view_item_post_video_type_autoplay) - PlayerView videoPlayer; - @BindView(R.id.mute_exo_playback_control_view) - ImageView muteButton; - @BindView(R.id.fullscreen_exo_playback_control_view) - ImageView fullscreenButton; - @BindView(R.id.bottom_constraint_layout_item_post_video_type_autoplay) - ConstraintLayout bottomConstraintLayout; - @BindView(R.id.plus_button_item_post_video_type_autoplay) - ImageView upvoteButton; - @BindView(R.id.score_text_view_item_post_video_type_autoplay) - TextView scoreTextView; - @BindView(R.id.minus_button_item_post_video_type_autoplay) - ImageView downvoteButton; - @BindView(R.id.comments_count_item_post_video_type_autoplay) - TextView commentsCountTextView; - @BindView(R.id.save_button_item_post_video_type_autoplay) - ImageView saveButton; - @BindView(R.id.share_button_item_post_video_type_autoplay) - ImageView shareButton; - - @Nullable - ExoPlayerViewHelper helper; - private Uri mediaUri; - private float volume; - public FetchGfycatOrRedgifsVideoLinks fetchGfycatOrRedgifsVideoLinks; - - PostVideoAutoplayViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(cardView, - 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(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); - helper.setVolume(0f); - volume = 0f; - } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); - helper.setVolume(1f); - volume = 1f; - } - } - }); - - fullscreenButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - Intent intent = new Intent(mActivity, ViewVideoActivity.class); - if (post.isGfycat()) { - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); - intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); - if (post.isLoadGfyOrRedgifsVideoSuccess()) { - 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.isLoadGfyOrRedgifsVideoSuccess()) { - intent.setData(Uri.parse(post.getVideoUrl())); - intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); - } - } 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.setOnLongClickListener(view -> fullscreenButton.performClick()); - videoPlayer.setOnLongClickListener(view -> fullscreenButton.performClick()); - } - - void bindVideoUri(Uri videoUri) { - mediaUri = videoUri; - } - - void setVolume(float volume) { - this.volume = volume; - } - - void resetVolume() { - volume = 0f; - } - - @NonNull - @Override - public View getPlayerView() { - return videoPlayer; - } - - @NonNull - @Override - public PlaybackInfo getCurrentPlaybackInfo() { - return helper != null && mediaUri != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo(); - } - - @Override - public void initialize(@NonNull Container container, @NonNull PlaybackInfo playbackInfo) { - if (mediaUri == null) { - return; - } - if (helper == null) { - helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); - helper.addEventListener(new Playable.EventListener() { - @Override - public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - if (!trackGroups.isEmpty()) { - for (int i = 0; i < trackGroups.length; i++) { - String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; - if (mimeType != null && mimeType.contains("audio")) { - helper.setVolume(volume); - muteButton.setVisibility(View.VISIBLE); - if (volume != 0f) { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); - } else { - muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); - } - break; - } - } - } else { - muteButton.setVisibility(View.GONE); - } - } - - @Override - public void onMetadata(Metadata metadata) { - - } - - @Override - public void onCues(List cues) { - - } - - @Override - public void onRenderedFirstFrame() { - mGlide.clear(previewImageView); - previewImageView.setVisibility(View.GONE); - } - }); - } - helper.initialize(container, playbackInfo); - } - - @Override - public void play() { - if (helper != null && mediaUri != null) { - helper.play(); - } - } - - @Override - public void pause() { - if (helper != null) helper.pause(); - } - - @Override - public boolean isPlaying() { - return helper != null && helper.isPlaying(); - } - - @Override - public void release() { - if (helper != null) { - helper.release(); - helper = null; - } - } - - @Override - public boolean wantsToPlay() { - return mediaUri != null && ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= mStartAutoplayVisibleAreaOffset; - } - - @Override - public int getPlayerOrder() { - return getAdapterPosition(); - } - } - - class PostWithPreviewTypeViewHolder extends PostBaseViewHolder { - @BindView(R.id.card_view_item_post_with_preview) - MaterialCardView cardView; - @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) - RelativeLayout 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_relative_layout_item_post_with_preview) - RelativeLayout errorRelativeLayout; - @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; - - PostWithPreviewTypeViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(cardView, - iconGifImageView, - subredditTextView, - userTextView, - stickiedPostImageView, - postTimeTextView, - titleTextView, - typeTextView, - archivedImageView, - lockedImageView, - crosspostImageView, - nsfwTextView, - spoilerTextView, - flairTextView, - awardsTextView, - bottomConstraintLayout, - upvoteButton, - scoreTextView, - downvoteButton, - commentsCountTextView, - saveButton, - shareButton); - - linkTextView.setTextColor(mSecondaryTextColor); - noPreviewLinkImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); - noPreviewLinkImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - errorTextView.setTextColor(mPrimaryTextColor); - - imageView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (post.getPostType() == Post.VIDEO_TYPE) { - Intent intent = new Intent(mActivity, ViewVideoActivity.class); - 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 { - 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()); - 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()); - 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()); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(post.getUrl())); - } else { - 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()); - mActivity.startActivity(intent); - } - } - }); - - noPreviewLinkImageView.setOnClickListener(view -> { - imageView.performClick(); - }); - } - } - - class PostTextTypeViewHolder extends PostBaseViewHolder { - @BindView(R.id.card_view_item_post_text_type) - MaterialCardView cardView; - @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(cardView, - iconGifImageView, - subredditTextView, - userTextView, - stickiedPostImageView, - postTimeTextView, - titleTextView, - typeTextView, - archivedImageView, - lockedImageView, - crosspostImageView, - nsfwTextView, - spoilerTextView, - flairTextView, - awardsTextView, - bottomConstraintLayout, - upvoteButton, - scoreTextView, - downvoteButton, - commentsCountTextView, - saveButton, - shareButton); - - 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 noPreviewLinkImageFrameLayout; - ImageView noPreviewLinkImageView; - Barrier imageBarrier; - ConstraintLayout bottomConstraintLayout; - ImageView upvoteButton; - TextView scoreTextView; - ImageView downvoteButton; - TextView commentsCountTextView; - ImageView saveButton; - ImageView shareButton; - View divider; - - 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.noPreviewLinkImageFrameLayout = noPreviewLinkImageFrameLayout; - this.noPreviewLinkImageView = 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); - } - - 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); - 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 = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null && canStartActivity) { - canStartActivity = false; - - Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, post); - intent.putExtra(ViewPostDetailActivity.EXTRA_POST_LIST_POSITION, getAdapterPosition()); - mActivity.startActivity(intent); - } - }); - - itemView.setOnLongClickListener(view -> { - if (mLongPressToHideToolbarInCompactLayout) { - if (bottomConstraintLayout.getLayoutParams().height == 0) { - ViewGroup.LayoutParams params = (LinearLayout.LayoutParams) bottomConstraintLayout.getLayoutParams(); - params.height = LinearLayout.LayoutParams.WRAP_CONTENT; - bottomConstraintLayout.setLayoutParams(params); - mCallback.delayTransition(); - } else { - mCallback.delayTransition(); - ViewGroup.LayoutParams params = (LinearLayout.LayoutParams) bottomConstraintLayout.getLayoutParams(); - params.height = 0; - bottomConstraintLayout.setLayoutParams(params); - } - } - return true; - }); - - nameTextView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null && canStartActivity) { - canStartActivity = false; - if (mDisplaySubredditName) { - if (post.getSubredditNamePrefixed().startsWith("u/")) { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, - post.getSubredditNamePrefixed().substring(2)); - mActivity.startActivity(intent); - } else { - Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, - post.getSubredditNamePrefixed().substring(2)); - mActivity.startActivity(intent); - } - } else { - Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); - mActivity.startActivity(intent); - } - } - }); - - iconGifImageView.setOnClickListener(view -> nameTextView.performClick()); - - nsfwTextView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null && !(mActivity instanceof FilteredThingActivity)) { - Intent intent = new Intent(mActivity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, post.getSubredditNamePrefixed().substring(2)); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, Post.NSFW_TYPE); - mActivity.startActivity(intent); - } - }); - - typeTextView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null && !(mActivity instanceof FilteredThingActivity)) { - mCallback.typeChipClicked(post.getPostType()); - } - }); - - imageView.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (post.getPostType() == Post.VIDEO_TYPE) { - Intent intent = new Intent(mActivity, ViewVideoActivity.class); - 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 { - 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()); - 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()); - 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()); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(post.getUrl())); - } else { - 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()); - mActivity.startActivity(intent); - } - } - }); - - 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 = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (post.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); - int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); - - int previousVoteType = post.getVoteType(); - String newVoteType; - - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != 1) { - //Not upvoted before - post.setVoteType(1); - newVoteType = APIUtils.DIR_UPVOTE; - upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - //Upvoted before - post.setVoteType(0); - newVoteType = APIUtils.DIR_UNVOTE; - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { - post.setVoteType(1); - upvoteButton - .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mUpvotedColor); - } else { - post.setVoteType(0); - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - - @Override - public void onVoteThingFail(int position1) { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - post.setVoteType(previousVoteType); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); - upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - scoreTextView.setTextColor(previousScoreTextViewColor); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - }, post.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - downvoteButton.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (post.isArchived()) { - Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); - return; - } - - ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); - ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); - int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); - - int previousVoteType = post.getVoteType(); - String newVoteType; - - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - - if (previousVoteType != -1) { - //Not downvoted before - post.setVoteType(-1); - newVoteType = APIUtils.DIR_DOWNVOTE; - downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - //Downvoted before - post.setVoteType(0); - newVoteType = APIUtils.DIR_UNVOTE; - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { - @Override - public void onVoteThingSuccess(int position1) { - if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { - post.setVoteType(-1); - downvoteButton - .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mDownvotedColor); - } else { - post.setVoteType(0); - downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setTextColor(mPostIconAndInfoColor); - } - - upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - - @Override - public void onVoteThingFail(int position1) { - Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); - post.setVoteType(previousVoteType); - scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); - upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); - downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); - scoreTextView.setTextColor(previousScoreTextViewColor); - - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - }, post.getFullName(), newVoteType, getAdapterPosition()); - } - }); - - saveButton.setOnClickListener(view -> { - if (mAccessToken == null) { - Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); - return; - } - - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - if (post.isSaved()) { - saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); - SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, post.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - post.setSaved(false); - 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 PostUpdateEventToDetailActivity(post)); - } - - @Override - public void failed() { - post.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - }); - } else { - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - SaveThing.saveThing(mOauthRetrofit, mAccessToken, post.getFullName(), - new SaveThing.SaveThingListener() { - @Override - public void success() { - post.setSaved(true); - saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); - Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); - } - - @Override - public void failed() { - post.setSaved(false); - 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 PostUpdateEventToDetailActivity(post)); - } - }); - } - } - }); - - shareButton.setOnClickListener(view -> { - int position = getAdapterPosition(); - if (position < 0) { - return; - } - Post post = getItem(position); - if (post != null) { - shareLink(post); - } - }); - } - } - - 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 ErrorViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_footer_error) - TextView errorTextView; - @BindView(R.id.retry_button_item_footer_error) - Button retryButton; - - ErrorViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - errorTextView.setText(R.string.load_more_posts_error); - errorTextView.setTextColor(mSecondaryTextColor); - retryButton.setOnClickListener(view -> mCallback.retryLoadingMore()); - retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); - retryButton.setTextColor(mButtonTextColor); - itemView.setOnClickListener(view -> retryButton.performClick()); - } - } - - class LoadingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_item_footer_loading) - ProgressBar progressBar; - - LoadingViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java deleted file mode 100644 index 572db144..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/PrivateMessagesDetailRecyclerViewAdapter.java +++ /dev/null @@ -1,277 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.graphics.Color; -import android.net.Uri; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -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 com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import java.util.Locale; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPrivateMessagesActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Message.Message; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapter { - private static final int VIEW_TYPE_MESSAGE_SENT = 0; - private static final int VIEW_TYPE_MESSAGE_RECEIVED = 1; - private Message mMessage; - private ViewPrivateMessagesActivity mViewPrivateMessagesActivity; - private RequestManager mGlide; - private Locale mLocale; - private String mAccountName; - private Markwon mMarkwon; - private boolean mShowElapsedTime; - private String mTimeFormatPattern; - private int mSecondaryTextColor; - private int mReceivedMessageTextColor; - private int mSentMessageTextColor; - private int mReceivedMessageBackgroundColor; - private int mSentMessageBackgroundColor; - - public PrivateMessagesDetailRecyclerViewAdapter(ViewPrivateMessagesActivity viewPrivateMessagesActivity, - SharedPreferences sharedPreferences, Locale locale, - Message message, String accountName, - CustomThemeWrapper customThemeWrapper) { - mMessage = message; - mViewPrivateMessagesActivity = viewPrivateMessagesActivity; - mGlide = Glide.with(viewPrivateMessagesActivity); - mLocale = locale; - mAccountName = accountName; - mMarkwon = Markwon.builder(viewPrivateMessagesActivity) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(viewPrivateMessagesActivity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - viewPrivateMessagesActivity.startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(customThemeWrapper.getLinkColor()); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .build(); - mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); - mTimeFormatPattern = sharedPreferences.getString(SharedPreferencesUtils.TIME_FORMAT_KEY, SharedPreferencesUtils.TIME_FORMAT_DEFAULT_VALUE); - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - mReceivedMessageTextColor = customThemeWrapper.getReceivedMessageTextColor(); - mSentMessageTextColor = customThemeWrapper.getSentMessageTextColor(); - mReceivedMessageBackgroundColor = customThemeWrapper.getReceivedMessageBackgroundColor(); - mSentMessageBackgroundColor = customThemeWrapper.getSentMessageBackgroundColor(); - } - - @Override - public int getItemViewType(int position) { - if (position == 0) { - return mMessage.getAuthor().equals(mAccountName) ? VIEW_TYPE_MESSAGE_SENT : VIEW_TYPE_MESSAGE_RECEIVED; - } else { - return mMessage.getReplies().get(position - 1).getAuthor().equals(mAccountName) ? VIEW_TYPE_MESSAGE_SENT : VIEW_TYPE_MESSAGE_RECEIVED; - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if (viewType == VIEW_TYPE_MESSAGE_SENT) { - return new SentMessageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_private_message_sent, parent, false)); - } else { - return new ReceivedMessageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_private_message_received, parent, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - Message message; - if (holder.getAdapterPosition() == 0) { - message = mMessage; - } else { - message = mMessage.getReplies().get(holder.getAdapterPosition() - 1); - } - if (message != null) { - if (holder instanceof MessageViewHolder) { - mMarkwon.setMarkdown(((MessageViewHolder) holder).messageTextView, message.getBody()); - - ((MessageViewHolder) holder).messageTextView.setOnClickListener(view -> ((MessageViewHolder) holder).itemView.performClick()); - if (mShowElapsedTime) { - ((MessageViewHolder) holder).timeTextView.setText(Utils.getElapsedTime(mViewPrivateMessagesActivity, message.getTimeUTC())); - } else { - ((MessageViewHolder) holder).timeTextView.setText(Utils.getFormattedTime(mLocale, message.getTimeUTC(), mTimeFormatPattern)); - } - - ((MessageViewHolder) holder).messageTextView.setOnClickListener(view -> { - if (((MessageViewHolder) holder).timeTextView.getVisibility() != View.VISIBLE) { - ((MessageViewHolder) holder).timeTextView.setVisibility(View.VISIBLE); - mViewPrivateMessagesActivity.delayTransition(); - } else { - ((MessageViewHolder) holder).timeTextView.setVisibility(View.GONE); - mViewPrivateMessagesActivity.delayTransition(); - } - }); - } - - if (holder instanceof SentMessageViewHolder) { - ((SentMessageViewHolder) holder).messageTextView.setBackground(Utils.getTintedDrawable(mViewPrivateMessagesActivity, - R.drawable.private_message_ballon, mSentMessageBackgroundColor)); - } else if (holder instanceof ReceivedMessageViewHolder) { - mViewPrivateMessagesActivity.fetchUserAvatar(message.getAuthor(), userAvatarUrl -> { - if (userAvatarUrl == null || userAvatarUrl.equals("")) { - mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((ReceivedMessageViewHolder) holder).userAvatarImageView); - } else { - mGlide.load(userAvatarUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(mGlide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((ReceivedMessageViewHolder) holder).userAvatarImageView); - } - }); - - ((ReceivedMessageViewHolder) holder).userAvatarImageView.setOnClickListener(view -> { - Intent intent = new Intent(mViewPrivateMessagesActivity, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor()); - mViewPrivateMessagesActivity.startActivity(intent); - }); - - ((ReceivedMessageViewHolder) holder).messageTextView.setBackground( - Utils.getTintedDrawable(mViewPrivateMessagesActivity, - R.drawable.private_message_ballon, mReceivedMessageBackgroundColor)); - } - } - } - - @Override - public int getItemCount() { - if (mMessage == null) { - return 0; - } else if (mMessage.getReplies() == null) { - return 1; - } else { - return 1 + mMessage.getReplies().size(); - } - } - - public void setMessage(Message message) { - mMessage = message; - notifyDataSetChanged(); - } - - public void addReply(Message reply) { - int currentSize = getItemCount(); - - if (mMessage != null) { - mMessage.addReply(reply); - } else { - mMessage = reply; - } - - notifyItemInserted(currentSize); - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - super.onViewRecycled(holder); - if (holder instanceof MessageViewHolder) { - ((MessageViewHolder) holder).messageTextView.setBackground(null); - ((MessageViewHolder) holder).timeTextView.setVisibility(View.GONE); - } - if (holder instanceof ReceivedMessageViewHolder) { - mGlide.clear(((ReceivedMessageViewHolder) holder).userAvatarImageView); - } - } - - class MessageViewHolder extends RecyclerView.ViewHolder { - TextView messageTextView; - TextView timeTextView; - - public MessageViewHolder(@NonNull View itemView) { - super(itemView); - } - - void setBaseView(TextView messageTextView, TextView timeTextView) { - this.messageTextView = messageTextView; - this.timeTextView = timeTextView; - - messageTextView.setTextColor(Color.WHITE); - timeTextView.setTextColor(mSecondaryTextColor); - } - } - - class SentMessageViewHolder extends MessageViewHolder { - @BindView(R.id.message_text_view_item_private_message_sent) - TextView messageTextView; - @BindView(R.id.time_text_view_item_private_message_sent) - TextView timeTextView; - - SentMessageViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(messageTextView, timeTextView); - - messageTextView.setTextColor(mSentMessageTextColor); - - } - } - - class ReceivedMessageViewHolder extends MessageViewHolder { - @BindView(R.id.avatar_image_view_item_private_message_received) - ImageView userAvatarImageView; - @BindView(R.id.message_text_view_item_private_message_received) - TextView messageTextView; - @BindView(R.id.time_text_view_item_private_message_received) - TextView timeTextView; - - ReceivedMessageViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - setBaseView(messageTextView, timeTextView); - - messageTextView.setTextColor(mReceivedMessageTextColor); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java deleted file mode 100644 index 8bbc3991..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/ReportReasonRecyclerViewAdapter.java +++ /dev/null @@ -1,130 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.res.ColorStateList; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import java.util.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.ReportReason; - -public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter { - - private ArrayList generalReasons; - private ArrayList rules; - private int primaryTextColor; - private int colorAccent; - - public ReportReasonRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList generalReasons) { - this.generalReasons = generalReasons; - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - colorAccent = customThemeWrapper.getColorAccent(); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new ReasonViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_report_reason, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof ReasonViewHolder) { - ReportReason reportReason; - if (position >= generalReasons.size()) { - reportReason = rules.get(holder.getAdapterPosition() - generalReasons.size()); - } else { - reportReason = generalReasons.get(holder.getAdapterPosition()); - } - ((ReasonViewHolder) holder).reasonTextView.setText(reportReason.getReportReason()); - ((ReasonViewHolder) holder).checkBox.setChecked(reportReason.isSelected()); - } - } - - @Override - public int getItemCount() { - return rules == null ? generalReasons.size() : rules.size() + generalReasons.size(); - } - - public void setRules(ArrayList reportReasons) { - this.rules = reportReasons; - notifyDataSetChanged(); - } - - public ReportReason getSelectedReason() { - for (ReportReason reportReason : rules) { - if (reportReason.isSelected()) { - return reportReason; - } - } - - for (ReportReason reportReason : generalReasons) { - if (reportReason.isSelected()) { - return reportReason; - } - } - - return null; - } - - public ArrayList getGeneralReasons() { - return generalReasons; - } - - public ArrayList getRules() { - return rules; - } - - class ReasonViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.reason_text_view_item_report_reason) - TextView reasonTextView; - @BindView(R.id.check_box_item_report_reason) - CheckBox checkBox; - - ReasonViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - reasonTextView.setTextColor(primaryTextColor); - checkBox.setButtonTintList(ColorStateList.valueOf(colorAccent)); - - checkBox.setOnClickListener(view -> { - for (int i = 0; i < generalReasons.size(); i++) { - if (generalReasons.get(i).isSelected()) { - generalReasons.get(i).setSelected(false); - notifyItemChanged(i); - - } - } - - if (rules != null) { - for (int i = 0; i < rules.size(); i++) { - if (rules.get(i).isSelected()) { - rules.get(i).setSelected(false); - notifyItemChanged(i + generalReasons.size()); - } - } - } - - if (getAdapterPosition() >= generalReasons.size()) { - rules.get(getAdapterPosition() - generalReasons.size()).setSelected(checkBox.isChecked()); - } else { - generalReasons.get(getAdapterPosition()).setSelected(checkBox.isChecked()); - } - }); - - itemView.setOnClickListener(view -> checkBox.performClick()); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/RulesRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/RulesRecyclerViewAdapter.java deleted file mode 100644 index 2b5e62df..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/RulesRecyclerViewAdapter.java +++ /dev/null @@ -1,118 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -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.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Rule; - -public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { - private Markwon markwon; - private ArrayList rules; - private int mPrimaryTextColor; - private int mSecondaryTextColor; - - public RulesRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper) { - markwon = Markwon.builder(context) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(context, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - context.startActivity(intent); - }); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(customThemeWrapper.getLinkColor()); - } - }) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .build(); - mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); - mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - } - - @NonNull - @Override - public RuleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new RuleViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rule, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RuleViewHolder holder, int position) { - holder.shortNameTextView.setText(rules.get(holder.getAdapterPosition()).getShortName()); - if (rules.get(holder.getAdapterPosition()).getDescriptionHtml() == null) { - holder.descriptionMarkwonView.setVisibility(View.GONE); - } else { - markwon.setMarkdown(holder.descriptionMarkwonView, rules.get(holder.getAdapterPosition()).getDescriptionHtml()); - } - } - - @Override - public int getItemCount() { - return rules == null ? 0 : rules.size(); - } - - @Override - public void onViewRecycled(@NonNull RuleViewHolder holder) { - super.onViewRecycled(holder); - holder.descriptionMarkwonView.setVisibility(View.VISIBLE); - } - - public void changeDataset(ArrayList rules) { - this.rules = rules; - notifyDataSetChanged(); - } - - class RuleViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.short_name_text_view_item_rule) - TextView shortNameTextView; - @BindView(R.id.description_markwon_view_item_rule) - TextView descriptionMarkwonView; - - RuleViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - shortNameTextView.setTextColor(mPrimaryTextColor); - descriptionMarkwonView.setTextColor(mSecondaryTextColor); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SearchActivityRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SearchActivityRecyclerViewAdapter.java deleted file mode 100644 index 75c22934..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SearchActivityRecyclerViewAdapter.java +++ /dev/null @@ -1,94 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.app.Activity; -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 ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RecentSearchQuery.RecentSearchQuery; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -public class SearchActivityRecyclerViewAdapter extends RecyclerView.Adapter { - private List recentSearchQueries; - private int primaryTextColor; - private Drawable historyIcon; - private Drawable deleteIcon; - private ItemOnClickListener itemOnClickListener; - - public interface ItemOnClickListener { - void onClick(String query); - void onDelete(RecentSearchQuery recentSearchQuery); - } - - public SearchActivityRecyclerViewAdapter(Activity activity, CustomThemeWrapper customThemeWrapper, - ItemOnClickListener itemOnClickListener) { - this.primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - this.historyIcon = Utils.getTintedDrawable(activity, R.drawable.ic_history_24dp, customThemeWrapper.getPrimaryIconColor()); - this.deleteIcon = Utils.getTintedDrawable(activity, R.drawable.ic_delete_24dp, customThemeWrapper.getPrimaryIconColor()); - this.itemOnClickListener = itemOnClickListener; - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new RecentSearchQueryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recent_search_query, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof RecentSearchQueryViewHolder) { - if (recentSearchQueries != null && !recentSearchQueries.isEmpty() && position < recentSearchQueries.size()) { - ((RecentSearchQueryViewHolder) holder).recentSearchQueryTextView.setText(recentSearchQueries.get(position).getSearchQuery()); - } - } - } - - @Override - public int getItemCount() { - return recentSearchQueries == null ? 0 : recentSearchQueries.size(); - } - - public void setRecentSearchQueries(List recentSearchQueries) { - this.recentSearchQueries = recentSearchQueries; - notifyDataSetChanged(); - } - - class RecentSearchQueryViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.recent_search_query_text_view_item_recent_search_query) - TextView recentSearchQueryTextView; - @BindView(R.id.delete_image_view_item_recent_search_query) - ImageView deleteImageView; - - public RecentSearchQueryViewHolder(@NonNull View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - - recentSearchQueryTextView.setTextColor(primaryTextColor); - recentSearchQueryTextView.setCompoundDrawablesWithIntrinsicBounds(historyIcon, null, null, null); - deleteImageView.setImageDrawable(deleteIcon); - - itemView.setOnClickListener(view -> { - if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) { - itemOnClickListener.onClick(recentSearchQueries.get(getAdapterPosition()).getSearchQuery()); - } - }); - - deleteImageView.setOnClickListener(view -> { - itemOnClickListener.onDelete(recentSearchQueries.get(getAdapterPosition())); - }); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SelectedSubredditsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SelectedSubredditsRecyclerViewAdapter.java deleted file mode 100644 index ce7c4812..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SelectedSubredditsRecyclerViewAdapter.java +++ /dev/null @@ -1,79 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -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.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; - -public class SelectedSubredditsRecyclerViewAdapter extends RecyclerView.Adapter { - private CustomThemeWrapper customThemeWrapper; - private ArrayList subreddits; - - public SelectedSubredditsRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList subreddits) { - this.customThemeWrapper = customThemeWrapper; - if (subreddits == null) { - this.subreddits = new ArrayList<>(); - } else { - this.subreddits = subreddits; - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new SubredditViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_selected_subreddit, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof SubredditViewHolder) { - ((SubredditViewHolder) holder).subredditNameTextView.setText(subreddits.get(holder.getAdapterPosition())); - ((SubredditViewHolder) holder).deleteButton.setOnClickListener(view -> { - subreddits.remove(holder.getAdapterPosition()); - notifyItemRemoved(holder.getAdapterPosition()); - }); - } - } - - @Override - public int getItemCount() { - return subreddits.size(); - } - - public void addSubreddits(ArrayList newSubreddits) { - int oldSize = subreddits.size(); - subreddits.addAll(newSubreddits); - notifyItemRangeInserted(oldSize, newSubreddits.size()); - } - - public ArrayList getSubreddits() { - return subreddits; - } - - class SubredditViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.subreddit_name_item_selected_subreddit) - TextView subredditNameTextView; - @BindView(R.id.delete_image_view_item_selected_subreddit) - ImageView deleteButton; - - public SubredditViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - subredditNameTextView.setTextColor(customThemeWrapper.getPrimaryIconColor()); - deleteButton.setColorFilter(customThemeWrapper.getPrimaryIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditFilterRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditFilterRecyclerViewAdapter.java deleted file mode 100644 index 28678b40..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditFilterRecyclerViewAdapter.java +++ /dev/null @@ -1,72 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -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 ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; - -public class SubredditFilterRecyclerViewAdapter extends RecyclerView.Adapter { - private List subredditFilters; - private ItemClickListener itemClickListener; - - public SubredditFilterRecyclerViewAdapter(ItemClickListener itemClickListener) { - this.itemClickListener = itemClickListener; - } - - public interface ItemClickListener { - void onItemDelete(SubredditFilter subredditFilter); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new SubredditNameViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_selected_subreddit, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof SubredditNameViewHolder) { - ((SubredditNameViewHolder) holder).subredditRedditNameTextView.setText(subredditFilters.get(position).getSubredditName()); - } - } - - @Override - public int getItemCount() { - return subredditFilters == null ? 0 : subredditFilters.size(); - } - - public void updateSubredditsName(List subredditFilters) { - this.subredditFilters = subredditFilters; - notifyDataSetChanged(); - } - - class SubredditNameViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.subreddit_name_item_selected_subreddit) - TextView subredditRedditNameTextView; - @BindView(R.id.delete_image_view_item_selected_subreddit) - ImageView deleteImageView; - - public SubredditNameViewHolder(@NonNull View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - - deleteImageView.setOnClickListener(view -> { - itemClickListener.onItemDelete(subredditFilters.get(getAdapterPosition())); - }); - } - } - -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditListingRecyclerViewAdapter.java deleted file mode 100644 index 964ecd5d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditListingRecyclerViewAdapter.java +++ /dev/null @@ -1,260 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.paging.PagedListAdapter; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.AsyncTask.CheckIsSubscribedToSubredditAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditSubscription; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class SubredditListingRecyclerViewAdapter extends PagedListAdapter { - private static final int VIEW_TYPE_DATA = 0; - private static final int VIEW_TYPE_ERROR = 1; - private static final int VIEW_TYPE_LOADING = 2; - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull SubredditData oldItem, @NonNull SubredditData newItem) { - return oldItem.getId().equals(newItem.getId()); - } - - @Override - public boolean areContentsTheSame(@NonNull SubredditData oldItem, @NonNull SubredditData newItem) { - return true; - } - }; - private RequestManager glide; - private Context context; - private Retrofit oauthRetrofit; - private Retrofit retrofit; - private String accessToken; - private String accountName; - private RedditDataRoomDatabase redditDataRoomDatabase; - private int colorPrimaryLightTheme; - private int primaryTextColor; - private int secondaryTextColor; - private int colorAccent; - private int buttonTextColor; - private int unsubscribed; - - private NetworkState networkState; - private Callback callback; - - public SubredditListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, Retrofit retrofit, - CustomThemeWrapper customThemeWrapper, - String accessToken, String accountName, - RedditDataRoomDatabase redditDataRoomDatabase, - Callback callback) { - super(DIFF_CALLBACK); - this.context = context; - this.oauthRetrofit = oauthRetrofit; - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.callback = callback; - glide = Glide.with(context); - colorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - colorAccent = customThemeWrapper.getColorAccent(); - buttonTextColor = customThemeWrapper.getButtonTextColor(); - unsubscribed = customThemeWrapper.getUnsubscribed(); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if (viewType == VIEW_TYPE_DATA) { - ConstraintLayout constraintLayout = (ConstraintLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_subreddit_listing, parent, false); - return new DataViewHolder(constraintLayout); - } else if (viewType == VIEW_TYPE_ERROR) { - RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false); - return new ErrorViewHolder(relativeLayout); - } else { - RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false); - return new LoadingViewHolder(relativeLayout); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof DataViewHolder) { - SubredditData subredditData = getItem(position); - ((DataViewHolder) holder).constraintLayout.setOnClickListener(view -> - callback.subredditSelected(subredditData.getName(), subredditData.getIconUrl())); - - if (!subredditData.getIconUrl().equals("")) { - glide.load(subredditData.getIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((DataViewHolder) holder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((DataViewHolder) holder).iconGifImageView); - } - - ((DataViewHolder) holder).subredditNameTextView.setText(subredditData.getName()); - - new CheckIsSubscribedToSubredditAsyncTask(redditDataRoomDatabase, subredditData.getName(), accountName, - new CheckIsSubscribedToSubredditAsyncTask.CheckIsSubscribedToSubredditListener() { - @Override - public void isSubscribed() { - ((DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); - } - - @Override - public void isNotSubscribed() { - ((DataViewHolder) holder).subscribeButton.setVisibility(View.VISIBLE); - ((DataViewHolder) holder).subscribeButton.setOnClickListener(view -> { - SubredditSubscription.subscribeToSubreddit(oauthRetrofit, retrofit, - accessToken, subredditData.getName(), accountName, redditDataRoomDatabase, - new SubredditSubscription.SubredditSubscriptionListener() { - @Override - public void onSubredditSubscriptionSuccess() { - ((DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); - Toast.makeText(context, R.string.subscribed, Toast.LENGTH_SHORT).show(); - } - - @Override - public void onSubredditSubscriptionFail() { - Toast.makeText(context, R.string.subscribe_failed, Toast.LENGTH_SHORT).show(); - } - }); - }); - } - }).execute(); - } - } - - @Override - public int getItemViewType(int position) { - // Reached at the end - if (hasExtraRow() && position == getItemCount() - 1) { - if (networkState.getStatus() == NetworkState.Status.LOADING) { - return VIEW_TYPE_LOADING; - } else { - return VIEW_TYPE_ERROR; - } - } else { - return VIEW_TYPE_DATA; - } - } - - @Override - public int getItemCount() { - if (hasExtraRow()) { - return super.getItemCount() + 1; - } - return super.getItemCount(); - } - - private boolean hasExtraRow() { - return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; - } - - public void setNetworkState(NetworkState newNetworkState) { - NetworkState previousState = this.networkState; - boolean previousExtraRow = hasExtraRow(); - this.networkState = newNetworkState; - boolean newExtraRow = hasExtraRow(); - if (previousExtraRow != newExtraRow) { - if (previousExtraRow) { - notifyItemRemoved(super.getItemCount()); - } else { - notifyItemInserted(super.getItemCount()); - } - } else if (newExtraRow && !previousState.equals(newNetworkState)) { - notifyItemChanged(getItemCount() - 1); - } - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if (holder instanceof DataViewHolder) { - glide.clear(((DataViewHolder) holder).iconGifImageView); - ((DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); - } - } - - public interface Callback { - void retryLoadingMore(); - - void subredditSelected(String subredditName, String iconUrl); - } - - class DataViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.constraint_layout_item_subreddit_listing) - ConstraintLayout constraintLayout; - @BindView(R.id.subreddit_icon_gif_image_view_item_subreddit_listing) - GifImageView iconGifImageView; - @BindView(R.id.subreddit_name_text_view_item_subreddit_listing) - TextView subredditNameTextView; - @BindView(R.id.subscribe_image_view_item_subreddit_listing) - ImageView subscribeButton; - - DataViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - subredditNameTextView.setTextColor(primaryTextColor); - subscribeButton.setColorFilter(unsubscribed, android.graphics.PorterDuff.Mode.SRC_IN); - } - } - - class ErrorViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_footer_error) - TextView errorTextView; - @BindView(R.id.retry_button_item_footer_error) - Button retryButton; - - ErrorViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - retryButton.setOnClickListener(view -> callback.retryLoadingMore()); - errorTextView.setText(R.string.load_comments_failed); - errorTextView.setTextColor(secondaryTextColor); - retryButton.setBackgroundTintList(ColorStateList.valueOf(colorPrimaryLightTheme)); - retryButton.setTextColor(buttonTextColor); - } - } - - class LoadingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_item_footer_loading) - ProgressBar progressBar; - - LoadingViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorAccent)); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditMultiselectionRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditMultiselectionRecyclerViewAdapter.java deleted file mode 100644 index 6c2d0b87..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubredditMultiselectionRecyclerViewAdapter.java +++ /dev/null @@ -1,123 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.CheckBox; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import java.util.ArrayList; -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditWithSelection; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import pl.droidsonroids.gif.GifImageView; - -public class SubredditMultiselectionRecyclerViewAdapter extends RecyclerView.Adapter { - - private ArrayList subscribedSubreddits; - private RequestManager glide; - private int primaryTextColor; - private int colorAccent; - - public SubredditMultiselectionRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper) { - glide = Glide.with(context); - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - colorAccent = customThemeWrapper.getColorAccent(); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new SubscribedSubredditViewHolder(LayoutInflater.from(parent.getContext()) - .inflate(R.layout.item_subscribed_subreddit_multi_selection, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof SubscribedSubredditViewHolder) { - ((SubscribedSubredditViewHolder) holder).nameTextView.setText(subscribedSubreddits.get(position).getName()); - glide.load(subscribedSubreddits.get(position).getIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((SubscribedSubredditViewHolder) holder).iconImageView); - if (subscribedSubreddits.get(position).isSelected()) { - ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(true); - } else { - ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(false); - } - ((SubscribedSubredditViewHolder) holder).checkBox.setOnClickListener(view -> { - if (subscribedSubreddits.get(position).isSelected()) { - ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(false); - subscribedSubreddits.get(position).setSelected(false); - } else { - ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(true); - subscribedSubreddits.get(position).setSelected(true); - } - }); - ((SubscribedSubredditViewHolder) holder).itemView.setOnClickListener(view -> - ((SubscribedSubredditViewHolder) holder).checkBox.performClick()); - } - } - - @Override - public int getItemCount() { - return subscribedSubreddits == null ? 0 : subscribedSubreddits.size(); - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - super.onViewRecycled(holder); - if (holder instanceof SubscribedSubredditViewHolder) { - glide.clear(((SubscribedSubredditViewHolder) holder).iconImageView); - } - } - - public void setSubscribedSubreddits(List subscribedSubreddits) { - this.subscribedSubreddits = SubredditWithSelection.convertSubscribedSubreddits(subscribedSubreddits); - notifyDataSetChanged(); - } - - public ArrayList getAllSelectedSubreddits() { - ArrayList selectedSubreddits = new ArrayList<>(); - for (SubredditWithSelection s : subscribedSubreddits) { - if (s.isSelected()) { - selectedSubreddits.add(s.getName()); - } - } - return selectedSubreddits; - } - - class SubscribedSubredditViewHolder extends RecyclerView.ViewHolder { - View itemView; - @BindView(R.id.icon_gif_image_view_item_subscribed_subreddit_multiselection) - GifImageView iconImageView; - @BindView(R.id.name_text_view_item_subscribed_subreddit_multiselection) - TextView nameTextView; - @BindView(R.id.checkbox_item_subscribed_subreddit_multiselection) - CheckBox checkBox; - - SubscribedSubredditViewHolder(@NonNull View itemView) { - super(itemView); - this.itemView = itemView; - ButterKnife.bind(this, itemView); - nameTextView.setTextColor(primaryTextColor); - checkBox.setButtonTintList(ColorStateList.valueOf(colorAccent)); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubscribedSubredditsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubscribedSubredditsRecyclerViewAdapter.java deleted file mode 100644 index 3e557594..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/SubscribedSubredditsRecyclerViewAdapter.java +++ /dev/null @@ -1,513 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import java.util.List; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import me.zhanghai.android.fastscroll.PopupTextProvider; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FavoriteThing; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class SubscribedSubredditsRecyclerViewAdapter extends RecyclerView.Adapter implements PopupTextProvider { - private static final int VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER = 0; - private static final int VIEW_TYPE_FAVORITE_SUBREDDIT = 1; - private static final int VIEW_TYPE_SUBREDDIT_DIVIDER = 2; - private static final int VIEW_TYPE_SUBREDDIT = 3; - - private Context mContext; - private Retrofit mOauthRetrofit; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private List mSubscribedSubredditData; - private List mFavoriteSubscribedSubredditData; - private RequestManager glide; - private ItemClickListener itemClickListener; - - private String accessToken; - private String username; - private String userIconUrl; - private boolean hasClearSelectionRow; - - private int primaryTextColor; - private int secondaryTextColor; - - public SubscribedSubredditsRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, - RedditDataRoomDatabase redditDataRoomDatabase, - CustomThemeWrapper customThemeWrapper, - String accessToken) { - mContext = context; - glide = Glide.with(context); - mOauthRetrofit = oauthRetrofit; - mRedditDataRoomDatabase = redditDataRoomDatabase; - this.accessToken = accessToken; - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - } - - public SubscribedSubredditsRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, - RedditDataRoomDatabase redditDataRoomDatabase, - CustomThemeWrapper customThemeWrapper, - String accessToken, boolean hasClearSelectionRow, - ItemClickListener itemClickListener) { - this(context, oauthRetrofit, redditDataRoomDatabase, customThemeWrapper, accessToken); - this.hasClearSelectionRow = hasClearSelectionRow; - this.itemClickListener = itemClickListener; - } - - @Override - public int getItemViewType(int position) { - if (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) { - if (itemClickListener != null && !hasClearSelectionRow) { - if (position == 0) { - return VIEW_TYPE_SUBREDDIT; - } else if (position == 1) { - return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; - } else if (position == mFavoriteSubscribedSubredditData.size() + 2) { - return VIEW_TYPE_SUBREDDIT_DIVIDER; - } else if (position <= mFavoriteSubscribedSubredditData.size() + 1) { - return VIEW_TYPE_FAVORITE_SUBREDDIT; - } else { - return VIEW_TYPE_SUBREDDIT; - } - } else if (hasClearSelectionRow) { - if (position == 0) { - return VIEW_TYPE_SUBREDDIT; - } else if (position == 1) { - return VIEW_TYPE_SUBREDDIT; - } else if (position == 2) { - return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; - } else if (position == mFavoriteSubscribedSubredditData.size() + 3) { - return VIEW_TYPE_SUBREDDIT_DIVIDER; - } else if (position <= mFavoriteSubscribedSubredditData.size() + 2) { - return VIEW_TYPE_FAVORITE_SUBREDDIT; - } else { - return VIEW_TYPE_SUBREDDIT; - } - } else { - if (position == 0) { - return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; - } else if (position == mFavoriteSubscribedSubredditData.size() + 1) { - return VIEW_TYPE_SUBREDDIT_DIVIDER; - } else if (position <= mFavoriteSubscribedSubredditData.size()) { - return VIEW_TYPE_FAVORITE_SUBREDDIT; - } else { - return VIEW_TYPE_SUBREDDIT; - } - } - } else { - return VIEW_TYPE_SUBREDDIT; - } - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { - switch (i) { - case VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER: - return new FavoriteSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); - case VIEW_TYPE_FAVORITE_SUBREDDIT: - return new FavoriteSubredditViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_subscribed_thing, viewGroup, false)); - case VIEW_TYPE_SUBREDDIT_DIVIDER: - return new AllSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); - default: - return new SubredditViewHolder(LayoutInflater.from(viewGroup.getContext()) - .inflate(R.layout.item_subscribed_thing, viewGroup, false)); - } - } - - @Override - public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) { - if (viewHolder instanceof SubredditViewHolder) { - String name; - String iconUrl; - - if (hasClearSelectionRow && viewHolder.getAdapterPosition() == 0) { - ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(R.string.all_subreddits); - ((SubredditViewHolder) viewHolder).favoriteImageView.setVisibility(View.GONE); - viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(null, null, false)); - return; - } else if (itemClickListener != null && !hasClearSelectionRow && viewHolder.getAdapterPosition() == 0) { - ((SubredditViewHolder) viewHolder).favoriteImageView.setVisibility(View.GONE); - name = username; - iconUrl = userIconUrl; - viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, true)); - } else if (hasClearSelectionRow && viewHolder.getAdapterPosition() == 1) { - ((SubredditViewHolder) viewHolder).favoriteImageView.setVisibility(View.GONE); - name = username; - iconUrl = userIconUrl; - if (itemClickListener != null) { - viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, true)); - } - } else { - int offset; - if (itemClickListener != null) { - if (hasClearSelectionRow) { - offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? - mFavoriteSubscribedSubredditData.size() + 4 : 0; - } else { - offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? - mFavoriteSubscribedSubredditData.size() + 3 : 0; - } - } else { - offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? - mFavoriteSubscribedSubredditData.size() + 2 : 0; - } - - name = mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getName(); - iconUrl = mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getIconUrl(); - if(mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } else { - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - ((SubredditViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { - if(mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(false); - FavoriteThing.unfavoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, - mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mSubscribedSubredditData.size() > position) { - mSubscribedSubredditData.get(position).setFavorite(false); - } - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mSubscribedSubredditData.size() > position) { - mSubscribedSubredditData.get(position).setFavorite(true); - } - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - }); - } else { - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(true); - FavoriteThing.favoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, - mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mSubscribedSubredditData.size() > position) { - mSubscribedSubredditData.get(position).setFavorite(true); - } - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - offset; - if(position >= 0 && mSubscribedSubredditData.size() > position) { - mSubscribedSubredditData.get(position).setFavorite(false); - } - ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - }); - } - }); - - if (itemClickListener != null) { - viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, false)); - } - } - - if (itemClickListener == null) { - viewHolder.itemView.setOnClickListener(view -> { - Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name); - mContext.startActivity(intent); - }); - } - - if (iconUrl != null && !iconUrl.equals("")) { - glide.load(iconUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((SubredditViewHolder) viewHolder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((SubredditViewHolder) viewHolder).iconGifImageView); - } - ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(name); - } else if (viewHolder instanceof FavoriteSubredditViewHolder) { - int offset; - if (itemClickListener != null) { - if (hasClearSelectionRow) { - offset = 3; - } else { - offset = 2; - } - } else { - offset = 1; - } - String name = mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getName(); - String iconUrl = mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getIconUrl(); - if(mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } else { - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { - if(mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(false); - FavoriteThing.unfavoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, - mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { - mFavoriteSubscribedSubredditData.get(position).setFavorite(false); - } - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { - mFavoriteSubscribedSubredditData.get(position).setFavorite(true); - } - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - }); - } else { - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(true); - FavoriteThing.favoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, - mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), - new FavoriteThing.FavoriteThingListener() { - @Override - public void success() { - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { - mFavoriteSubscribedSubredditData.get(position).setFavorite(true); - } - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); - } - - @Override - public void failed() { - Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); - int position = viewHolder.getAdapterPosition() - 1; - if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { - mFavoriteSubscribedSubredditData.get(position).setFavorite(false); - } - ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); - } - }); - } - }); - - if (itemClickListener != null) { - viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, false)); - } else { - viewHolder.itemView.setOnClickListener(view -> { - Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name); - mContext.startActivity(intent); - }); - } - - if (iconUrl != null && !iconUrl.equals("")) { - glide.load(iconUrl) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView); - } - ((FavoriteSubredditViewHolder) viewHolder).subredditNameTextView.setText(name); - } - } - - @Override - public int getItemCount() { - if (mSubscribedSubredditData != null) { - if(mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) { - if (itemClickListener != null) { - if (hasClearSelectionRow) { - return mSubscribedSubredditData.size() > 0 ? - mFavoriteSubscribedSubredditData.size() + mSubscribedSubredditData.size() + 4 : 0; - } else { - return mSubscribedSubredditData.size() > 0 ? - mFavoriteSubscribedSubredditData.size() + mSubscribedSubredditData.size() + 3 : 0; - } - } - return mSubscribedSubredditData.size() > 0 ? - mFavoriteSubscribedSubredditData.size() + mSubscribedSubredditData.size() + 2 : 0; - } - - return mSubscribedSubredditData.size(); - } - return 0; - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if(holder instanceof SubredditViewHolder) { - glide.clear(((SubredditViewHolder) holder).iconGifImageView); - ((SubredditViewHolder) holder).favoriteImageView.setVisibility(View.VISIBLE); - } else if (holder instanceof FavoriteSubredditViewHolder) { - glide.clear(((FavoriteSubredditViewHolder) holder).iconGifImageView); - } - } - - public void setSubscribedSubreddits(List subscribedSubreddits) { - mSubscribedSubredditData = subscribedSubreddits; - notifyDataSetChanged(); - } - - public void setFavoriteSubscribedSubreddits(List favoriteSubscribedSubredditData) { - mFavoriteSubscribedSubredditData = favoriteSubscribedSubredditData; - notifyDataSetChanged(); - } - - public void addUser(String username, String userIconUrl) { - this.username = username; - this.userIconUrl = userIconUrl; - } - - @NonNull - @Override - public String getPopupText(int position) { - switch (getItemViewType(position)) { - case VIEW_TYPE_SUBREDDIT: - if (hasClearSelectionRow && position == 0) { - return ""; - } else if (itemClickListener != null && !hasClearSelectionRow && position == 0) { - return ""; - } else if (hasClearSelectionRow && position == 1) { - return ""; - } else { - int offset; - if (itemClickListener != null) { - if (hasClearSelectionRow) { - offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? - mFavoriteSubscribedSubredditData.size() + 4 : 0; - } else { - offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? - mFavoriteSubscribedSubredditData.size() + 3 : 0; - } - } else { - offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? - mFavoriteSubscribedSubredditData.size() + 2 : 0; - } - - return mSubscribedSubredditData.get(position - offset).getName().substring(0, 1).toUpperCase(); - } - case VIEW_TYPE_FAVORITE_SUBREDDIT: - int offset; - if (itemClickListener != null) { - if (hasClearSelectionRow) { - offset = 3; - } else { - offset = 2; - } - } else { - offset = 1; - } - return mFavoriteSubscribedSubredditData.get(position - offset).getName().substring(0, 1).toUpperCase(); - default: - return ""; - } - } - - public interface ItemClickListener { - void onClick(String name, String iconUrl, boolean subredditIsUser); - } - - class SubredditViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) - GifImageView iconGifImageView; - @BindView(R.id.thing_name_text_view_item_subscribed_thing) - TextView subredditNameTextView; - @BindView(R.id.favorite_image_view_item_subscribed_thing) - ImageView favoriteImageView; - - SubredditViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - subredditNameTextView.setTextColor(primaryTextColor); - } - } - - class FavoriteSubredditViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) - GifImageView iconGifImageView; - @BindView(R.id.thing_name_text_view_item_subscribed_thing) - TextView subredditNameTextView; - @BindView(R.id.favorite_image_view_item_subscribed_thing) - ImageView favoriteImageView; - - FavoriteSubredditViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - subredditNameTextView.setTextColor(primaryTextColor); - } - } - - class FavoriteSubredditsDividerViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; - - FavoriteSubredditsDividerViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - dividerTextView.setText(R.string.favorites); - dividerTextView.setTextColor(secondaryTextColor); - } - } - - class AllSubredditsDividerViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; - - AllSubredditsDividerViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - dividerTextView.setText(R.string.all); - dividerTextView.setTextColor(secondaryTextColor); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/TranslationFragmentRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/TranslationFragmentRecyclerViewAdapter.java deleted file mode 100644 index a31381c5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/TranslationFragmentRecyclerViewAdapter.java +++ /dev/null @@ -1,82 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.app.Activity; -import android.content.Intent; -import android.net.Uri; -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.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Settings.Translation; - -public class TranslationFragmentRecyclerViewAdapter extends RecyclerView.Adapter { - private Activity activity; - private int primaryTextColor; - private int secondaryTextColor; - private ArrayList translationContributors; - - public TranslationFragmentRecyclerViewAdapter(Activity activity, CustomThemeWrapper customThemeWrapper) { - this.activity = activity; - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); - translationContributors = Translation.getTranslationContributors(); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new TranslationContributorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_translation_contributor, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof TranslationContributorViewHolder) { - Translation translation = translationContributors.get(position); - ((TranslationContributorViewHolder) holder).countryFlagImageView.setImageResource(translation.flagDrawableId); - ((TranslationContributorViewHolder) holder).languageNameTextView.setText(translation.language); - ((TranslationContributorViewHolder) holder).contributorNamesTextView.setText(translation.contributors); - } - } - - @Override - public int getItemCount() { - return translationContributors.size(); - } - - class TranslationContributorViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.country_flag_image_view_item_translation_contributor) - ImageView countryFlagImageView; - @BindView(R.id.language_name_text_view_item_translation_contributor) - TextView languageNameTextView; - @BindView(R.id.contributor_names_text_view_item_translation_contributor) - TextView contributorNamesTextView; - - public TranslationContributorViewHolder(@NonNull View itemView) { - super(itemView); - - ButterKnife.bind(this, itemView); - - languageNameTextView.setTextColor(primaryTextColor); - contributorNamesTextView.setTextColor(secondaryTextColor); - - itemView.setOnClickListener(view -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://poeditor.com/join/project?hash=b2IRyfaJv6")); - activity.startActivity(intent); - }); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java deleted file mode 100644 index a9ae4687..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java +++ /dev/null @@ -1,88 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -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.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.UserFlair; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -public class UserFlairRecyclerViewAdapter extends RecyclerView.Adapter { - private CustomThemeWrapper customThemeWrapper; - private ArrayList userFlairs; - private ItemClickListener itemClickListener; - - public UserFlairRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList userFlairs, - ItemClickListener itemClickListener) { - this.customThemeWrapper = customThemeWrapper; - this.userFlairs = userFlairs; - this.itemClickListener = itemClickListener; - } - - public interface ItemClickListener { - void onClick(UserFlair userFlair, boolean editUserFlair); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - return new UserFlairViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_flair, parent, false)); - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof UserFlairViewHolder) { - UserFlair userFlair = userFlairs.get(holder.getAdapterPosition()); - if (userFlair.getHtmlText() == null || userFlair.getHtmlText().equals("")) { - ((UserFlairViewHolder) holder).userFlairHtmlTextView.setText(userFlair.getText()); - } else { - Utils.setHTMLWithImageToTextView(((UserFlairViewHolder) holder).userFlairHtmlTextView, userFlair.getHtmlText(), true); - } - if (userFlair.isEditable()) { - ((UserFlairViewHolder) holder).editUserFlairImageView.setVisibility(View.VISIBLE); - } else { - ((UserFlairViewHolder) holder).editUserFlairImageView.setVisibility(View.GONE); - } - } - } - - @Override - public int getItemCount() { - return userFlairs == null ? 0 : userFlairs.size(); - } - - class UserFlairViewHolder extends RecyclerView.ViewHolder { - - @BindView(R.id.user_flair_html_text_view_item_user_flair) - TextView userFlairHtmlTextView; - @BindView(R.id.edit_user_flair_image_view_item_user_flair) - ImageView editUserFlairImageView; - - public UserFlairViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - - userFlairHtmlTextView.setTextColor(customThemeWrapper.getPrimaryTextColor()); - editUserFlairImageView.setColorFilter(customThemeWrapper.getPrimaryTextColor(), android.graphics.PorterDuff.Mode.SRC_IN); - - itemView.setOnClickListener(view -> { - itemClickListener.onClick(userFlairs.get(getAdapterPosition()), false); - }); - - editUserFlairImageView.setOnClickListener(view -> { - itemClickListener.onClick(userFlairs.get(getAdapterPosition()), true); - }); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserListingRecyclerViewAdapter.java deleted file mode 100644 index fad8c30a..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserListingRecyclerViewAdapter.java +++ /dev/null @@ -1,263 +0,0 @@ -package ml.docilealligator.infinityforreddit.Adapter; - -import android.content.Context; -import android.content.Intent; -import android.content.res.ColorStateList; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.paging.PagedListAdapter; -import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.RecyclerView; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.request.RequestOptions; - -import butterknife.BindView; -import butterknife.ButterKnife; -import jp.wasabeef.glide.transformations.RoundedCornersTransformation; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.AsyncTask.CheckIsFollowingUserAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserDao; -import ml.docilealligator.infinityforreddit.User.UserData; -import ml.docilealligator.infinityforreddit.User.UserFollowing; -import pl.droidsonroids.gif.GifImageView; -import retrofit2.Retrofit; - -public class UserListingRecyclerViewAdapter extends PagedListAdapter { - private static final int VIEW_TYPE_DATA = 0; - private static final int VIEW_TYPE_ERROR = 1; - private static final int VIEW_TYPE_LOADING = 2; - private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { - @Override - public boolean areItemsTheSame(@NonNull UserData oldItem, @NonNull UserData newItem) { - return oldItem.getName().equals(newItem.getName()); - } - - @Override - public boolean areContentsTheSame(@NonNull UserData oldItem, @NonNull UserData newItem) { - return true; - } - }; - private RequestManager glide; - private Context context; - private Retrofit oauthRetrofit; - private Retrofit retrofit; - private String accessToken; - private String accountName; - private SubscribedUserDao subscribedUserDao; - - private int primaryTextColor; - private int buttonTextColor; - private int colorPrimaryLightTheme; - private int colorAccent; - private int unsubscribedColor; - - private NetworkState networkState; - private UserListingRecyclerViewAdapter.RetryLoadingMoreCallback retryLoadingMoreCallback; - - public UserListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, Retrofit retrofit, - CustomThemeWrapper customThemeWrapper, String accessToken, - String accountName, SubscribedUserDao subscribedUserDao, - UserListingRecyclerViewAdapter.RetryLoadingMoreCallback retryLoadingMoreCallback) { - super(DIFF_CALLBACK); - this.context = context; - this.oauthRetrofit = oauthRetrofit; - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.subscribedUserDao = subscribedUserDao; - this.retryLoadingMoreCallback = retryLoadingMoreCallback; - glide = Glide.with(context); - primaryTextColor = customThemeWrapper.getPrimaryTextColor(); - buttonTextColor = customThemeWrapper.getButtonTextColor(); - colorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); - colorAccent = customThemeWrapper.getColorAccent(); - unsubscribedColor = customThemeWrapper.getUnsubscribed(); - } - - @NonNull - @Override - public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { - if (viewType == VIEW_TYPE_DATA) { - ConstraintLayout constraintLayout = (ConstraintLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_listing, parent, false); - return new UserListingRecyclerViewAdapter.DataViewHolder(constraintLayout); - } else if (viewType == VIEW_TYPE_ERROR) { - RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false); - return new UserListingRecyclerViewAdapter.ErrorViewHolder(relativeLayout); - } else { - RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false); - return new UserListingRecyclerViewAdapter.LoadingViewHolder(relativeLayout); - } - } - - @Override - public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { - if (holder instanceof UserListingRecyclerViewAdapter.DataViewHolder) { - UserData userData = getItem(position); - if (userData != null) { - ((UserListingRecyclerViewAdapter.DataViewHolder) holder).constraintLayout.setOnClickListener(view -> { - Intent intent = new Intent(context, ViewUserDetailActivity.class); - intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, userData.getName()); - context.startActivity(intent); - }); - - if (!userData.getIconUrl().equals("")) { - glide.load(userData.getIconUrl()) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .error(glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) - .into(((UserListingRecyclerViewAdapter.DataViewHolder) holder).iconGifImageView); - } else { - glide.load(R.drawable.subreddit_default_icon) - .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) - .into(((UserListingRecyclerViewAdapter.DataViewHolder) holder).iconGifImageView); - } - - ((UserListingRecyclerViewAdapter.DataViewHolder) holder).userNameTextView.setText(userData.getName()); - - new CheckIsFollowingUserAsyncTask(subscribedUserDao, userData.getName(), accountName, - new CheckIsFollowingUserAsyncTask.CheckIsFollowingUserListener() { - @Override - public void isSubscribed() { - ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); - } - - @Override - public void isNotSubscribed() { - ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.VISIBLE); - ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setOnClickListener(view -> { - UserFollowing.followUser(oauthRetrofit, retrofit, - accessToken, userData.getName(), accountName, subscribedUserDao, - new UserFollowing.UserFollowingListener() { - @Override - public void onUserFollowingSuccess() { - ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); - Toast.makeText(context, R.string.followed, Toast.LENGTH_SHORT).show(); - } - - @Override - public void onUserFollowingFail() { - Toast.makeText(context, R.string.follow_failed, Toast.LENGTH_SHORT).show(); - } - }); - }); - } - }).execute(); - } - } - } - - @Override - public int getItemViewType(int position) { - // Reached at the end - if (hasExtraRow() && position == getItemCount() - 1) { - if (networkState.getStatus() == NetworkState.Status.LOADING) { - return VIEW_TYPE_LOADING; - } else { - return VIEW_TYPE_ERROR; - } - } else { - return VIEW_TYPE_DATA; - } - } - - @Override - public int getItemCount() { - if (hasExtraRow()) { - return super.getItemCount() + 1; - } - return super.getItemCount(); - } - - private boolean hasExtraRow() { - return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; - } - - public void setNetworkState(NetworkState newNetworkState) { - NetworkState previousState = this.networkState; - boolean previousExtraRow = hasExtraRow(); - this.networkState = newNetworkState; - boolean newExtraRow = hasExtraRow(); - if (previousExtraRow != newExtraRow) { - if (previousExtraRow) { - notifyItemRemoved(super.getItemCount()); - } else { - notifyItemInserted(super.getItemCount()); - } - } else if (newExtraRow && !previousState.equals(newNetworkState)) { - notifyItemChanged(getItemCount() - 1); - } - } - - @Override - public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { - if (holder instanceof UserListingRecyclerViewAdapter.DataViewHolder) { - glide.clear(((UserListingRecyclerViewAdapter.DataViewHolder) holder).iconGifImageView); - ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); - } - } - - public interface RetryLoadingMoreCallback { - void retryLoadingMore(); - } - - class DataViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.constraint_layout_item_user_listing) - ConstraintLayout constraintLayout; - @BindView(R.id.user_icon_gif_image_view_item_user_listing) - GifImageView iconGifImageView; - @BindView(R.id.user_name_text_view_item_user_listing) - TextView userNameTextView; - @BindView(R.id.subscribe_image_view_item_user_listing) - ImageView subscribeButton; - - DataViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - userNameTextView.setTextColor(primaryTextColor); - subscribeButton.setColorFilter(unsubscribedColor, android.graphics.PorterDuff.Mode.SRC_IN); - } - } - - class ErrorViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.error_text_view_item_footer_error) - TextView errorTextView; - @BindView(R.id.retry_button_item_footer_error) - Button retryButton; - - ErrorViewHolder(View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - retryButton.setOnClickListener(view -> retryLoadingMoreCallback.retryLoadingMore()); - errorTextView.setText(R.string.load_comments_failed); - errorTextView.setTextColor(primaryTextColor); - retryButton.setTextColor(buttonTextColor); - retryButton.setBackgroundTintList(ColorStateList.valueOf(colorPrimaryLightTheme)); - } - } - - class LoadingViewHolder extends RecyclerView.ViewHolder { - @BindView(R.id.progress_bar_item_footer_loading) - ProgressBar progressBar; - - LoadingViewHolder(@NonNull View itemView) { - super(itemView); - ButterKnife.bind(this, itemView); - progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorAccent)); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index 8fc499cb..717a1e83 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -3,79 +3,79 @@ package ml.docilealligator.infinityforreddit; import javax.inject.Singleton; import dagger.Component; -import ml.docilealligator.infinityforreddit.Activity.AccountPostsActivity; -import ml.docilealligator.infinityforreddit.Activity.AccountSavedThingActivity; -import ml.docilealligator.infinityforreddit.Activity.CommentActivity; -import ml.docilealligator.infinityforreddit.Activity.FullMarkdownActivity; -import ml.docilealligator.infinityforreddit.Activity.CreateMultiRedditActivity; -import ml.docilealligator.infinityforreddit.Activity.CustomThemeListingActivity; -import ml.docilealligator.infinityforreddit.Activity.CustomThemePreviewActivity; -import ml.docilealligator.infinityforreddit.Activity.CustomizeThemeActivity; -import ml.docilealligator.infinityforreddit.Activity.EditCommentActivity; -import ml.docilealligator.infinityforreddit.Activity.EditMultiRedditActivity; -import ml.docilealligator.infinityforreddit.Activity.EditPostActivity; -import ml.docilealligator.infinityforreddit.Activity.FetchRandomSubredditOrPostActivity; -import ml.docilealligator.infinityforreddit.Activity.FilteredThingActivity; -import ml.docilealligator.infinityforreddit.Activity.GiveAwardActivity; -import ml.docilealligator.infinityforreddit.Activity.InboxActivity; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.Activity.LoginActivity; -import ml.docilealligator.infinityforreddit.Activity.MainActivity; -import ml.docilealligator.infinityforreddit.Activity.PostImageActivity; -import ml.docilealligator.infinityforreddit.Activity.PostLinkActivity; -import ml.docilealligator.infinityforreddit.Activity.PostTextActivity; -import ml.docilealligator.infinityforreddit.Activity.PostVideoActivity; -import ml.docilealligator.infinityforreddit.Activity.ReportActivity; -import ml.docilealligator.infinityforreddit.Activity.RulesActivity; -import ml.docilealligator.infinityforreddit.Activity.SearchActivity; -import ml.docilealligator.infinityforreddit.Activity.SearchResultActivity; -import ml.docilealligator.infinityforreddit.Activity.SearchSubredditsResultActivity; -import ml.docilealligator.infinityforreddit.Activity.SelectUserFlairActivity; -import ml.docilealligator.infinityforreddit.Activity.SelectedSubredditsActivity; -import ml.docilealligator.infinityforreddit.Activity.SendPrivateMessageActivity; -import ml.docilealligator.infinityforreddit.Activity.SettingsActivity; -import ml.docilealligator.infinityforreddit.Activity.SubmitCrosspostActivity; -import ml.docilealligator.infinityforreddit.Activity.SubredditFilterPopularAndAllActivity; -import ml.docilealligator.infinityforreddit.Activity.SubredditMultiselectionActivity; -import ml.docilealligator.infinityforreddit.Activity.SubredditSelectionActivity; -import ml.docilealligator.infinityforreddit.Activity.SubscribedThingListingActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewImageOrGifActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewImgurMediaActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewMultiRedditDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPostDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPrivateMessagesActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewRedditGalleryActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewVideoActivity; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.FlairBottomSheetFragment; -import ml.docilealligator.infinityforreddit.Fragment.CommentsListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.FollowedUsersListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.InboxFragment; -import ml.docilealligator.infinityforreddit.Fragment.MultiRedditListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.Fragment.SidebarFragment; -import ml.docilealligator.infinityforreddit.Fragment.SubredditListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.SubscribedSubredditsListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.UserListingFragment; -import ml.docilealligator.infinityforreddit.Fragment.ViewImgurVideoFragment; -import ml.docilealligator.infinityforreddit.Fragment.ViewRedditGalleryVideoFragment; -import ml.docilealligator.infinityforreddit.Service.DownloadMediaService; -import ml.docilealligator.infinityforreddit.Service.DownloadRedditVideoService; -import ml.docilealligator.infinityforreddit.Service.SubmitPostService; -import ml.docilealligator.infinityforreddit.Settings.AdvancedPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.CustomizeBottomAppBarFragment; -import ml.docilealligator.infinityforreddit.Settings.CustomizeMainPageTabsFragment; -import ml.docilealligator.infinityforreddit.Settings.DownloadLocationPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.GesturesAndButtonsPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.MainPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.MiscellaneousPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.NotificationPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.NsfwAndBlurringFragment; -import ml.docilealligator.infinityforreddit.Settings.SecurityPreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.ThemePreferenceFragment; -import ml.docilealligator.infinityforreddit.Settings.TranslationFragment; -import ml.docilealligator.infinityforreddit.Settings.VideoPreferenceFragment; +import ml.docilealligator.infinityforreddit.activities.AccountPostsActivity; +import ml.docilealligator.infinityforreddit.activities.AccountSavedThingActivity; +import ml.docilealligator.infinityforreddit.activities.CommentActivity; +import ml.docilealligator.infinityforreddit.activities.FullMarkdownActivity; +import ml.docilealligator.infinityforreddit.activities.CreateMultiRedditActivity; +import ml.docilealligator.infinityforreddit.activities.CustomThemeListingActivity; +import ml.docilealligator.infinityforreddit.activities.CustomThemePreviewActivity; +import ml.docilealligator.infinityforreddit.activities.CustomizeThemeActivity; +import ml.docilealligator.infinityforreddit.activities.EditCommentActivity; +import ml.docilealligator.infinityforreddit.activities.EditMultiRedditActivity; +import ml.docilealligator.infinityforreddit.activities.EditPostActivity; +import ml.docilealligator.infinityforreddit.activities.FetchRandomSubredditOrPostActivity; +import ml.docilealligator.infinityforreddit.activities.FilteredThingActivity; +import ml.docilealligator.infinityforreddit.activities.GiveAwardActivity; +import ml.docilealligator.infinityforreddit.activities.InboxActivity; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.LoginActivity; +import ml.docilealligator.infinityforreddit.activities.MainActivity; +import ml.docilealligator.infinityforreddit.activities.PostImageActivity; +import ml.docilealligator.infinityforreddit.activities.PostLinkActivity; +import ml.docilealligator.infinityforreddit.activities.PostTextActivity; +import ml.docilealligator.infinityforreddit.activities.PostVideoActivity; +import ml.docilealligator.infinityforreddit.activities.ReportActivity; +import ml.docilealligator.infinityforreddit.activities.RulesActivity; +import ml.docilealligator.infinityforreddit.activities.SearchActivity; +import ml.docilealligator.infinityforreddit.activities.SearchResultActivity; +import ml.docilealligator.infinityforreddit.activities.SearchSubredditsResultActivity; +import ml.docilealligator.infinityforreddit.activities.SelectUserFlairActivity; +import ml.docilealligator.infinityforreddit.activities.SelectedSubredditsActivity; +import ml.docilealligator.infinityforreddit.activities.SendPrivateMessageActivity; +import ml.docilealligator.infinityforreddit.activities.SettingsActivity; +import ml.docilealligator.infinityforreddit.activities.SubmitCrosspostActivity; +import ml.docilealligator.infinityforreddit.activities.SubredditFilterPopularAndAllActivity; +import ml.docilealligator.infinityforreddit.activities.SubredditMultiselectionActivity; +import ml.docilealligator.infinityforreddit.activities.SubredditSelectionActivity; +import ml.docilealligator.infinityforreddit.activities.SubscribedThingListingActivity; +import ml.docilealligator.infinityforreddit.activities.ViewImageOrGifActivity; +import ml.docilealligator.infinityforreddit.activities.ViewImgurMediaActivity; +import ml.docilealligator.infinityforreddit.activities.ViewMultiRedditDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPrivateMessagesActivity; +import ml.docilealligator.infinityforreddit.activities.ViewRedditGalleryActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewVideoActivity; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; +import ml.docilealligator.infinityforreddit.fragments.FollowedUsersListingFragment; +import ml.docilealligator.infinityforreddit.fragments.InboxFragment; +import ml.docilealligator.infinityforreddit.fragments.MultiRedditListingFragment; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.fragments.SidebarFragment; +import ml.docilealligator.infinityforreddit.fragments.SubredditListingFragment; +import ml.docilealligator.infinityforreddit.fragments.SubscribedSubredditsListingFragment; +import ml.docilealligator.infinityforreddit.fragments.UserListingFragment; +import ml.docilealligator.infinityforreddit.fragments.ViewImgurVideoFragment; +import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryVideoFragment; +import ml.docilealligator.infinityforreddit.services.DownloadMediaService; +import ml.docilealligator.infinityforreddit.services.DownloadRedditVideoService; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import ml.docilealligator.infinityforreddit.settings.AdvancedPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.CustomizeBottomAppBarFragment; +import ml.docilealligator.infinityforreddit.settings.CustomizeMainPageTabsFragment; +import ml.docilealligator.infinityforreddit.settings.DownloadLocationPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.GesturesAndButtonsPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.MainPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.MiscellaneousPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.NotificationPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.NsfwAndBlurringFragment; +import ml.docilealligator.infinityforreddit.settings.SecurityPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.ThemePreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.TranslationFragment; +import ml.docilealligator.infinityforreddit.settings.VideoPreferenceFragment; @Singleton @Component(modules = AppModule.class) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java index 18f4ac7d..8e483803 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppModule.java @@ -22,10 +22,10 @@ import im.ene.toro.exoplayer.Config; import im.ene.toro.exoplayer.ExoCreator; import im.ene.toro.exoplayer.MediaSourceBuilder; import im.ene.toro.exoplayer.ToroExo; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import okhttp3.ConnectionPool; import okhttp3.OkHttpClient; import retrofit2.Retrofit; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ChangeThemeNameAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ChangeThemeNameAsyncTask.java deleted file mode 100644 index 65fc3b8d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ChangeThemeNameAsyncTask.java +++ /dev/null @@ -1,23 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class ChangeThemeNameAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private String oldName; - private String newName; - - public ChangeThemeNameAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String oldName, String newName) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.oldName = oldName; - this.newName = newName; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.customThemeDao().updateName(oldName, newName); - return null; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsFollowingUserAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsFollowingUserAsyncTask.java deleted file mode 100644 index 418d0bbe..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsFollowingUserAsyncTask.java +++ /dev/null @@ -1,44 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserDao; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; - -public class CheckIsFollowingUserAsyncTask extends AsyncTask { - private SubscribedUserDao subscribedUserDao; - private String username; - private String accountName; - private SubscribedUserData subscribedUserData; - private CheckIsFollowingUserListener checkIsFollowingUserListener; - - public CheckIsFollowingUserAsyncTask(SubscribedUserDao subscribedUserDao, String username, String accountName, - CheckIsFollowingUserListener checkIsFollowingUserListener) { - this.subscribedUserDao = subscribedUserDao; - this.username = username; - this.accountName = accountName; - this.checkIsFollowingUserListener = checkIsFollowingUserListener; - } - - @Override - protected Void doInBackground(Void... voids) { - subscribedUserData = subscribedUserDao.getSubscribedUser(username, accountName); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (subscribedUserData != null) { - checkIsFollowingUserListener.isSubscribed(); - } else { - checkIsFollowingUserListener.isNotSubscribed(); - } - } - - public interface CheckIsFollowingUserListener { - void isSubscribed(); - - void isNotSubscribed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsSubscribedToSubredditAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsSubscribedToSubredditAsyncTask.java deleted file mode 100644 index a9388bf5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/CheckIsSubscribedToSubredditAsyncTask.java +++ /dev/null @@ -1,46 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; - -public class CheckIsSubscribedToSubredditAsyncTask extends AsyncTask { - - private RedditDataRoomDatabase redditDataRoomDatabase; - private String subredditName; - private String accountName; - private SubscribedSubredditData subscribedSubredditData; - private CheckIsSubscribedToSubredditListener checkIsSubscribedToSubredditListener; - - public CheckIsSubscribedToSubredditAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - String subredditName, String accountName, - CheckIsSubscribedToSubredditListener checkIsSubscribedToSubredditListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.subredditName = subredditName; - this.accountName = accountName; - this.checkIsSubscribedToSubredditListener = checkIsSubscribedToSubredditListener; - } - - @Override - protected Void doInBackground(Void... voids) { - subscribedSubredditData = redditDataRoomDatabase.subscribedSubredditDao().getSubscribedSubreddit(subredditName, accountName); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (subscribedSubredditData != null) { - checkIsSubscribedToSubredditListener.isSubscribed(); - } else { - checkIsSubscribedToSubredditListener.isNotSubscribed(); - } - } - - public interface CheckIsSubscribedToSubredditListener { - void isSubscribed(); - - void isNotSubscribed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllPostLayoutsAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllPostLayoutsAsyncTask.java deleted file mode 100644 index 8f844963..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllPostLayoutsAsyncTask.java +++ /dev/null @@ -1,57 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.content.SharedPreferences; -import android.os.AsyncTask; - -import java.util.Map; - -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class DeleteAllPostLayoutsAsyncTask extends AsyncTask { - - private SharedPreferences defaultSharedPreferences; - private SharedPreferences postLayoutSharedPreferences; - private DeleteAllPostLayoutsAsyncTaskListener deleteAllPostLayoutsAsyncTaskListener; - - public interface DeleteAllPostLayoutsAsyncTaskListener { - void success(); - } - - public DeleteAllPostLayoutsAsyncTask(SharedPreferences defaultSharedPreferences, - SharedPreferences postLayoutSharedPreferences, - DeleteAllPostLayoutsAsyncTaskListener deleteAllPostLayoutsAsyncTaskListener) { - this.defaultSharedPreferences = defaultSharedPreferences; - this.postLayoutSharedPreferences = postLayoutSharedPreferences; - this.deleteAllPostLayoutsAsyncTaskListener = deleteAllPostLayoutsAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - Map keys = defaultSharedPreferences.getAll(); - SharedPreferences.Editor editor = defaultSharedPreferences.edit(); - - for(Map.Entry entry : keys.entrySet()){ - String key = entry.getKey(); - if (key.startsWith(SharedPreferencesUtils.POST_LAYOUT_SHARED_PREFERENCES_FILE) - || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST) - || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST_LEGACY) - || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_ALL_POST_LEGACY) - || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE) - || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE) - || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE) - || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST)) { - editor.remove(key); - } - } - editor.apply(); - - postLayoutSharedPreferences.edit().clear().apply(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteAllPostLayoutsAsyncTaskListener.success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSortTypesAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSortTypesAsyncTask.java deleted file mode 100644 index 2e76b6c3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSortTypesAsyncTask.java +++ /dev/null @@ -1,58 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.content.SharedPreferences; -import android.os.AsyncTask; - -import java.util.Map; - -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class DeleteAllSortTypesAsyncTask extends AsyncTask { - private SharedPreferences defaultSharedPreferences; - private SharedPreferences sortTypeSharedPreferences; - private DeleteAllSortTypesAsyncTaskListener deleteAllSortTypesAsyncTaskListener; - - public interface DeleteAllSortTypesAsyncTaskListener { - void success(); - } - - public DeleteAllSortTypesAsyncTask(SharedPreferences defaultSharedPreferences, - SharedPreferences sortTypeSharedPreferences, - DeleteAllSortTypesAsyncTaskListener deleteAllSortTypesAsyncTaskListener) { - this.defaultSharedPreferences = defaultSharedPreferences; - this.sortTypeSharedPreferences = sortTypeSharedPreferences; - this.deleteAllSortTypesAsyncTaskListener = deleteAllSortTypesAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - Map keys = defaultSharedPreferences.getAll(); - SharedPreferences.Editor editor = defaultSharedPreferences.edit(); - - for(Map.Entry entry : keys.entrySet()){ - String key = entry.getKey(); - if (key.contains(SharedPreferencesUtils.SORT_TYPE_BEST_POST) || key.contains(SharedPreferencesUtils.SORT_TIME_BEST_POST) - || key.contains(SharedPreferencesUtils.SORT_TYPE_ALL_POST_LEGACY) || key.contains(SharedPreferencesUtils.SORT_TIME_ALL_POST_LEGACY) - || key.contains(SharedPreferencesUtils.SORT_TYPE_POPULAR_POST_LEGACY) || key.contains(SharedPreferencesUtils.SORT_TIME_POPULAR_POST_LEGACY) - || key.contains(SharedPreferencesUtils.SORT_TYPE_SEARCH_POST) || key.contains(SharedPreferencesUtils.SORT_TIME_SEARCH_POST) - || key.contains(SharedPreferencesUtils.SORT_TYPE_SUBREDDIT_POST_BASE) || key.contains(SharedPreferencesUtils.SORT_TIME_SUBREDDIT_POST_BASE) - || key.contains(SharedPreferencesUtils.SORT_TYPE_MULTI_REDDIT_POST_BASE) || key.contains(SharedPreferencesUtils.SORT_TIME_MULTI_REDDIT_POST_BASE) - || key.contains(SharedPreferencesUtils.SORT_TYPE_USER_POST_BASE) || key.contains(SharedPreferencesUtils.SORT_TIME_USER_POST_BASE) - || key.contains(SharedPreferencesUtils.SORT_TYPE_USER_COMMENT) || key.contains(SharedPreferencesUtils.SORT_TIME_USER_COMMENT) - || key.contains(SharedPreferencesUtils.SORT_TYPE_SEARCH_SUBREDDIT) || key.contains(SharedPreferencesUtils.SORT_TYPE_SEARCH_USER) - || key.contains(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT)) { - editor.remove(key); - } - } - editor.apply(); - - sortTypeSharedPreferences.edit().clear().apply(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteAllSortTypesAsyncTaskListener.success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSubredditsAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSubredditsAsyncTask.java deleted file mode 100644 index db39f9c1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllSubredditsAsyncTask.java +++ /dev/null @@ -1,33 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class DeleteAllSubredditsAsyncTask extends AsyncTask { - - private RedditDataRoomDatabase redditDataRoomDatabase; - private DeleteAllSubredditsAsyncTaskListener deleteAllSubredditsAsyncTaskListener; - - public interface DeleteAllSubredditsAsyncTaskListener { - void success(); - } - - public DeleteAllSubredditsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - DeleteAllSubredditsAsyncTaskListener deleteAllSubredditsAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.deleteAllSubredditsAsyncTaskListener = deleteAllSubredditsAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.subredditDao().deleteAllSubreddits(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteAllSubredditsAsyncTaskListener.success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllThemesAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllThemesAsyncTask.java deleted file mode 100644 index 0859fefd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllThemesAsyncTask.java +++ /dev/null @@ -1,45 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.content.SharedPreferences; -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class DeleteAllThemesAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private SharedPreferences lightThemeSharedPreferences; - private SharedPreferences darkThemeSharedPreferences; - private SharedPreferences amoledThemeSharedPreferences; - private DeleteAllThemesAsyncTaskListener deleteAllThemesAsyncTaskListener; - - public interface DeleteAllThemesAsyncTaskListener { - void success(); - } - - public DeleteAllThemesAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - SharedPreferences lightThemeSharedPreferences, - SharedPreferences darkThemeSharedPreferences, - SharedPreferences amoledThemeSharedPreferences, - DeleteAllThemesAsyncTaskListener deleteAllThemesAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.lightThemeSharedPreferences = lightThemeSharedPreferences; - this.darkThemeSharedPreferences = darkThemeSharedPreferences; - this.amoledThemeSharedPreferences = amoledThemeSharedPreferences; - this.deleteAllThemesAsyncTaskListener = deleteAllThemesAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.customThemeDao().deleteAllCustomThemes(); - lightThemeSharedPreferences.edit().clear().apply(); - darkThemeSharedPreferences.edit().clear().apply(); - amoledThemeSharedPreferences.edit().clear().apply(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteAllThemesAsyncTaskListener.success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllUsersAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllUsersAsyncTask.java deleted file mode 100644 index d73f749c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteAllUsersAsyncTask.java +++ /dev/null @@ -1,33 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class DeleteAllUsersAsyncTask extends AsyncTask { - - private RedditDataRoomDatabase redditDataRoomDatabase; - private DeleteAllUsersAsyncTaskListener deleteAllUsersAsyncTaskListener; - - public interface DeleteAllUsersAsyncTaskListener { - void success(); - } - - public DeleteAllUsersAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - DeleteAllUsersAsyncTaskListener deleteAllUsersAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.deleteAllUsersAsyncTaskListener = deleteAllUsersAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.userDao().deleteAllUsers(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteAllUsersAsyncTaskListener.success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteMultiredditInDatabaseAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteMultiredditInDatabaseAsyncTask.java deleted file mode 100644 index 14805c9c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteMultiredditInDatabaseAsyncTask.java +++ /dev/null @@ -1,37 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class DeleteMultiredditInDatabaseAsyncTask extends AsyncTask { - public interface DeleteMultiredditInDatabaseAsyncTaskListener { - void success(); - } - - private RedditDataRoomDatabase redditDataRoomDatabase; - private String accountName; - private String multipath; - private DeleteMultiredditInDatabaseAsyncTaskListener deleteMultiredditInDatabaseAsyncTaskListener; - - public DeleteMultiredditInDatabaseAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - String accountName, String multipath, - DeleteMultiredditInDatabaseAsyncTaskListener deleteMultiredditInDatabaseAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.accountName = accountName; - this.multipath = multipath; - this.deleteMultiredditInDatabaseAsyncTaskListener = deleteMultiredditInDatabaseAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.multiRedditDao().deleteMultiReddit(multipath, accountName); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteMultiredditInDatabaseAsyncTaskListener.success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteThemeAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteThemeAsyncTask.java deleted file mode 100644 index c166087c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/DeleteThemeAsyncTask.java +++ /dev/null @@ -1,44 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class DeleteThemeAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private String themeName; - private DeleteThemeAsyncTaskListener deleteThemeAsyncTaskListener; - private boolean isLightTheme = false; - private boolean isDarkTheme = false; - private boolean isAmoledTheme = false; - - public interface DeleteThemeAsyncTaskListener { - void success(boolean isLightTheme, boolean isDarkTheme, boolean isAmoledTheme); - } - - public DeleteThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String themeName, - DeleteThemeAsyncTaskListener deleteThemeAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.themeName = themeName; - this.deleteThemeAsyncTaskListener = deleteThemeAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - CustomTheme customTheme = redditDataRoomDatabase.customThemeDao().getCustomTheme(themeName); - if (customTheme != null) { - isLightTheme = customTheme.isLightTheme; - isDarkTheme = customTheme.isDarkTheme; - isAmoledTheme = customTheme.isAmoledTheme; - redditDataRoomDatabase.customThemeDao().deleteCustomTheme(themeName); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteThemeAsyncTaskListener.success(isLightTheme, isDarkTheme, isAmoledTheme); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCurrentAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCurrentAccountAsyncTask.java deleted file mode 100644 index 38d67e02..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCurrentAccountAsyncTask.java +++ /dev/null @@ -1,33 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.Account.Account; -import ml.docilealligator.infinityforreddit.Account.AccountDao; - -public class GetCurrentAccountAsyncTask extends AsyncTask { - - private Account account; - private AccountDao accountDao; - private GetCurrentAccountAsyncTaskListener getCurrentAccountAsyncTaskListener; - - public GetCurrentAccountAsyncTask(AccountDao accountDao, GetCurrentAccountAsyncTaskListener getCurrentAccountAsyncTaskListener) { - this.accountDao = accountDao; - this.getCurrentAccountAsyncTaskListener = getCurrentAccountAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - account = accountDao.getCurrentAccount(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - getCurrentAccountAsyncTaskListener.success(account); - } - - public interface GetCurrentAccountAsyncTaskListener { - void success(Account account); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCustomThemeAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCustomThemeAsyncTask.java deleted file mode 100644 index ffc8771e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/GetCustomThemeAsyncTask.java +++ /dev/null @@ -1,60 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; - -public class GetCustomThemeAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private String customThemeName; - private int themeType; - private GetCustomThemeAsyncTaskListener getCustomThemeAsyncTaskListener; - private CustomTheme customTheme; - - public interface GetCustomThemeAsyncTaskListener { - void success(CustomTheme customTheme); - } - - public GetCustomThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - String customThemeName, - GetCustomThemeAsyncTaskListener getCustomThemeAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.customThemeName = customThemeName; - this.getCustomThemeAsyncTaskListener = getCustomThemeAsyncTaskListener; - } - - public GetCustomThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - int themeType, - GetCustomThemeAsyncTaskListener getCustomThemeAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.themeType = themeType; - this.getCustomThemeAsyncTaskListener = getCustomThemeAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - if (customThemeName != null) { - customTheme = redditDataRoomDatabase.customThemeDao().getCustomTheme(customThemeName); - } else { - switch (themeType) { - case CustomThemeSharedPreferencesUtils.DARK: - customTheme = redditDataRoomDatabase.customThemeDao().getDarkCustomTheme(); - break; - case CustomThemeSharedPreferencesUtils.AMOLED: - customTheme = redditDataRoomDatabase.customThemeDao().getAmoledCustomTheme(); - break; - default: - customTheme = redditDataRoomDatabase.customThemeDao().getLightCustomTheme(); - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - getCustomThemeAsyncTaskListener.success(customTheme); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertCustomThemeAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertCustomThemeAsyncTask.java deleted file mode 100644 index 86a0f43b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertCustomThemeAsyncTask.java +++ /dev/null @@ -1,80 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.content.SharedPreferences; -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; - -public class InsertCustomThemeAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private SharedPreferences lightThemeSharedPreferences; - private SharedPreferences darkThemeSharedPreferences; - private SharedPreferences amoledThemeSharedPreferences; - private CustomTheme customTheme; - private boolean checkDuplicate; - private InsertCustomThemeAsyncTaskListener insertCustomThemeAsyncTaskListener; - private boolean isDuplicate = false; - - public interface InsertCustomThemeAsyncTaskListener { - void success(); - default void duplicate() {} - } - - public InsertCustomThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - SharedPreferences lightThemeSharedPreferences, - SharedPreferences darkThemeSharedPreferences, - SharedPreferences amoledThemeSharedPreferences, - CustomTheme customTheme, boolean checkDuplicate, - InsertCustomThemeAsyncTaskListener insertCustomThemeAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.lightThemeSharedPreferences = lightThemeSharedPreferences; - this.darkThemeSharedPreferences = darkThemeSharedPreferences; - this.amoledThemeSharedPreferences = amoledThemeSharedPreferences; - this.customTheme = customTheme; - this.checkDuplicate = checkDuplicate; - this.insertCustomThemeAsyncTaskListener = insertCustomThemeAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - if (checkDuplicate) { - if (redditDataRoomDatabase.customThemeDao().getCustomTheme(customTheme.name) != null) { - isDuplicate = true; - return null; - } - } - CustomTheme previousTheme = redditDataRoomDatabase.customThemeDao().getCustomTheme(customTheme.name); - if (customTheme.isLightTheme) { - redditDataRoomDatabase.customThemeDao().unsetLightTheme(); - CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(customTheme, lightThemeSharedPreferences); - } else if (previousTheme != null && previousTheme.isLightTheme) { - lightThemeSharedPreferences.edit().clear().apply(); - } - if (customTheme.isDarkTheme) { - redditDataRoomDatabase.customThemeDao().unsetDarkTheme(); - CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(customTheme, darkThemeSharedPreferences); - } else if (previousTheme != null && previousTheme.isDarkTheme) { - darkThemeSharedPreferences.edit().clear().apply(); - } - if (customTheme.isAmoledTheme) { - redditDataRoomDatabase.customThemeDao().unsetAmoledTheme(); - CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(customTheme, amoledThemeSharedPreferences); - } else if (previousTheme != null && previousTheme.isAmoledTheme) { - amoledThemeSharedPreferences.edit().clear().apply(); - } - redditDataRoomDatabase.customThemeDao().insert(customTheme); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (isDuplicate) { - insertCustomThemeAsyncTaskListener.duplicate(); - } else { - insertCustomThemeAsyncTaskListener.success(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertMultiRedditAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertMultiRedditAsyncTask.java deleted file mode 100644 index 2c49eccb..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertMultiRedditAsyncTask.java +++ /dev/null @@ -1,94 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import ml.docilealligator.infinityforreddit.MultiReddit.MultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiRedditDao; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class InsertMultiRedditAsyncTask extends AsyncTask { - private MultiRedditDao multiRedditDao; - private ArrayList multiReddits; - private MultiReddit multiReddit; - private String accountName; - private InsertMultiRedditAsyncTaskListener insertMultiRedditAsyncTaskListener; - - public InsertMultiRedditAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - ArrayList multiReddits, String accountName, - InsertMultiRedditAsyncTaskListener insertMultiRedditAsyncTaskListener) { - multiRedditDao = redditDataRoomDatabase.multiRedditDao(); - this.multiReddits = multiReddits; - this.accountName = accountName; - this.insertMultiRedditAsyncTaskListener = insertMultiRedditAsyncTaskListener; - } - - public InsertMultiRedditAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - MultiReddit multiReddit, - InsertMultiRedditAsyncTaskListener insertMultiRedditAsyncTaskListener) { - multiRedditDao = redditDataRoomDatabase.multiRedditDao(); - this.multiReddit = multiReddit; - this.insertMultiRedditAsyncTaskListener = insertMultiRedditAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - if (multiReddit != null) { - multiRedditDao.insert(multiReddit); - return null; - } - - List existingMultiReddits = multiRedditDao.getAllMultiRedditsList(accountName); - Collections.sort(multiReddits, (multiReddit, t1) -> multiReddit.getName().compareToIgnoreCase(t1.getName())); - List deletedMultiredditNames = new ArrayList<>(); - compareTwoMultiRedditList(multiReddits, existingMultiReddits, deletedMultiredditNames); - - for (String deleted : deletedMultiredditNames) { - multiRedditDao.deleteMultiReddit(deleted, accountName); - } - - for (MultiReddit multiReddit : multiReddits) { - multiRedditDao.insert(multiReddit); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - insertMultiRedditAsyncTaskListener.success(); - } - - private void compareTwoMultiRedditList(List newMultiReddits, - List oldMultiReddits, - List deletedMultiReddits) { - int newIndex = 0; - for (int oldIndex = 0; oldIndex < oldMultiReddits.size(); oldIndex++) { - if (newIndex >= newMultiReddits.size()) { - for (; oldIndex < oldMultiReddits.size(); oldIndex++) { - deletedMultiReddits.add(oldMultiReddits.get(oldIndex).getName()); - } - return; - } - - MultiReddit old = oldMultiReddits.get(oldIndex); - for (; newIndex < newMultiReddits.size(); newIndex++) { - if (newMultiReddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) == 0) { - newIndex++; - break; - } - if (newMultiReddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) > 0) { - deletedMultiReddits.add(old.getName()); - break; - } - } - } - } - - public interface InsertMultiRedditAsyncTaskListener { - void success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubredditDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubredditDataAsyncTask.java deleted file mode 100644 index 7b3e40f9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubredditDataAsyncTask.java +++ /dev/null @@ -1,35 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditDao; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; - -public class InsertSubredditDataAsyncTask extends AsyncTask { - private SubredditDao mSubredditDao; - private SubredditData subredditData; - private InsertSubredditDataAsyncTaskListener insertSubredditDataAsyncTaskListener; - - public InsertSubredditDataAsyncTask(RedditDataRoomDatabase db, SubredditData subredditData, - InsertSubredditDataAsyncTaskListener insertSubredditDataAsyncTaskListener) { - mSubredditDao = db.subredditDao(); - this.subredditData = subredditData; - this.insertSubredditDataAsyncTaskListener = insertSubredditDataAsyncTaskListener; - } - - @Override - protected Void doInBackground(final Void... params) { - mSubredditDao.insert(subredditData); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - insertSubredditDataAsyncTaskListener.insertSuccess(); - } - - public interface InsertSubredditDataAsyncTaskListener { - void insertSuccess(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubscribedThingsAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubscribedThingsAsyncTask.java deleted file mode 100644 index 0a73135e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertSubscribedThingsAsyncTask.java +++ /dev/null @@ -1,184 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import androidx.annotation.Nullable; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditDao; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditDao; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserDao; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; - -public class InsertSubscribedThingsAsyncTask extends AsyncTask { - - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private String mAccountName; - private SubscribedSubredditDao mSubscribedSubredditDao; - private SubscribedUserDao mSubscribedUserDao; - private SubredditDao mSubredditDao; - private SubscribedSubredditData mSingleSubscribedSubredditData; - private SubscribedUserData mSingleSubscribedUserData; - private List subscribedSubredditDataList; - private List subscribedUserDataList; - private List subredditDataList; - private InsertSubscribedThingListener mInsertSubscribedThingListener; - - public InsertSubscribedThingsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, @Nullable String accountName, - List subscribedSubredditDataList, - List subscribedUserDataList, - List subredditDataList, - InsertSubscribedThingListener insertSubscribedThingListener) { - mRedditDataRoomDatabase = redditDataRoomDatabase; - mAccountName = accountName; - mSubscribedSubredditDao = redditDataRoomDatabase.subscribedSubredditDao(); - mSubscribedUserDao = redditDataRoomDatabase.subscribedUserDao(); - mSubredditDao = redditDataRoomDatabase.subredditDao(); - - this.subscribedSubredditDataList = subscribedSubredditDataList; - this.subscribedUserDataList = subscribedUserDataList; - this.subredditDataList = subredditDataList; - mInsertSubscribedThingListener = insertSubscribedThingListener; - } - - public InsertSubscribedThingsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - SubscribedSubredditData subscribedSubredditDataList, - InsertSubscribedThingListener insertSubscribedThingListener) { - mRedditDataRoomDatabase = redditDataRoomDatabase; - mSubscribedSubredditDao = redditDataRoomDatabase.subscribedSubredditDao(); - mAccountName = subscribedSubredditDataList.getUsername(); - mSingleSubscribedSubredditData = subscribedSubredditDataList; - mInsertSubscribedThingListener = insertSubscribedThingListener; - } - - public InsertSubscribedThingsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - SubscribedUserData subscribedUserDataList, - InsertSubscribedThingListener insertSubscribedThingListener) { - mRedditDataRoomDatabase = redditDataRoomDatabase; - mSubscribedUserDao = redditDataRoomDatabase.subscribedUserDao(); - mAccountName = subscribedUserDataList.getUsername(); - mSingleSubscribedUserData = subscribedUserDataList; - mInsertSubscribedThingListener = insertSubscribedThingListener; - } - - @Override - protected Void doInBackground(final Void... params) { - if (mAccountName != null && mRedditDataRoomDatabase.accountDao().getAccountData(mAccountName) == null) { - return null; - } - - if (mSingleSubscribedSubredditData != null) { - mSubscribedSubredditDao.insert(mSingleSubscribedSubredditData); - } else if (mSingleSubscribedUserData != null) { - mSubscribedUserDao.insert(mSingleSubscribedUserData); - } else { - if (subscribedSubredditDataList != null) { - List existingSubscribedSubredditDataList = - mSubscribedSubredditDao.getAllSubscribedSubredditsList(mAccountName); - Collections.sort(subscribedSubredditDataList, (subscribedSubredditData, t1) -> subscribedSubredditData.getName().compareToIgnoreCase(t1.getName())); - List unsubscribedSubreddits = new ArrayList<>(); - compareTwoSubscribedSubredditList(subscribedSubredditDataList, existingSubscribedSubredditDataList, - unsubscribedSubreddits); - - for (String unsubscribed : unsubscribedSubreddits) { - mSubscribedSubredditDao.deleteSubscribedSubreddit(unsubscribed, mAccountName); - } - - for (SubscribedSubredditData s : subscribedSubredditDataList) { - mSubscribedSubredditDao.insert(s); - } - } - - if (subscribedUserDataList != null) { - List existingSubscribedUserDataList = - mSubscribedUserDao.getAllSubscribedUsersList(mAccountName); - Collections.sort(subscribedUserDataList, (subscribedUserData, t1) -> subscribedUserData.getName().compareToIgnoreCase(t1.getName())); - List unsubscribedUsers = new ArrayList<>(); - compareTwoSubscribedUserList(subscribedUserDataList, existingSubscribedUserDataList, - unsubscribedUsers); - - for (String unsubscribed : unsubscribedUsers) { - mSubscribedUserDao.deleteSubscribedUser(unsubscribed, mAccountName); - } - - for (SubscribedUserData s : subscribedUserDataList) { - mSubscribedUserDao.insert(s); - } - } - - if (subredditDataList != null) { - for (SubredditData s : subredditDataList) { - mSubredditDao.insert(s); - } - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - mInsertSubscribedThingListener.insertSuccess(); - } - - private void compareTwoSubscribedSubredditList(List newSubscribedSubreddits, - List oldSubscribedSubreddits, - List unsubscribedSubredditNames) { - int newIndex = 0; - for (int oldIndex = 0; oldIndex < oldSubscribedSubreddits.size(); oldIndex++) { - if (newIndex >= newSubscribedSubreddits.size()) { - for (; oldIndex < oldSubscribedSubreddits.size(); oldIndex++) { - unsubscribedSubredditNames.add(oldSubscribedSubreddits.get(oldIndex).getName()); - } - return; - } - - SubscribedSubredditData old = oldSubscribedSubreddits.get(oldIndex); - for (; newIndex < newSubscribedSubreddits.size(); newIndex++) { - if (newSubscribedSubreddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) == 0) { - newIndex++; - break; - } - if (newSubscribedSubreddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) > 0) { - unsubscribedSubredditNames.add(old.getName()); - break; - } - } - } - } - - private void compareTwoSubscribedUserList(List newSubscribedUsers, - List oldSubscribedUsers, - List unsubscribedUserNames) { - int newIndex = 0; - for (int oldIndex = 0; oldIndex < oldSubscribedUsers.size(); oldIndex++) { - if (newIndex >= newSubscribedUsers.size()) { - for (; oldIndex < oldSubscribedUsers.size(); oldIndex++) { - unsubscribedUserNames.add(oldSubscribedUsers.get(oldIndex).getName()); - } - return; - } - - SubscribedUserData old = oldSubscribedUsers.get(oldIndex); - for (; newIndex < newSubscribedUsers.size(); newIndex++) { - if (newSubscribedUsers.get(newIndex).getName().compareToIgnoreCase(old.getName()) == 0) { - newIndex++; - break; - } - if (newSubscribedUsers.get(newIndex).getName().compareToIgnoreCase(old.getName()) > 0) { - unsubscribedUserNames.add(old.getName()); - break; - } - } - } - } - - public interface InsertSubscribedThingListener { - void insertSuccess(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertUserDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertUserDataAsyncTask.java deleted file mode 100644 index ea12b546..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/InsertUserDataAsyncTask.java +++ /dev/null @@ -1,36 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.User.UserDao; -import ml.docilealligator.infinityforreddit.User.UserData; - -public class InsertUserDataAsyncTask extends AsyncTask { - private UserDao userDao; - private UserData userData; - private InsertUserDataCallback insertUserDataCallback; - - public InsertUserDataAsyncTask(UserDao userDao, UserData userData, InsertUserDataCallback insertUserDataCallback) { - this.userDao = userDao; - this.userData = userData; - this.insertUserDataCallback = insertUserDataCallback; - } - - @Override - protected Void doInBackground(Void... voids) { - userDao.insert(userData); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (insertUserDataCallback != null) { - insertUserDataCallback.insertSuccess(); - } - } - - public interface InsertUserDataCallback { - void insertSuccess(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadSubredditIconAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadSubredditIconAsyncTask.java deleted file mode 100644 index a89f1064..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadSubredditIconAsyncTask.java +++ /dev/null @@ -1,71 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.Subreddit.FetchSubredditData; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditDao; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import retrofit2.Retrofit; - -public class LoadSubredditIconAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private SubredditDao subredditDao; - private String subredditName; - private Retrofit retrofit; - private String iconImageUrl; - private boolean hasSubredditInDb; - private LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener; - public LoadSubredditIconAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String subredditName, Retrofit retrofit, - LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.subredditDao = redditDataRoomDatabase.subredditDao(); - this.subredditName = subredditName; - this.retrofit = retrofit; - this.loadSubredditIconAsyncTaskListener = loadSubredditIconAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - SubredditData subredditData = subredditDao.getSubredditData(subredditName); - if (subredditData != null) { - iconImageUrl = subredditDao.getSubredditData(subredditName).getIconUrl(); - hasSubredditInDb = true; - } else { - hasSubredditInDb = false; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (!isCancelled()) { - if (hasSubredditInDb) { - loadSubredditIconAsyncTaskListener.loadIconSuccess(iconImageUrl); - } else { - FetchSubredditData.fetchSubredditData(retrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { - @Override - public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { - ArrayList singleSubredditDataList = new ArrayList<>(); - singleSubredditDataList.add(subredditData); - new InsertSubscribedThingsAsyncTask(redditDataRoomDatabase, null, - null, null, singleSubredditDataList, - () -> loadSubredditIconAsyncTaskListener.loadIconSuccess(subredditData.getIconUrl())).execute(); - } - - @Override - public void onFetchSubredditDataFail() { - loadSubredditIconAsyncTaskListener.loadIconSuccess(null); - } - }); - } - } - } - - public interface LoadSubredditIconAsyncTaskListener { - void loadIconSuccess(String iconImageUrl); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadUserDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadUserDataAsyncTask.java deleted file mode 100644 index 30c9e039..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/LoadUserDataAsyncTask.java +++ /dev/null @@ -1,58 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.User.FetchUserData; -import ml.docilealligator.infinityforreddit.User.UserDao; -import ml.docilealligator.infinityforreddit.User.UserData; -import retrofit2.Retrofit; - -public class LoadUserDataAsyncTask extends AsyncTask { - private UserDao userDao; - private String userName; - private String iconImageUrl; - private boolean hasUserInDb; - private Retrofit retrofit; - private LoadUserDataAsyncTaskListener loadUserDataAsyncTaskListener; - public LoadUserDataAsyncTask(UserDao userDao, String userName, Retrofit retrofit, LoadUserDataAsyncTaskListener loadUserDataAsyncTaskListener) { - this.userDao = userDao; - this.userName = userName; - this.retrofit = retrofit; - this.loadUserDataAsyncTaskListener = loadUserDataAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - if (userDao.getUserData(userName) != null) { - iconImageUrl = userDao.getUserData(userName).getIconUrl(); - hasUserInDb = true; - } else { - hasUserInDb = false; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (hasUserInDb) { - loadUserDataAsyncTaskListener.loadUserDataSuccess(iconImageUrl); - } else { - FetchUserData.fetchUserData(retrofit, userName, new FetchUserData.FetchUserDataListener() { - @Override - public void onFetchUserDataSuccess(UserData userData) { - new InsertUserDataAsyncTask(userDao, userData, () -> loadUserDataAsyncTaskListener.loadUserDataSuccess(userData.getIconUrl())).execute(); - } - - @Override - public void onFetchUserDataFailed() { - loadUserDataAsyncTaskListener.loadUserDataSuccess(null); - } - }); - } - } - - public interface LoadUserDataAsyncTaskListener { - void loadUserDataSuccess(String iconImageUrl); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ParseAndInsertNewAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ParseAndInsertNewAccountAsyncTask.java deleted file mode 100644 index 1a3c23fb..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/ParseAndInsertNewAccountAsyncTask.java +++ /dev/null @@ -1,50 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.Account.Account; -import ml.docilealligator.infinityforreddit.Account.AccountDao; - -public class ParseAndInsertNewAccountAsyncTask extends AsyncTask { - - private String username; - private String accessToken; - private String refreshToken; - private String profileImageUrl; - private String bannerImageUrl; - private int karma; - private String code; - private AccountDao accountDao; - private ParseAndInsertAccountListener parseAndInsertAccountListener; - public ParseAndInsertNewAccountAsyncTask(String username, String accessToken, String refreshToken, String profileImageUrl, String bannerImageUrl, - int karma, String code, AccountDao accountDao, - ParseAndInsertAccountListener parseAndInsertAccountListener) { - this.username = username; - this.accessToken = accessToken; - this.refreshToken = refreshToken; - this.profileImageUrl = profileImageUrl; - this.bannerImageUrl = bannerImageUrl; - this.karma = karma; - this.code = code; - this.accountDao = accountDao; - this.parseAndInsertAccountListener = parseAndInsertAccountListener; - } - - @Override - protected Void doInBackground(Void... voids) { - Account account = new Account(username, accessToken, refreshToken, code, profileImageUrl, - bannerImageUrl, karma, true); - accountDao.markAllAccountsNonCurrent(); - accountDao.insert(account); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - parseAndInsertAccountListener.success(); - } - - public interface ParseAndInsertAccountListener { - void success(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveBitmapImageToFileAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveBitmapImageToFileAsyncTask.java deleted file mode 100644 index f70a87be..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveBitmapImageToFileAsyncTask.java +++ /dev/null @@ -1,55 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.graphics.Bitmap; -import android.os.AsyncTask; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -public class SaveBitmapImageToFileAsyncTask extends AsyncTask { - private Bitmap resource; - private String cacheDirPath; - private String fileName; - private SaveBitmapImageToFileAsyncTaskListener saveBitmapImageToFileAsyncTaskListener; - private boolean saveSuccess = true; - private File imageFile; - - public SaveBitmapImageToFileAsyncTask(Bitmap resource, String cacheDirPath, String fileName, - SaveBitmapImageToFileAsyncTaskListener saveBitmapImageToFileAsyncTaskListener) { - this.resource = resource; - this.cacheDirPath = cacheDirPath; - this.fileName = fileName; - this.saveBitmapImageToFileAsyncTaskListener = saveBitmapImageToFileAsyncTaskListener; - } - - public interface SaveBitmapImageToFileAsyncTaskListener { - void saveSuccess(File imageFile); - void saveFailed(); - } - - @Override - protected Void doInBackground(Void... voids) { - try { - imageFile = new File(cacheDirPath, fileName); - OutputStream outputStream = new FileOutputStream(imageFile); - resource.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); - outputStream.flush(); - outputStream.close(); - } catch (IOException e) { - saveSuccess = false; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (saveSuccess) { - saveBitmapImageToFileAsyncTaskListener.saveSuccess(imageFile); - } else { - saveBitmapImageToFileAsyncTaskListener.saveFailed(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java deleted file mode 100644 index c1a9ee19..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SaveGIFToFileAsyncTask.java +++ /dev/null @@ -1,59 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import com.bumptech.glide.load.resource.gif.GifDrawable; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -public class SaveGIFToFileAsyncTask extends AsyncTask { - private GifDrawable resource; - private String cacheDirPath; - private String fileName; - private SaveGIFToFileAsyncTaskListener saveImageToFileAsyncTaskListener; - private boolean saveSuccess = true; - private File imageFile; - - public SaveGIFToFileAsyncTask(GifDrawable resource, String cacheDirPath, String fileName, - SaveGIFToFileAsyncTaskListener saveImageToFileAsyncTaskListener) { - this.resource = resource; - this.cacheDirPath = cacheDirPath; - this.fileName = fileName; - this.saveImageToFileAsyncTaskListener = saveImageToFileAsyncTaskListener; - } - - public interface SaveGIFToFileAsyncTaskListener { - void saveSuccess(File imageFile); - void saveFailed(); - } - - @Override - protected Void doInBackground(Void... voids) { - try { - imageFile = new File(cacheDirPath, fileName); - ByteBuffer byteBuffer = resource.getBuffer(); - OutputStream outputStream = new FileOutputStream(imageFile); - byte[] bytes = new byte[byteBuffer.capacity()]; - ((ByteBuffer) byteBuffer.duplicate().clear()).get(bytes); - outputStream.write(bytes, 0, bytes.length); - outputStream.close(); - } catch (IOException e) { - saveSuccess = false; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (saveSuccess) { - saveImageToFileAsyncTaskListener.saveSuccess(imageFile); - } else { - saveImageToFileAsyncTaskListener.saveFailed(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SetAsWallpaperAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SetAsWallpaperAsyncTask.java deleted file mode 100644 index b868e5d6..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SetAsWallpaperAsyncTask.java +++ /dev/null @@ -1,95 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.app.WallpaperManager; -import android.graphics.Bitmap; -import android.graphics.Rect; -import android.media.ThumbnailUtils; -import android.os.AsyncTask; -import android.os.Build; -import android.util.DisplayMetrics; -import android.view.WindowManager; - -import java.io.IOException; - -import ml.docilealligator.infinityforreddit.WallpaperSetter; - -public class SetAsWallpaperAsyncTask extends AsyncTask { - - private Bitmap bitmap; - private int setTo; - private WallpaperManager manager; - private WindowManager windowManager; - private WallpaperSetter.SetWallpaperListener setWallpaperListener; - private boolean success = true; - - public SetAsWallpaperAsyncTask(Bitmap bitmap, int setTo, WallpaperManager manager, WindowManager windowManager, - WallpaperSetter.SetWallpaperListener setWallpaperListener) { - this.bitmap = bitmap; - this.setTo = setTo; - this.manager = manager; - this.windowManager = windowManager; - this.setWallpaperListener = setWallpaperListener; - } - - @Override - protected Void doInBackground(Void... voids) { - DisplayMetrics metrics = new DisplayMetrics(); - Rect rect = null; - - if (windowManager != null) { - windowManager.getDefaultDisplay().getMetrics(metrics); - int height = metrics.heightPixels; - int width = metrics.widthPixels; - - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { - bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height); - } - - float imageAR = (float) bitmap.getWidth() / (float) bitmap.getHeight(); - float screenAR = (float) width / (float) height; - - if (imageAR > screenAR) { - int desiredWidth = (int) (bitmap.getHeight() * screenAR); - rect = new Rect((bitmap.getWidth() - desiredWidth) / 2, 0, bitmap.getWidth(), bitmap.getHeight()); - } else { - int desiredHeight = (int) (bitmap.getWidth() / screenAR); - rect = new Rect(0, (bitmap.getHeight() - desiredHeight) / 2, bitmap.getWidth(), (bitmap.getHeight() + desiredHeight) / 2); - } - } - try { - switch (setTo) { - case WallpaperSetter.HOME_SCREEN: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - manager.setBitmap(bitmap, rect, true, WallpaperManager.FLAG_SYSTEM); - } - break; - case WallpaperSetter.LOCK_SCREEN: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - manager.setBitmap(bitmap, rect, true, WallpaperManager.FLAG_LOCK); - } - break; - case WallpaperSetter.BOTH_SCREENS: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - manager.setBitmap(bitmap, rect, true, WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK); - } else { - manager.setBitmap(bitmap); - } - break; - } - } catch (IOException e) { - success = false; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (success) { - setWallpaperListener.success(); - } else { - setWallpaperListener.failed(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchAccountAsyncTask.java deleted file mode 100644 index 8ddf8a94..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchAccountAsyncTask.java +++ /dev/null @@ -1,36 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.Account.Account; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SwitchAccountAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private String newAccountName; - private Account account; - private SwitchAccountAsyncTaskListener switchAccountAsyncTaskListener; - public SwitchAccountAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String newAccountName, - SwitchAccountAsyncTaskListener switchAccountAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.newAccountName = newAccountName; - this.switchAccountAsyncTaskListener = switchAccountAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.accountDao().markAllAccountsNonCurrent(); - redditDataRoomDatabase.accountDao().markAccountCurrent(newAccountName); - account = redditDataRoomDatabase.accountDao().getCurrentAccount(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - switchAccountAsyncTaskListener.switched(account); - } - - public interface SwitchAccountAsyncTaskListener { - void switched(Account account); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchToAnonymousAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchToAnonymousAccountAsyncTask.java deleted file mode 100644 index 3ac47124..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AsyncTask/SwitchToAnonymousAccountAsyncTask.java +++ /dev/null @@ -1,37 +0,0 @@ -package ml.docilealligator.infinityforreddit.AsyncTask; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.Account.AccountDao; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SwitchToAnonymousAccountAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private boolean removeCurrentAccount; - private SwitchToAnonymousAccountAsyncTaskListener switchToAnonymousAccountAsyncTaskListener; - public SwitchToAnonymousAccountAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, boolean removeCurrentAccount, - SwitchToAnonymousAccountAsyncTaskListener switchToAnonymousAccountAsyncTaskListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.removeCurrentAccount = removeCurrentAccount; - this.switchToAnonymousAccountAsyncTaskListener = switchToAnonymousAccountAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - AccountDao accountDao = redditDataRoomDatabase.accountDao(); - if (removeCurrentAccount) { - accountDao.deleteCurrentAccount(); - } - accountDao.markAllAccountsNonCurrent(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - switchToAnonymousAccountAsyncTaskListener.logoutSuccess(); - } - - public interface SwitchToAnonymousAccountAsyncTaskListener { - void logoutSuccess(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Award/Award.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Award/Award.java deleted file mode 100644 index ac8effe3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Award/Award.java +++ /dev/null @@ -1,143 +0,0 @@ -package ml.docilealligator.infinityforreddit.Award; - -import java.util.ArrayList; - -public class Award { - private String id; - private String awardSubType; - private String name; - private String description; - private String iconUrl; - private int coinPrice; - - public Award(String id, String awardSubType, String name, String description, String iconUrl, int coinPrice) { - this.id = id; - this.awardSubType = awardSubType; - this.name = name; - this.description = description; - this.iconUrl = iconUrl; - this.coinPrice = coinPrice; - } - - public static ArrayList getAvailableAwards() { - ArrayList awards = new ArrayList<>(); - awards.add(new Award("gid_2", "GLOBAL", "Gold", "Gives the author a week of Reddit Premium, 100 Coins to do with as they please, and shows a Gold Award.", "https://www.redditstatic.com/gold/awards/icon/gold_512.png", 500)); - awards.add(new Award("gid_3", "GLOBAL", "Platinum", "Gives the author a month of Reddit Premium, which includes 700 Coins for that month, and shows a Platinum Award.", "https://www.redditstatic.com/gold/awards/icon/platinum_512.png", 1800)); - awards.add(new Award("award_4ca5a4e6-8873-4ac5-99b9-71b1d5161a91", "GLOBAL", "Argentium", "Latin for distinguished. Shimmers like silver & stronger than steel. When someone deserves outsize recognition. This award gives a three-month Premium subscription and 2500 coins to the recipient.", "https://www.redditstatic.com/gold/awards/icon/Mithril_512.png", 20000)); - awards.add(new Award("award_2385c499-a1fb-44ec-b9b7-d260f3dc55de", "GLOBAL", "Ternion All-Powerful", "Legendary level. A no holds barred celebration of something that hits you in the heart, mind and soul. Some might call it unachievanium. Gives the author 6 months of Premium and 5000 Coins.", "https://www.redditstatic.com/gold/awards/icon/Trinity_512.png", 50000)); - awards.add(new Award("gid_1", "GLOBAL", "Silver", "Shows the Silver Award... and that's it.", "https://www.redditstatic.com/gold/awards/icon/silver_512.png", 100)); - awards.add(new Award("award_e55d1889-11f2-4d04-8abb-44b1de7dd53d", "GLOBAL", "Aww-some", "Use the Aww-some Award to highlight comments that are absolutely adorable.", "https://www.redditstatic.com/gold/awards/icon/Awwsome_512.png", 350)); - awards.add(new Award("award_11eb6af3-3d0d-4d70-8261-22d216ab591d", "GLOBAL", "Heartbeat", "Use the Heartbeat Award to highlight comments that make you feel warm and fuzzy", "https://www.redditstatic.com/gold/awards/icon/Heartbeat_512.png", 350)); - awards.add(new Award("award_0e957fb0-c8f1-4ba1-a8ef-e1e524b60d7d", "GLOBAL", "Starry", "Use the Starry Award to highlight comments that deserve to stand out from the crowd.", "https://www.redditstatic.com/gold/awards/icon/Starry_512.png", 500)); - awards.add(new Award("award_75f9bc56-eba3-4988-a1af-aec974404a0b", "GROUP", "Super Medal Train", "All aboard! Every 5 Awards gives the author 100 Coins and 1 week of Premium. Rack up the number of Awards and watch the Train level-up.", "https://i.redd.it/award_images/t5_22cerq/v3wyujfap4p51_SuperMedalTrain.png", 125)); - awards.add(new Award("award_7149a401-1223-4543-bfd6-4127cb4246da", "GLOBAL", "Cool Summer", "The key is to keep your cool this summer.", "https://i.redd.it/award_images/t5_22cerq/1m9abin81nc51_CoolSummer.png", 50)); - awards.add(new Award("award_02d9ab2c-162e-4c01-8438-317a016ed3d9", "GLOBAL", "Take My Energy", "I'm in this with you.", "https://i.redd.it/award_images/t5_22cerq/898sygoknoo41_TakeMyEnergy.png", 50)); - awards.add(new Award("award_7becef23-fb0b-4d62-b8a6-01d5759367cb", "GLOBAL", "Faith In Humanity Restored", "When goodness lifts you", "https://i.redd.it/award_images/t5_22cerq/gva4vt20qc751_FaithInHumanityRestored.png", 70)); - awards.add(new Award("award_84276b1e-cc8f-484f-a19c-be6c09adc1a5", "GLOBAL", "Bravo!", "An amazing showing.", "https://www.redditstatic.com/gold/awards/icon/SnooClapping_512.png", 400)); - awards.add(new Award("award_68ba1ee3-9baf-4252-be52-b808c1e8bdc4", "GLOBAL", "This", "Me approved", "https://i.redd.it/award_images/t5_22cerq/vu6om0xnb7e41_This.png", 300)); - awards.add(new Award("award_1f0462ee-18f5-4f33-89cf-f1f79336a452", "GLOBAL", "Wholesome (Pro)", "When you come across a feel-good thing. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/0o2j782f00e41_WholesomeSuperpro.png", 500)); - awards.add(new Award("award_3dd248bc-3438-4c5b-98d4-24421fd6d670", "GLOBAL", "Coin Gift", "Give the gift of 250 Reddit Coins.", "https://i.redd.it/award_images/t5_22cerq/cr1mq4yysv541_CoinGift.png", 300)); - awards.add(new Award("award_2ae56630-cfe0-424e-b810-4945b9145358", "GLOBAL", "Helpful (Pro)", "Thank you stranger. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/trz28na8ajz31_Helpful.png", 500)); - awards.add(new Award("award_6220ecfe-4552-4949-aa13-fb1fb7db537c", "GLOBAL", "Super Heart Eyes", "When the love is out of control.", "https://www.redditstatic.com/gold/awards/icon/Superheart_512.png", 325)); - awards.add(new Award("award_5b39e8fd-7a58-4cbe-8ca0-bdedd5ed1f5a", "GLOBAL", "Doot 🎵 Doot", "Sometimes you just got to dance with the doots.", "https://www.redditstatic.com/gold/awards/icon/Updoot_512.png", 400)); - awards.add(new Award("award_9f928aff-c9f5-4e7e-aa91-8619dce60f1c", "GLOBAL", "Table Slap", "When laughter meets percussion", "https://www.redditstatic.com/gold/awards/icon/TableSlap_512.png", 325)); - awards.add(new Award("award_3409a4c0-ba69-43a0-be9f-27bc27c159cc", "GLOBAL", "Spit-take", "Shower them with laughs", "https://www.redditstatic.com/gold/awards/icon/Spits_drink_512.png", 325)); - awards.add(new Award("award_3267ca1c-127a-49e9-9a3d-4ba96224af18", "GLOBAL", "I'll Drink to That", "Let's sip to good health and good company", "https://i.redd.it/award_images/t5_22cerq/45aeu8mzvsj51_IllDrinktoThat.png", 100)); - awards.add(new Award("award_31260000-2f4a-4b40-ad20-f5aa46a577bf", "APPRECIATION", "Timeless Beauty", "Beauty that's forever. Gives 100 Coins each to the author and the community.", "https://i.redd.it/award_images/t5_22cerq/crhlsu5wzlc41_TimelessBeauty.png", 250)); - awards.add(new Award("award_69c94eb4-d6a3-48e7-9cf2-0f39fed8b87c", "GLOBAL", "Ally", "Listen, get educated, and get involved.", "https://i.redd.it/award_images/t5_22cerq/5nswjpyy44551_Ally.png", 50)); - awards.add(new Award("award_a903c949-ccc5-420d-8239-1bbefc424838", "GLOBAL", "Healthcare Hero", "Putting yourself on the line for us - you are the perfect super hero!", "https://i.redd.it/award_images/t5_22cerq/xs2na1t1v9p41_HealthcareHero.png", 50)); - awards.add(new Award("award_03c4f93d-efc7-463b-98a7-c01814462ab0", "GLOBAL", "I am disappoint", "I'm not mad, I'm just disappointed.", "https://i.redd.it/award_images/t5_22cerq/3ekkailk5s551_Iamdisappoint.png", 50)); - awards.add(new Award("award_d33fddd7-a58a-4472-b1a2-3157d8c8b76f", "GLOBAL", "Looking Busy", "Looking like you're working is hard work.", "https://i.redd.it/award_images/t5_22cerq/k0qzautvyyk51_LookingBusy.png", 50)); - awards.add(new Award("award_e1b2bf9e-8c62-4edc-9b6d-ffa44a7cb53b", "GLOBAL", "Recharge", "Feeling relaxed and restored", "https://i.redd.it/award_images/t5_22cerq/0lurnbnhqkl51_Recharge.png", 50)); - awards.add(new Award("award_80d4d339-95d0-43ac-b051-bc3fe0a9bab8", "GLOBAL", "Wearing is Caring", "Keep the community and yourself healthy and happy.", "https://i.redd.it/award_images/t5_22cerq/lcswc5d07hb51_WearingisCaring.png", 50)); - awards.add(new Award("award_b1b44fa1-8179-4d84-a9ed-f25bb81f1c5f", "GLOBAL", "Facepalm", "*Lowers face into palm*", "https://i.redd.it/award_images/t5_22cerq/ey2iodron2s41_Facepalm.png", 70)); - awards.add(new Award("award_99d95969-6100-45b2-b00c-0ec45ae19596", "GLOBAL", "Snek", "A smol, delicate danger noodle.", "https://i.redd.it/award_images/t5_22cerq/rc5iesz2z8t41_Snek.png", 70)); - awards.add(new Award("award_b92370bb-b7de-4fb3-9608-c5b4a22f714a", "GLOBAL", "Tree Hug", "Show nature some love.", "https://i.redd.it/award_images/t5_22cerq/fukjtec638u41_TreeHug.png", 70)); - awards.add(new Award("award_ae89e420-c4a5-47b8-a007-5dacf1c0f0d4", "GLOBAL", "Lawyer Up", "OBJECTION!", "https://i.redd.it/award_images/t5_22cerq/iq0sgwn5bzy41_LawyerUp.png", 75)); - awards.add(new Award("award_8352bdff-3e03-4189-8a08-82501dd8f835", "GLOBAL", "Hugz", "Everything is better with a good hug", "https://i.redd.it/award_images/t5_22cerq/niiatoknifn51_Hugz.png", 80)); - awards.add(new Award("award_869d4135-8738-41e5-8630-de593b4f049f", "GLOBAL", "'MURICA", "Did somebody say 'Murica?", "https://i.redd.it/award_images/t5_22cerq/18mwqw5th9e51_MURICA.png", 100)); - awards.add(new Award("award_81cf5c92-8500-498c-9c94-3e4034cece0a", "GLOBAL", "Dread", "Staring into the abyss and it's staring right back", "https://i.redd.it/award_images/t5_22cerq/nvfe4gyawnf51_Dread.png", 100)); - awards.add(new Award("award_483d8e29-bbe5-404e-a09a-c2d7b16c4fff", "GLOBAL", "Evil Cackle", "Laugh like a supervillain", "https://i.redd.it/award_images/t5_22cerq/43zl6dfcg9e51_EvilCackle.png", 100)); - awards.add(new Award("award_74fe5152-7906-4991-9016-bc2d8e261200", "GLOBAL", "Excited", "I don't know what to do with my hands!", "https://i.redd.it/award_images/t5_22cerq/x069ow7ewnf51_Excited.png", 100)); - awards.add(new Award("award_01178870-6a4f-4172-8f36-9ed5092ee4f9", "GLOBAL", "Glow Up", "You look amazing, glowing, incredible!", "https://i.redd.it/award_images/t5_22cerq/2754pa5jvsj51_GlowUp.png", 100)); - awards.add(new Award("award_19860e30-3331-4bac-b3d1-bd28de0c7974", "GLOBAL", "Heartwarming", "I needed this today", "https://i.redd.it/award_images/t5_22cerq/v1mxw8i6wnf51_Heartwarming.png", 100)); - awards.add(new Award("award_1da6ff27-7c0d-4524-9954-86e5cda5fcac", "GLOBAL", "Keep Calm", "Stop, chill, relax", "https://i.redd.it/award_images/t5_22cerq/g77c4oud7hb51_KeepCalm.png", 100)); - awards.add(new Award("award_1e516e18-cbee-4668-b338-32d5530f91fe", "GLOBAL", "Kiss", "You deserve a smooch", "https://i.redd.it/award_images/t5_22cerq/sb42u5gmwsj51_Kiss.png", 100)); - awards.add(new Award("award_b4072731-c0fb-4440-adc7-1063d6a5e6a0", "GLOBAL", "Masterpiece", "C'est magnifique", "https://i.redd.it/award_images/t5_22cerq/2juh333m40n51_Masterpiece.png", 100)); - awards.add(new Award("award_fbe9527a-adb3-430e-af1a-5fd3489e641b", "GLOBAL", "Shocked", "I'm genuinely flabbergasted.", "https://i.redd.it/award_images/t5_22cerq/fck3iedi2ug51_Shocked.png", 100)); - awards.add(new Award("award_0b41ba9b-8ad9-42c8-85b1-942d5462c830", "GLOBAL", "Starts Recording", "This should be good", "https://i.redd.it/award_images/t5_22cerq/zlrdwu9kh9e51_StartsRecording.png", 100)); - awards.add(new Award("award_43f3bf99-92d6-47ab-8205-130d26e7929f", "GLOBAL", "Tearing Up", "This hits me right in the feels", "https://i.redd.it/award_images/t5_22cerq/lop66ut2wnf51_TearingUp.png", 100)); - awards.add(new Award("award_ae7f17fb-6538-4c75-9ff4-5f48b4cdaa94", "GLOBAL", "Yummy", "That looks so good", "https://i.redd.it/award_images/t5_22cerq/a7dhg27hvnf51_Yummy.png", 100)); - awards.add(new Award("award_5f123e3d-4f48-42f4-9c11-e98b566d5897", "GLOBAL", "Wholesome", "When you come across a feel-good thing.", "https://i.redd.it/award_images/t5_22cerq/5izbv4fn0md41_Wholesome.png", 125)); - awards.add(new Award("award_77ba55a2-c33c-4351-ac49-807455a80148", "GLOBAL", "Bless Up", "Prayers up for the blessed.", "https://i.redd.it/award_images/t5_22cerq/trfv6ems1md41_BlessUp.png", 150)); - awards.add(new Award("award_c42dc561-0b41-40b6-a23d-ef7e110e739e", "GLOBAL", "Buff Doge", "So buff, wow", "https://i.redd.it/award_images/t5_22cerq/zc4a9vk5zmc51_BuffDoge.png", 150)); - awards.add(new Award("award_f44611f1-b89e-46dc-97fe-892280b13b82", "GLOBAL", "Helpful", "Thank you stranger. Shows the award.", "https://i.redd.it/award_images/t5_22cerq/klvxk1wggfd41_Helpful.png", 150)); - awards.add(new Award("award_88fdcafc-57a0-48db-99cc-76276bfaf28b", "GLOBAL", "Press F", "To pay respects.", "https://i.redd.it/award_images/t5_22cerq/tcofsbf92md41_PressF.png", 150)); - awards.add(new Award("award_a7f9cbd7-c0f1-4569-a913-ebf8d18de00b", "GLOBAL", "Take My Money", "I'm buying what you're selling", "https://i.redd.it/award_images/t5_22cerq/9jr8pv84v7i51_TakeMyMoney.png", 150)); - awards.add(new Award("award_a9968927-3f72-4af9-8bcd-aaf804838dc6", "GLOBAL", "Back Away", "...slowly", "https://i.redd.it/award_images/t5_22cerq/t5z1oc8t2ug51_BackAway.png", 200)); - awards.add(new Award("award_e813313c-1002-49bf-ac37-e966710f605f", "GLOBAL", "Giggle", "Innocent laughter", "https://www.redditstatic.com/gold/awards/icon/Giggle_512.png", 200)); - awards.add(new Award("award_1703f934-cf44-40cc-a96d-3729d0b48262", "GLOBAL", "I'd Like to Thank...", "My kindergarten teacher, my cat, my mom, and you.", "https://i.redd.it/award_images/t5_22cerq/8ad2jffnclf41_Thanks.png", 200)); - awards.add(new Award("award_b28d9565-4137-433d-bb65-5d4aa82ade4c", "GLOBAL", "I'm Deceased", "Call an ambulance, I'm laughing too hard.", "https://i.redd.it/award_images/t5_22cerq/2jd92wtn25g41_ImDeceased.png", 200)); - awards.add(new Award("award_4922c1be-3646-4d62-96ea-19a56798df51", "GLOBAL", "Looking", "I can't help but look.", "https://i.redd.it/award_images/t5_22cerq/kjpl76213ug51_Looking.png", 200)); - awards.add(new Award("award_9ee30a8f-463e-4ef7-9da9-a09f270ec026", "GLOBAL", "Stonks Falling", "Losing value fast.", "https://i.redd.it/award_images/t5_22cerq/ree13odobef41_StonksFalling.png", 200)); - awards.add(new Award("award_d125d124-5c03-490d-af3d-d07c462003da", "GLOBAL", "Stonks Rising", "To the MOON.", "https://i.redd.it/award_images/t5_22cerq/s5edqq9abef41_StonksRising.png", 200)); - awards.add(new Award("award_dc391ef9-0df8-468f-bd3c-7b177092de35", "GLOBAL", "This is 2020", "Every reason to be alarmed", "https://i.redd.it/award_images/t5_22cerq/ncon692ev7i51_Thisis2020.png", 200)); - awards.add(new Award("award_11be92ba-509e-46d3-991b-593239006521", "GLOBAL", "1UP", "Extra life", "https://www.redditstatic.com/gold/awards/icon/Levelup_512.png", 250)); - awards.add(new Award("award_351f8639-ee3b-4def-adf3-6b39980c278a", "GLOBAL", "2020 Vision", "Looking into the present.", "https://i.redd.it/award_images/t5_22cerq/48eychq6e9741_2020Vision.png", 300)); - awards.add(new Award("award_cc299d65-77de-4828-89de-708b088349a0", "GLOBAL", "GOAT", "Historical anomaly - greatest in eternity.", "https://i.redd.it/award_images/t5_22cerq/x52x5be57fd41_GOAT.png", 300)); - awards.add(new Award("award_8dc476c7-1478-4d41-b940-f139e58f7756", "GLOBAL", "Got the W", "", "https://i.redd.it/award_images/t5_22cerq/9avdcwgupta41_GottheW.png", 300)); - awards.add(new Award("award_28e8196b-d4e9-45bc-b612-cd4c7d3ed4b3", "GLOBAL", "Rocket Like", "When an upvote just isn't enough, smash the Rocket Like.", "https://i.redd.it/award_images/t5_22cerq/94pn64yuas941_RocketLike.png", 300)); - awards.add(new Award("award_3e000ecb-c1a4-49dc-af14-c8ac2029ca97", "GLOBAL", "Table Flip", "ARGH!", "https://i.redd.it/award_images/t5_22cerq/a05z7bb9v7i51_TableFlip.png", 300)); - awards.add(new Award("award_725b427d-320b-4d02-8fb0-8bb7aa7b78aa", "GLOBAL", "Updoot", "Sometimes you just got to doot.", "https://i.redd.it/award_images/t5_22cerq/7atjjqpy1mc41_Updoot.png", 300)); - awards.add(new Award("award_c043e7ef-8514-4862-99c6-45e36cec4f66", "GLOBAL", "OOF", "That hurts", "https://www.redditstatic.com/gold/awards/icon/OOF_512.png", 325)); - awards.add(new Award("award_2bc47247-b107-44a8-a78c-613da21869ff", "GLOBAL", "To The Stars", "Boldly go where we haven't been in a long, long time.", "https://www.redditstatic.com/gold/awards/icon/Rocket_512.png", 325)); - awards.add(new Award("award_2ff1fdd0-ff73-47e6-a43c-bde6d4de8fbd", "GLOBAL", "Into the Magic Portal", "Hope to make it to the other side.", "https://www.redditstatic.com/gold/awards/icon/TeleportIn_512.png", 350)); - awards.add(new Award("award_7fe72f36-1141-4a39-ba76-0d481889b390", "GLOBAL", "Out of the Magic Portal", "That was fun, but I'm glad to be back", "https://www.redditstatic.com/gold/awards/icon/TeleportOut_512.png", 350)); - awards.add(new Award("award_f7a4fd5e-7cd1-4c11-a1c9-c18d05902e81", "GLOBAL", "Crab Rave", "[Happy crab noises]", "https://www.redditstatic.com/gold/awards/icon/CrabRave_512.png", 400)); - awards.add(new Award("award_43c43a35-15c5-4f73-91ef-fe538426435a", "GLOBAL", "Bless Up (Pro)", "Prayers up for the blessed. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/xe5mw55w5v541_BlessUp.png", 500)); - awards.add(new Award("award_27d3176c-b388-4616-80ec-11b8ece5b7ee", "GLOBAL", "Snoo Nice", "Gives the author a week of Reddit Premium and 100 Coins to do with as they please.", "https://i.redd.it/award_images/t5_22cerq/9r7hexe6pta41_SnooNice.png", 500)); - awards.add(new Award("award_35c78e6e-507b-4f1d-b3d8-ed43840909a8", "GLOBAL", "Pot o' Coins", "The treasure at the end of the rainbow. Gives the author 800 Coins to do with as they please.", "https://i.redd.it/award_images/t5_22cerq/wg3lzllyg9n41_PotoCoins.png", 1000)); - awards.add(new Award("award_5eac457f-ebac-449b-93a7-eb17b557f03c", "PREMIUM", "LOVE!", "When you follow your heart, love is the answer", "https://i.redd.it/award_images/t5_22cerq/j3azv69qjfn51_LOVE.png", 20)); - awards.add(new Award("award_abb865cf-620b-4219-8777-3658cf9091fb", "PREMIUM", "Starstruck", "Can't stop seeing stars", "https://www.redditstatic.com/gold/awards/icon/Starstruck_512.png", 20)); - awards.add(new Award("award_b4ff447e-05a5-42dc-9002-63568807cfe6", "PREMIUM", "All-Seeing Upvote", "A glowing commendation for all to see", "https://i.redd.it/award_images/t5_22cerq/rg960rc47jj41_All-SeeingUpvote.png", 30)); - awards.add(new Award("award_a2506925-fc82-4d6c-ae3b-b7217e09d7f0", "PREMIUM", "Narwhal Salute", "A golden splash of respect", "https://i.redd.it/award_images/t5_22cerq/80j20o397jj41_NarwhalSalute.png", 30)); - awards.add(new Award("award_c4b2e438-16bb-4568-88e7-7893b7662944", "PREMIUM", "Wholesome Seal of Approval", "A glittering stamp for a feel-good thing", "https://i.redd.it/award_images/t5_22cerq/b9ks3a5k7jj41_WholesomeSealofApproval.png", 30)); - awards.add(new Award("award_9663243a-e77f-44cf-abc6-850ead2cd18d", "PREMIUM", "Bravo Grande!", "For an especially amazing showing.", "https://www.redditstatic.com/gold/awards/icon/SnooClappingPremium_512.png", 75)); - awards.add(new Award("award_92cb6518-a71a-4217-9f8f-7ecbd7ab12ba", "PREMIUM", "Take My Power", "Add my power to yours.", "https://www.redditstatic.com/gold/awards/icon/TakeMyPower_512.png", 75)); - awards.add(new Award("award_5fb42699-4911-42a2-884c-6fc8bdc36059", "APPRECIATION", "Cake", "Did someone say... cake?", "https://i.redd.it/award_images/t5_22cerq/aoa99054n2s41_Cake.png", 150)); - awards.add(new Award("award_f7562045-905d-413e-9ed2-0a16d4bfe349", "APPRECIATION", "Plus One", "You officially endorse and add your voice to the crowd.", "https://i.redd.it/award_images/t5_22cerq/6vgr8y21i9741_PlusOne.png", 200)); - awards.add(new Award("award_2adc49e8-d6c9-4923-9293-2bfab1648569", "APPRECIATION", "Awesome Answer", "For a winning take and the kind soul who nails a question. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/71v56o5a5v541_AwesomeAnswer.png", 250)); - awards.add(new Award("award_cc540de7-dfdb-4a68-9acf-6f9ce6b17d21", "APPRECIATION", "It's Cute!", "You made me UwU.", "https://i.redd.it/award_images/t5_22cerq/n94bgm83in941_ItsCute.png", 250)); - awards.add(new Award("award_9583d210-a7d0-4f3c-b0c7-369ad579d3d4", "APPRECIATION", "Mind Blown", "When a thing immediately combusts your brain. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/wa987k0p4v541_MindBlown.png", 250)); - awards.add(new Award("award_d306c865-0d49-4a36-a1ab-a4122a0e3480", "APPRECIATION", "Original", "When something new and creative wows you. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/b8xt4z8yajz31_Original.png", 250)); - awards.add(new Award("award_a67d649d-5aa5-407e-a98b-32fd9e3a9696", "APPRECIATION", "Today I Learned", "The more you know... Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/bph2png4ajz31_TodayILearned.png", 250)); - awards.add(new Award("award_d48aad4b-286f-4a3a-bb41-ec05b3cd87cc", "APPRECIATION", "Yas Queen", "YAAAAAAAAAAASSS.", "https://i.redd.it/award_images/t5_22cerq/kthj3e4h3bm41_YasQueen.png", 250)); - awards.add(new Award("award_a9009ea5-1a36-42ae-aab2-5967563ee054", "APPRECIATION", "Heart Eyes", "For love at first sight. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/12kz7a7j4v541_HeartEyes.png", 500)); - awards.add(new Award("award_a7a04d6a-8dd8-41bb-b906-04fa8f144014", "APPRECIATION", "Made Me Smile", "When you're smiling before you know it. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/hwnbr9l67s941_MadeMeSmile.png", 500)); - return awards; - } - - public String getId() { - return id; - } - - public String getAwardSubType() { - return awardSubType; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - public String getIconUrl() { - return iconUrl; - } - - public int getCoinPrice() { - return coinPrice; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Award/GiveAward.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Award/GiveAward.java deleted file mode 100644 index e2596534..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Award/GiveAward.java +++ /dev/null @@ -1,134 +0,0 @@ -package ml.docilealligator.infinityforreddit.Award; - -import android.os.AsyncTask; -import android.text.Html; - -import androidx.annotation.NonNull; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class GiveAward { - public interface GiveAwardListener { - void success(String awardsHTML, int awardCount); - void failed(int code, String message); - } - - public static void giveAwardV2(Retrofit oauthRetrofit, String accessToken, String thingFullName, String awardId, - boolean isAnonymous, GiveAwardListener giveAwardListener) { - Map params = new HashMap<>(); - params.put(APIUtils.GILD_TYPE, awardId); - params.put(APIUtils.IS_ANONYMOUS, Boolean.toString(isAnonymous)); - params.put(APIUtils.THING_ID_KEY, thingFullName); - oauthRetrofit.create(RedditAPI.class).awardThing(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseResponseAsyncTask(response.body(), new ParseResponseAsyncTask.ParseResponseAsyncTaskListener() { - @Override - public void success(String awardsHTML, int awardCount) { - giveAwardListener.success(awardsHTML, awardCount); - } - - @Override - public void failed(String errorMessage) { - giveAwardListener.failed(response.code(), response.body()); - } - }).execute(); - } else { - giveAwardListener.failed(response.code(), response.body()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - giveAwardListener.failed(0, t.getMessage()); - } - }); - } - - private static class ParseResponseAsyncTask extends AsyncTask { - - private String response; - private boolean error = false; - private String awardsHTML; - private int awardCount; - private String errorMessage = null; - private ParseResponseAsyncTaskListener parseResponseAsyncTaskListener; - - public ParseResponseAsyncTask(String response, ParseResponseAsyncTaskListener parseResponseAsyncTaskListener) { - this.response = response; - this.parseResponseAsyncTaskListener = parseResponseAsyncTaskListener; - } - - interface ParseResponseAsyncTaskListener { - void success(String awardsHTML, int awardCount); - void failed(String errorMessage); - } - - @Override - protected Void doInBackground(Void... voids) { - try { - //Check for error - JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); - - if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { - JSONArray errorArray = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) - .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); - if (errorArray.length() != 0) { - String errorString; - if (errorArray.length() >= 2) { - errorString = errorArray.getString(1); - } else { - errorString = errorArray.getString(0); - } - errorMessage = errorString.substring(0, 1).toUpperCase() + errorString.substring(1); - error = true; - return null; - } - } - } catch (JSONException ignore) {} - - try { - JSONArray awardingsArray = new JSONObject(response).getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); - StringBuilder awardingsBuilder = new StringBuilder(); - awardCount = 0; - for (int i = 0; i < awardingsArray.length(); i++) { - JSONObject award = awardingsArray.getJSONObject(i); - int count = award.getInt(JSONUtils.COUNT_KEY); - awardCount += count; - String iconUrl = award.getString(JSONUtils.ICON_URL_KEY); - awardingsBuilder.append(" ").append("x").append(count).append(" "); - } - - awardsHTML = awardingsBuilder.toString(); - } catch (JSONException e) { - e.printStackTrace(); - error = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (error) { - parseResponseAsyncTaskListener.failed(errorMessage); - } else { - parseResponseAsyncTaskListener.success(awardsHTML, awardCount); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CommentMoreBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CommentMoreBottomSheetFragment.java deleted file mode 100644 index 198a9965..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CommentMoreBottomSheetFragment.java +++ /dev/null @@ -1,197 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.FullMarkdownActivity; -import ml.docilealligator.infinityforreddit.Activity.EditCommentActivity; -import ml.docilealligator.infinityforreddit.Activity.GiveAwardActivity; -import ml.docilealligator.infinityforreddit.Activity.ReportActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewPostDetailActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewUserDetailActivity; -import ml.docilealligator.infinityforreddit.Comment.Comment; -import ml.docilealligator.infinityforreddit.R; - - -/** - * A simple {@link Fragment} subclass. - */ -public class CommentMoreBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_COMMENT = "ECF"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_EDIT_AND_DELETE_AVAILABLE = "EEADA"; - public static final String EXTRA_POSITION = "EP"; - public static final String EXTRA_COMMENT_MARKDOWN = "ECM"; - public static final String EXTRA_IS_NSFW = "EIN"; - @BindView(R.id.edit_text_view_comment_more_bottom_sheet_fragment) - TextView editTextView; - @BindView(R.id.delete_text_view_comment_more_bottom_sheet_fragment) - TextView deleteTextView; - @BindView(R.id.save_text_view_comment_more_bottom_sheet_fragment) - TextView shareTextView; - @BindView(R.id.copy_text_view_comment_more_bottom_sheet_fragment) - TextView copyTextView; - @BindView(R.id.give_award_text_view_comment_more_bottom_sheet_fragment) - TextView giveAwardTextView; - @BindView(R.id.view_full_markdown_text_view_comment_more_bottom_sheet_fragment) - TextView viewFullMarkdownTextView; - @BindView(R.id.report_view_comment_more_bottom_sheet_fragment) - TextView reportTextView; - @BindView(R.id.see_removed_view_comment_more_bottom_sheet_fragment) - TextView seeRemovedTextView; - private AppCompatActivity activity; - - public CommentMoreBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_comment_more_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - Bundle bundle = getArguments(); - if (bundle == null) { - dismiss(); - return rootView; - } - Comment comment = bundle.getParcelable(EXTRA_COMMENT); - if (comment == null) { - dismiss(); - return rootView; - } - String accessToken = bundle.getString(EXTRA_ACCESS_TOKEN); - boolean editAndDeleteAvailable = bundle.getBoolean(EXTRA_EDIT_AND_DELETE_AVAILABLE, false); - - if (accessToken != null && !accessToken.equals("")) { - giveAwardTextView.setVisibility(View.VISIBLE); - giveAwardTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, GiveAwardActivity.class); - intent.putExtra(GiveAwardActivity.EXTRA_THING_FULLNAME, comment.getFullName()); - intent.putExtra(GiveAwardActivity.EXTRA_ITEM_POSITION, bundle.getInt(EXTRA_POSITION)); - if (activity instanceof ViewPostDetailActivity) { - activity.startActivityForResult(intent, ViewPostDetailActivity.GIVE_AWARD_REQUEST_CODE); - } else if (activity instanceof ViewUserDetailActivity) { - activity.startActivityForResult(intent, ViewUserDetailActivity.GIVE_AWARD_REQUEST_CODE); - } - dismiss(); - }); - - if (editAndDeleteAvailable) { - editTextView.setVisibility(View.VISIBLE); - deleteTextView.setVisibility(View.VISIBLE); - - editTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, EditCommentActivity.class); - intent.putExtra(EditCommentActivity.EXTRA_ACCESS_TOKEN, accessToken); - intent.putExtra(EditCommentActivity.EXTRA_FULLNAME, comment.getFullName()); - intent.putExtra(EditCommentActivity.EXTRA_CONTENT, comment.getCommentMarkdown()); - intent.putExtra(EditCommentActivity.EXTRA_POSITION, bundle.getInt(EXTRA_POSITION)); - if (activity instanceof ViewPostDetailActivity) { - activity.startActivityForResult(intent, ViewPostDetailActivity.EDIT_COMMENT_REQUEST_CODE); - } else { - activity.startActivityForResult(intent, ViewUserDetailActivity.EDIT_COMMENT_REQUEST_CODE); - } - - dismiss(); - }); - - deleteTextView.setOnClickListener(view -> { - dismiss(); - if (activity instanceof ViewPostDetailActivity) { - ((ViewPostDetailActivity) activity).deleteComment(comment.getFullName(), bundle.getInt(EXTRA_POSITION)); - } else if (activity instanceof ViewUserDetailActivity) { - ((ViewUserDetailActivity) activity).deleteComment(comment.getFullName()); - } - }); - } - } - - shareTextView.setOnClickListener(view -> { - dismiss(); - try { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, comment.getPermalink()); - activity.startActivity(Intent.createChooser(intent, getString(R.string.share))); - } catch (ActivityNotFoundException e) { - Toast.makeText(activity, R.string.no_activity_found_for_share, Toast.LENGTH_SHORT).show(); - } - }); - - copyTextView.setOnClickListener(view -> { - dismiss(); - CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); - Bundle copyBundle = new Bundle(); - copyBundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, comment.getCommentMarkdown()); - copyBundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, comment.getCommentRawText()); - copyTextBottomSheetFragment.setArguments(copyBundle); - copyTextBottomSheetFragment.show(activity.getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); - }); - - viewFullMarkdownTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, FullMarkdownActivity.class); - intent.putExtra(FullMarkdownActivity.EXTRA_IS_NSFW, bundle.getBoolean(EXTRA_IS_NSFW, false)); - intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, bundle.getString(EXTRA_COMMENT_MARKDOWN, "")); - activity.startActivity(intent); - - dismiss(); - }); - - reportTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, ReportActivity.class); - intent.putExtra(ReportActivity.EXTRA_SUBREDDIT_NAME, comment.getSubredditName()); - intent.putExtra(ReportActivity.EXTRA_THING_FULLNAME, comment.getFullName()); - activity.startActivity(intent); - - dismiss(); - }); - - if ("[deleted]".equals(comment.getAuthor()) || - "[deleted]".equals(comment.getCommentRawText()) || - "[removed]".equals(comment.getCommentRawText()) - ) { - seeRemovedTextView.setVisibility(View.VISIBLE); - - seeRemovedTextView.setOnClickListener(view -> { - dismiss(); - if (activity instanceof ViewPostDetailActivity) { - ((ViewPostDetailActivity) activity).showRemovedComment(comment, bundle.getInt(EXTRA_POSITION)); - } - }); - } - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (AppCompatActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CopyTextBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CopyTextBottomSheetFragment.java deleted file mode 100644 index 83cb6569..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CopyTextBottomSheetFragment.java +++ /dev/null @@ -1,115 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; - -/** - * A simple {@link Fragment} subclass. - */ -public class CopyTextBottomSheetFragment extends RoundedBottomSheetDialogFragment { - public static final String EXTRA_RAW_TEXT = "ERT"; - public static final String EXTRA_MARKDOWN = "EM"; - - @BindView(R.id.copy_raw_text_text_view_copy_text_bottom_sheet_fragment) - TextView copyRawTextTextView; - @BindView(R.id.copy_markdown_text_view_copy_text_bottom_sheet_fragment) - TextView copyMarkdownTextView; - @BindView(R.id.copy_all_raw_text_text_view_copy_text_bottom_sheet_fragment) - TextView copyAllRawTextTextView; - @BindView(R.id.copy_all_markdown_text_view_copy_text_bottom_sheet_fragment) - TextView copyAllMarkdownTextView; - - private Activity activity; - - public CopyTextBottomSheetFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_copy_text_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - String rawText = getArguments().getString(EXTRA_RAW_TEXT); - String markdownText = getArguments().getString(EXTRA_MARKDOWN); - - copyRawTextTextView.setOnClickListener(view -> { - showCopyDialog(rawText); - dismiss(); - }); - - copyAllRawTextTextView.setOnClickListener(view -> { - copyText(rawText); - dismiss(); - }); - - if (markdownText != null) { - copyMarkdownTextView.setOnClickListener(view -> { - showCopyDialog(markdownText); - dismiss(); - }); - - copyAllMarkdownTextView.setOnClickListener(view -> { - copyText(markdownText); - dismiss(); - }); - } else { - copyMarkdownTextView.setVisibility(View.GONE); - copyAllMarkdownTextView.setVisibility(View.GONE); - } - - return rootView; - } - - private void showCopyDialog(String text) { - LayoutInflater inflater = activity.getLayoutInflater(); - View layout = inflater.inflate(R.layout.copy_text_material_dialog, null); - TextView textView = layout.findViewById(R.id.text_view_copy_text_material_dialog); - textView.setText(text); - new MaterialAlertDialogBuilder(activity, R.style.CopyTextMaterialAlertDialogTheme) - .setTitle(R.string.copy_text) - .setView(layout) - .setPositiveButton(R.string.copy_all, (dialogInterface, i) -> copyText(text)) - .setNegativeButton(R.string.cancel, null) - .show(); - } - - private void copyText(String text) { - ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard != null) { - ClipData clip = ClipData.newPlainText("simple text", text); - clipboard.setPrimaryClip(clip); - Toast.makeText(activity, R.string.copy_success, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(activity, R.string.copy_link_failed, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CreateThemeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CreateThemeBottomSheetFragment.java deleted file mode 100644 index 111916d3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CreateThemeBottomSheetFragment.java +++ /dev/null @@ -1,90 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.CustomizeThemeActivity; -import ml.docilealligator.infinityforreddit.R; - -/** - * A simple {@link Fragment} subclass. - */ -public class CreateThemeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - @BindView(R.id.import_theme_text_view_create_theme_bottom_sheet_fragment) - TextView importTextView; - @BindView(R.id.light_theme_text_view_create_theme_bottom_sheet_fragment) - TextView lightThemeTextView; - @BindView(R.id.dark_theme_text_view_create_theme_bottom_sheet_fragment) - TextView darkThemeTextView; - @BindView(R.id.amoled_theme_text_view_create_theme_bottom_sheet_fragment) - TextView amoledThemeTextView; - private Activity activity; - - public interface SelectBaseThemeBottomSheetFragmentListener { - void importTheme(); - } - - public CreateThemeBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_create_theme_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - importTextView.setOnClickListener(view -> { - ((SelectBaseThemeBottomSheetFragmentListener) activity).importTheme(); - dismiss(); - }); - - lightThemeTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); - intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, getString(R.string.theme_name_indigo)); - startActivity(intent); - dismiss(); - }); - - darkThemeTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); - intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, getString(R.string.theme_name_indigo_dark)); - startActivity(intent); - dismiss(); - }); - - amoledThemeTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); - intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, getString(R.string.theme_name_indigo_amoled)); - startActivity(intent); - dismiss(); - }); - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CustomThemeOptionsBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CustomThemeOptionsBottomSheetFragment.java deleted file mode 100644 index b9a17fef..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/CustomThemeOptionsBottomSheetFragment.java +++ /dev/null @@ -1,91 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -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.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.CustomizeThemeActivity; -import ml.docilealligator.infinityforreddit.R; - -/** - * A simple {@link Fragment} subclass. - */ -public class CustomThemeOptionsBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_THEME_NAME = "ETN"; - @BindView(R.id.theme_name_text_view_custom_theme_options_bottom_sheet_fragment) - TextView themeNameTextView; - @BindView(R.id.edit_theme_text_view_custom_theme_options_bottom_sheet_fragment) - TextView editThemeTextView; - @BindView(R.id.share_theme_text_view_custom_theme_options_bottom_sheet_fragment) - TextView shareThemeTextView; - @BindView(R.id.change_theme_name_text_view_custom_theme_options_bottom_sheet_fragment) - TextView changeThemeNameTextView; - @BindView(R.id.delete_theme_text_view_custom_theme_options_bottom_sheet_fragment) - TextView deleteTextView; - private String themeName; - private Activity activity; - - public CustomThemeOptionsBottomSheetFragment() { - // Required empty public constructor - } - - public interface CustomThemeOptionsBottomSheetFragmentListener { - void changeName(String oldThemeName); - void shareTheme(String themeName); - void delete(String themeName); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_custom_theme_options_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - themeName = getArguments().getString(EXTRA_THEME_NAME); - themeNameTextView.setText(themeName); - - editThemeTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, themeName); - startActivity(intent); - dismiss(); - }); - - shareThemeTextView.setOnClickListener(view -> { - ((CustomThemeOptionsBottomSheetFragmentListener) activity).shareTheme(themeName); - dismiss(); - }); - - changeThemeNameTextView.setOnClickListener(view -> { - ((CustomThemeOptionsBottomSheetFragmentListener) activity).changeName(themeName); - dismiss(); - }); - - deleteTextView.setOnClickListener(view -> { - ((CustomThemeOptionsBottomSheetFragmentListener) activity).delete(themeName); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (AppCompatActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FABMoreOptionsBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FABMoreOptionsBottomSheetFragment.java deleted file mode 100644 index 2924f34c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FABMoreOptionsBottomSheetFragment.java +++ /dev/null @@ -1,111 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; - -public class FABMoreOptionsBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final int FAB_OPTION_SUBMIT_POST = 0; - public static final int FAB_OPTION_REFRESH = 1; - public static final int FAB_OPTION_CHANGE_SORT_TYPE = 2; - public static final int FAB_OPTION_CHANGE_POST_LAYOUT = 3; - public static final int FAB_OPTION_SEARCH = 4; - public static final int FAB_OPTION_GO_TO_SUBREDDIT = 5; - public static final int FAB_OPTION_GO_TO_USER = 6; - public static final int FAB_RANDOM = 7; - - @BindView(R.id.submit_post_text_view_fab_more_options_bottom_sheet_fragment) - TextView submitPostTextView; - @BindView(R.id.refresh_text_view_fab_more_options_bottom_sheet_fragment) - TextView refreshTextView; - @BindView(R.id.change_sort_type_text_view_fab_more_options_bottom_sheet_fragment) - TextView changeSortTypeTextView; - @BindView(R.id.change_post_layout_text_view_fab_more_options_bottom_sheet_fragment) - TextView changePostLayoutTextView; - @BindView(R.id.search_text_view_fab_more_options_bottom_sheet_fragment) - TextView searchTextView; - @BindView(R.id.go_to_subreddit_text_view_fab_more_options_bottom_sheet_fragment) - TextView goToSubredditTextView; - @BindView(R.id.go_to_user_text_view_fab_more_options_bottom_sheet_fragment) - TextView goToUserTextView; - @BindView(R.id.random_text_view_fab_more_options_bottom_sheet_fragment) - TextView randomTextView; - private FABOptionSelectionCallback activity; - - public FABMoreOptionsBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_fab_more_options_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); - - submitPostTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_OPTION_SUBMIT_POST); - dismiss(); - }); - - refreshTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_OPTION_REFRESH); - dismiss(); - }); - - changeSortTypeTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_OPTION_CHANGE_SORT_TYPE); - dismiss(); - }); - - changePostLayoutTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_OPTION_CHANGE_POST_LAYOUT); - dismiss(); - }); - - searchTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_OPTION_SEARCH); - dismiss(); - }); - - goToSubredditTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_OPTION_GO_TO_SUBREDDIT); - dismiss(); - }); - - goToUserTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_OPTION_GO_TO_USER); - dismiss(); - }); - - randomTextView.setOnClickListener(view -> { - activity.fabOptionSelected(FAB_RANDOM); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (FABOptionSelectionCallback) context; - } - - public interface FABOptionSelectionCallback { - void fabOptionSelected(int option); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FlairBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FlairBottomSheetFragment.java deleted file mode 100644 index 1856eb68..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/FlairBottomSheetFragment.java +++ /dev/null @@ -1,125 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.google.android.material.bottomsheet.BottomSheetDialogFragment; - -import java.util.ArrayList; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.FlairBottomSheetRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FetchFlairs; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import retrofit2.Retrofit; - - -/** - * A simple {@link Fragment} subclass. - */ -public class FlairBottomSheetFragment extends BottomSheetDialogFragment { - - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - @BindView(R.id.progress_bar_flair_bottom_sheet_fragment) - ProgressBar progressBar; - @BindView(R.id.error_text_view_flair_bottom_sheet_fragment) - TextView errorTextView; - @BindView(R.id.recycler_view_bottom_sheet_fragment) - RecyclerView recyclerView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String mAccessToken; - private String mSubredditName; - private Activity mActivity; - private FlairBottomSheetRecyclerViewAdapter mAdapter; - - public FlairBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_flair_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - mAdapter = new FlairBottomSheetRecyclerViewAdapter(mActivity, mCustomThemeWrapper, flair -> { - ((FlairSelectionCallback) mActivity).flairSelected(flair); - dismiss(); - }); - - recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); - recyclerView.setAdapter(mAdapter); - - mAccessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); - mSubredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); - - fetchFlairs(); - - return rootView; - } - - private void fetchFlairs() { - FetchFlairs.fetchFlairsInSubreddit(mOauthRetrofit, mAccessToken, - mSubredditName, new FetchFlairs.FetchFlairsInSubredditListener() { - @Override - public void fetchSuccessful(ArrayList flairs) { - progressBar.setVisibility(View.GONE); - if (flairs == null || flairs.size() == 0) { - errorTextView.setVisibility(View.VISIBLE); - errorTextView.setText(R.string.no_flair); - } else { - errorTextView.setVisibility(View.GONE); - mAdapter.changeDataset(flairs); - } - } - - @Override - public void fetchFailed() { - progressBar.setVisibility(View.GONE); - errorTextView.setVisibility(View.VISIBLE); - errorTextView.setText(R.string.error_loading_flairs); - errorTextView.setOnClickListener(view -> fetchFlairs()); - } - }); - } - - public interface FlairSelectionCallback { - void flairSelected(Flair flair); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mActivity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/MultiRedditOptionsBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/MultiRedditOptionsBottomSheetFragment.java deleted file mode 100644 index 8c7d49cd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/MultiRedditOptionsBottomSheetFragment.java +++ /dev/null @@ -1,72 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.EditMultiRedditActivity; -import ml.docilealligator.infinityforreddit.Activity.SubscribedThingListingActivity; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiReddit; -import ml.docilealligator.infinityforreddit.R; - -/** - * A simple {@link Fragment} subclass. - */ -public class MultiRedditOptionsBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_MULTI_REDDIT = "EMR"; - - @BindView(R.id.edit_multi_reddit_text_view_multi_reddit_options_bottom_sheet_fragment) - TextView editMultiRedditTextView; - @BindView(R.id.delete_multi_reddit_text_view_multi_reddit_options_bottom_sheet_fragment) - TextView deleteMultiRedditTextView; - private SubscribedThingListingActivity subscribedThingListingActivity; - - public MultiRedditOptionsBottomSheetFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_multi_reddit_options_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); - - MultiReddit multiReddit = getArguments().getParcelable(EXTRA_MULTI_REDDIT); - - editMultiRedditTextView.setOnClickListener(view -> { - if (multiReddit != null) { - Intent editIntent = new Intent(subscribedThingListingActivity, EditMultiRedditActivity.class); - editIntent.putExtra(EditMultiRedditActivity.EXTRA_MULTI_PATH, multiReddit.getPath()); - startActivity(editIntent); - } - dismiss(); - }); - - deleteMultiRedditTextView.setOnClickListener(view -> { - subscribedThingListingActivity.deleteMultiReddit(multiReddit); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - subscribedThingListingActivity = (SubscribedThingListingActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostCommentSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostCommentSortTypeBottomSheetFragment.java deleted file mode 100644 index da747efd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostCommentSortTypeBottomSheetFragment.java +++ /dev/null @@ -1,119 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; - -/** - * A simple {@link Fragment} subclass. - */ -public class PostCommentSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - @BindView(R.id.best_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView bestTypeTextView; - @BindView(R.id.confidence_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView confidenceTypeTextView; - @BindView(R.id.top_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView topTypeTextView; - @BindView(R.id.new_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView newTypeTextView; - @BindView(R.id.controversial_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView controversialTypeTextView; - @BindView(R.id.old_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView oldTypeTextView; - @BindView(R.id.random_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView randomTypeTextView; - @BindView(R.id.qa_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView qaTypeTextView; - @BindView(R.id.live_type_text_view_post_comment_sort_type_bottom_sheet_fragment) - TextView liveTypeTextView; - private Activity activity; - public PostCommentSortTypeBottomSheetFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_post_comment_sort_type_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - bestTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.BEST)); - dismiss(); - }); - - confidenceTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.CONFIDENCE)); - dismiss(); - }); - - topTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.TOP)); - dismiss(); - }); - - newTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); - dismiss(); - }); - - controversialTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.CONTROVERSIAL)); - dismiss(); - }); - - oldTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.OLD)); - dismiss(); - }); - - randomTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.RANDOM)); - dismiss(); - }); - - qaTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.QA)); - dismiss(); - }); - - liveTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.LIVE)); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostLayoutBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostLayoutBottomSheetFragment.java deleted file mode 100644 index c0873a14..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostLayoutBottomSheetFragment.java +++ /dev/null @@ -1,65 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -/** - * A simple {@link Fragment} subclass. - */ -public class PostLayoutBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - @BindView(R.id.card_layout_text_view_post_layout_bottom_sheet_fragment) - TextView cardLayoutTextView; - @BindView(R.id.compact_layout_text_view_post_layout_bottom_sheet_fragment) - TextView compactLayoutTextView; - private Activity activity; - public PostLayoutBottomSheetFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_post_layot_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - cardLayoutTextView.setOnClickListener(view -> { - ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_CARD); - dismiss(); - }); - compactLayoutTextView.setOnClickListener(view -> { - ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_COMPACT); - dismiss(); - }); - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (Activity) context; - } - - public interface PostLayoutSelectionCallback { - void postLayoutSelected(int postLayout); - } - -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostTypeBottomSheetFragment.java deleted file mode 100644 index 328aeec2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/PostTypeBottomSheetFragment.java +++ /dev/null @@ -1,91 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; - - -/** - * A simple {@link Fragment} subclass. - */ -public class PostTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final int TYPE_TEXT = 0; - public static final int TYPE_LINK = 1; - public static final int TYPE_IMAGE = 2; - public static final int TYPE_VIDEO = 3; - @BindView(R.id.text_type_linear_layout_post_type_bottom_sheet_fragment) - TextView textTypeTextView; - @BindView(R.id.link_type_linear_layout_post_type_bottom_sheet_fragment) - TextView linkTypeTextView; - @BindView(R.id.image_type_linear_layout_post_type_bottom_sheet_fragment) - TextView imageTypeTextView; - @BindView(R.id.video_type_linear_layout_post_type_bottom_sheet_fragment) - TextView videoTypeTextView; - private Activity activity; - - public PostTypeBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_post_type_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - textTypeTextView.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_TEXT); - dismiss(); - }); - - linkTypeTextView.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_LINK); - dismiss(); - }); - - imageTypeTextView.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_IMAGE); - dismiss(); - }); - - videoTypeTextView.setOnClickListener(view -> { - ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_VIDEO); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (Activity) context; - } - - public interface PostTypeSelectionCallback { - void postTypeSelected(int postType); - } - -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/RandomBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/RandomBottomSheetFragment.java deleted file mode 100644 index 56763627..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/RandomBottomSheetFragment.java +++ /dev/null @@ -1,88 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; - -public class RandomBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_IS_NSFW = "EIN"; - public static final int RANDOM_SUBREDDIT = 0; - public static final int RANDOM_POST = 1; - public static final int RANDOM_NSFW_SUBREDDIT = 2; - public static final int RANDOM_NSFW_POST = 3; - - @BindView(R.id.random_subreddit_text_view_random_bottom_sheet_fragment) - TextView randomSubredditTextView; - @BindView(R.id.random_post_text_view_random_bottom_sheet_fragment) - TextView randomPostTextView; - @BindView(R.id.random_nsfw_subreddit_text_view_random_bottom_sheet_fragment) - TextView randomNSFWSubredditTextView; - @BindView(R.id.random_nsfw_post_text_view_random_bottom_sheet_fragment) - TextView randomNSFWPostTextView; - - private RandomOptionSelectionCallback activity; - - public RandomBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_random_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); - - boolean isNSFW = getArguments().getBoolean(EXTRA_IS_NSFW, false); - - if (!isNSFW) { - randomNSFWSubredditTextView.setVisibility(View.GONE); - randomNSFWPostTextView.setVisibility(View.GONE); - } else { - randomNSFWSubredditTextView.setOnClickListener(view -> { - activity.randomOptionSelected(RANDOM_NSFW_SUBREDDIT); - dismiss(); - }); - - randomNSFWPostTextView.setOnClickListener(view -> { - activity.randomOptionSelected(RANDOM_NSFW_POST); - dismiss(); - }); - } - - randomSubredditTextView.setOnClickListener(view -> { - activity.randomOptionSelected(RANDOM_SUBREDDIT); - dismiss(); - }); - - randomPostTextView.setOnClickListener(view -> { - activity.randomOptionSelected(RANDOM_POST); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (RandomOptionSelectionCallback) context; - } - - public interface RandomOptionSelectionCallback { - void randomOptionSelected(int option); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchPostSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchPostSortTypeBottomSheetFragment.java deleted file mode 100644 index 12f97c9e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchPostSortTypeBottomSheetFragment.java +++ /dev/null @@ -1,90 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; - - -/** - * A simple {@link Fragment} subclass. - */ -public class SearchPostSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - @BindView(R.id.relevance_type_text_view_search_sort_type_bottom_sheet_fragment) - TextView relevanceTypeTextView; - @BindView(R.id.hot_type_text_view_search_sort_type_bottom_sheet_fragment) - TextView hotTypeTextView; - @BindView(R.id.top_type_text_view_search_sort_type_bottom_sheet_fragment) - TextView topTypeTextView; - @BindView(R.id.new_type_text_view_search_sort_type_bottom_sheet_fragment) - TextView newTypeTextView; - @BindView(R.id.comments_type_text_view_search_sort_type_bottom_sheet_fragment) - TextView commentsTypeTextView; - private Activity activity; - public SearchPostSortTypeBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_search_post_sort_type_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - relevanceTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.RELEVANCE.name()); - dismiss(); - }); - - hotTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.HOT.name()); - dismiss(); - }); - - topTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.TOP.name()); - dismiss(); - }); - - newTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); - dismiss(); - }); - - commentsTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.COMMENTS.name()); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchUserAndSubredditSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchUserAndSubredditSortTypeBottomSheetFragment.java deleted file mode 100644 index 0fad6d7b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SearchUserAndSubredditSortTypeBottomSheetFragment.java +++ /dev/null @@ -1,76 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; - - -/** - * A simple {@link Fragment} subclass. - */ -public class SearchUserAndSubredditSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_FRAGMENT_POSITION = "EFP"; - @BindView(R.id.relevance_type_text_view_search_user_and_subreddit_sort_type_bottom_sheet_fragment) - TextView relevanceTypeTextView; - @BindView(R.id.activity_type_text_view_search_user_and_subreddit_sort_type_bottom_sheet_fragment) - TextView activityTypeTextView; - private Activity activity; - public SearchUserAndSubredditSortTypeBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_search_user_and_subreddit_sort_type_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - int position = getArguments() != null ? getArguments().getInt(EXTRA_FRAGMENT_POSITION) : -1; - if(position < 0) { - dismiss(); - return rootView; - } - - relevanceTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).searchUserAndSubredditSortTypeSelected(new SortType(SortType.Type.RELEVANCE), position); - dismiss(); - }); - - activityTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).searchUserAndSubredditSortTypeSelected(new SortType(SortType.Type.ACTIVITY), position); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SetAsWallpaperBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SetAsWallpaperBottomSheetFragment.java deleted file mode 100644 index db6e80e9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SetAsWallpaperBottomSheetFragment.java +++ /dev/null @@ -1,79 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; - -public class SetAsWallpaperBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_VIEW_PAGER_POSITION = "EVPP"; - - @BindView(R.id.home_screen_text_view_set_as_wallpaper_bottom_sheet_fragment) - TextView homeScreenTextvView; - @BindView(R.id.lock_screen_text_view_set_as_wallpaper_bottom_sheet_fragment) - TextView lockScreenTextView; - @BindView(R.id.both_text_view_set_as_wallpaper_bottom_sheet_fragment) - TextView bothTextView; - private Activity mActivity; - - public SetAsWallpaperBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_set_as_wallpaper_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - Bundle bundle = getArguments(); - int viewPagerPosition = bundle == null ? -1 : bundle.getInt(EXTRA_VIEW_PAGER_POSITION); - - bothTextView.setOnClickListener(view -> { - if (mActivity instanceof SetAsWallpaperCallback) { - ((SetAsWallpaperCallback) mActivity).setToBoth(viewPagerPosition); - } - dismiss(); - }); - - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { - homeScreenTextvView.setVisibility(View.VISIBLE); - lockScreenTextView.setVisibility(View.VISIBLE); - - homeScreenTextvView.setOnClickListener(view -> { - if (mActivity instanceof SetAsWallpaperCallback) { - ((SetAsWallpaperCallback) mActivity).setToHomeScreen(viewPagerPosition); - } - dismiss(); - }); - - lockScreenTextView.setOnClickListener(view -> { - if (mActivity instanceof SetAsWallpaperCallback) { - ((SetAsWallpaperCallback) mActivity).setToLockScreen(viewPagerPosition); - } - dismiss(); - }); - } - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.mActivity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/ShareLinkBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/ShareLinkBottomSheetFragment.java deleted file mode 100644 index 1214dbc8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/ShareLinkBottomSheetFragment.java +++ /dev/null @@ -1,142 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.ActivityNotFoundException; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.R; - -/** - * A simple {@link Fragment} subclass. - */ -public class ShareLinkBottomSheetFragment extends RoundedBottomSheetDialogFragment { - public static final String EXTRA_POST_LINK = "EPL"; - public static final String EXTRA_MEDIA_LINK = "EML"; - public static final String EXTRA_MEDIA_TYPE = "EMT"; - - @BindView(R.id.share_post_link_text_view_share_link_bottom_sheet_fragment) - TextView sharePostLinkTextView; - @BindView(R.id.share_media_link_text_view_share_link_bottom_sheet_fragment) - TextView shareMediaLinkTextView; - @BindView(R.id.copy_post_link_text_view_share_link_bottom_sheet_fragment) - TextView copyPostLinkTextView; - @BindView(R.id.copy_media_link_text_view_share_link_bottom_sheet_fragment) - TextView copyMediaLinkTextView; - - private Activity activity; - - public ShareLinkBottomSheetFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_share_link_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); - - String postLink = getArguments().getString(EXTRA_POST_LINK); - String mediaLink = getArguments().containsKey(EXTRA_MEDIA_LINK) ? getArguments().getString(EXTRA_MEDIA_LINK) : null; - - if (mediaLink != null) { - shareMediaLinkTextView.setVisibility(View.VISIBLE); - copyMediaLinkTextView.setVisibility(View.VISIBLE); - - int mediaType = getArguments().getInt(EXTRA_MEDIA_TYPE); - switch (mediaType) { - case Post.IMAGE_TYPE: - shareMediaLinkTextView.setText(R.string.share_image_link); - copyMediaLinkTextView.setText(R.string.copy_image_link); - shareMediaLinkTextView.setCompoundDrawablesWithIntrinsicBounds( - activity.getDrawable(R.drawable.ic_image_24dp), null, null, null); - break; - case Post.GIF_TYPE: - shareMediaLinkTextView.setText(R.string.share_gif_link); - copyMediaLinkTextView.setText(R.string.copy_gif_link); - shareMediaLinkTextView.setCompoundDrawablesWithIntrinsicBounds( - activity.getDrawable(R.drawable.ic_image_24dp), null, null, null); - break; - case Post.VIDEO_TYPE: - shareMediaLinkTextView.setText(R.string.share_video_link); - copyMediaLinkTextView.setText(R.string.copy_video_link); - shareMediaLinkTextView.setCompoundDrawablesWithIntrinsicBounds( - activity.getDrawable(R.drawable.ic_outline_video_24dp), null, null, null); - break; - case Post.LINK_TYPE: - case Post.NO_PREVIEW_LINK_TYPE: - shareMediaLinkTextView.setText(R.string.share_link); - copyMediaLinkTextView.setText(R.string.copy_link); - break; - } - - shareMediaLinkTextView.setOnClickListener(view -> { - shareLink(mediaLink); - dismiss(); - }); - copyMediaLinkTextView.setOnClickListener(view -> { - copyLink(mediaLink); - dismiss(); - }); - } - - sharePostLinkTextView.setOnClickListener(view -> { - shareLink(postLink); - dismiss(); - }); - copyPostLinkTextView.setOnClickListener(view -> { - copyLink(postLink); - dismiss(); - }); - return rootView; - } - - private void shareLink(String link) { - try { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, link); - activity.startActivity(Intent.createChooser(intent, getString(R.string.share))); - } catch (ActivityNotFoundException e) { - Toast.makeText(activity, R.string.no_activity_found_for_share, Toast.LENGTH_SHORT).show(); - } - } - - private void copyLink(String link) { - ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard != null) { - ClipData clip = ClipData.newPlainText("simple text", link); - clipboard.setPrimaryClip(clip); - Toast.makeText(activity, R.string.copy_success, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(activity, R.string.copy_link_failed, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (AppCompatActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTimeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTimeBottomSheetFragment.java deleted file mode 100644 index f2f1da4d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTimeBottomSheetFragment.java +++ /dev/null @@ -1,112 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; - -/** - * A simple {@link Fragment} subclass. - */ -public class SortTimeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_SORT_TYPE = "EST"; - - @BindView(R.id.hour_text_view_sort_time_bottom_sheet_fragment) - TextView hourTextView; - @BindView(R.id.day_text_view_sort_time_bottom_sheet_fragment) - TextView dayTextView; - @BindView(R.id.week_text_view_sort_time_bottom_sheet_fragment) - TextView weekTextView; - @BindView(R.id.month_text_view_sort_time_bottom_sheet_fragment) - TextView monthTextView; - @BindView(R.id.year_text_view_sort_time_bottom_sheet_fragment) - TextView yearTextView; - @BindView(R.id.all_time_text_view_sort_time_bottom_sheet_fragment) - TextView allTimeTextView; - private Activity activity; - public SortTimeBottomSheetFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_sort_time_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - String sortType = getArguments() != null ? getArguments().getString(EXTRA_SORT_TYPE) : null; - if(sortType == null) { - dismiss(); - return rootView; - } - - hourTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity) - .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.HOUR)); - dismiss(); - }); - - dayTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity) - .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.DAY)); - dismiss(); - }); - - weekTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity) - .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.WEEK)); - dismiss(); - }); - - monthTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity) - .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.MONTH)); - dismiss(); - }); - - yearTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity) - .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.YEAR)); - dismiss(); - }); - - allTimeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity) - .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.ALL)); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTypeBottomSheetFragment.java deleted file mode 100644 index d86bb207..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/SortTypeBottomSheetFragment.java +++ /dev/null @@ -1,102 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; - - -/** - * A simple {@link Fragment} subclass. - */ -public class SortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_NO_BEST_TYPE = "ENBT"; - @BindView(R.id.best_type_text_view_sort_type_bottom_sheet_fragment) - TextView bestTypeTextView; - @BindView(R.id.hot_type_text_view_sort_type_bottom_sheet_fragment) - TextView hotTypeTextView; - @BindView(R.id.new_type_text_view_sort_type_bottom_sheet_fragment) - TextView newTypeTextView; - @BindView(R.id.rising_type_text_view_sort_type_bottom_sheet_fragment) - TextView risingTypeTextView; - @BindView(R.id.top_type_text_view_sort_type_bottom_sheet_fragment) - TextView topTypeTextView; - @BindView(R.id.controversial_type_text_view_sort_type_bottom_sheet_fragment) - TextView controversialTypeTextView; - private Activity activity; - public SortTypeBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_sort_type_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - if (getArguments() == null || getArguments().getBoolean(EXTRA_NO_BEST_TYPE)) { - bestTypeTextView.setVisibility(View.GONE); - } else { - bestTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.BEST)); - dismiss(); - }); - } - - hotTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.HOT)); - dismiss(); - }); - - newTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); - dismiss(); - }); - - risingTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.RISING)); - dismiss(); - }); - - topTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.TOP.name()); - dismiss(); - }); - - controversialTypeTextView.setOnClickListener(view -> { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.CONTROVERSIAL.name()); - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UrlMenuBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UrlMenuBottomSheetFragment.java deleted file mode 100644 index f2812232..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UrlMenuBottomSheetFragment.java +++ /dev/null @@ -1,87 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - -import android.app.Activity; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.R; - -public class UrlMenuBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - public static final String EXTRA_URL = "EU"; - @BindView(R.id.open_link_text_view_url_menu_bottom_sheet_fragment) - TextView openLinkTextView; - @BindView(R.id.copy_link_text_view_url_menu_bottom_sheet_fragment) - TextView copyLinkTextView; - @BindView(R.id.share_link_text_view_url_menu_bottom_sheet_fragment) - TextView shareLinkTextView; - private Activity activity; - - public UrlMenuBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_url_menu_bottom_sheet, container, false); - ButterKnife.bind(this, rootView); - - String url = getArguments().getString(EXTRA_URL); - - openLinkTextView.setOnClickListener(view -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse(url)); - activity.startActivity(intent); - dismiss(); - }); - - copyLinkTextView.setOnClickListener(view -> { - ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); - if (clipboard != null) { - ClipData clip = ClipData.newPlainText("simple text", url); - clipboard.setPrimaryClip(clip); - Toast.makeText(activity, R.string.copy_success, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(activity, R.string.copy_link_failed, Toast.LENGTH_SHORT).show(); - } - dismiss(); - }); - - shareLinkTextView.setOnClickListener(view -> { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, url); - if (intent.resolveActivity(activity.getPackageManager()) != null) { - startActivity(intent); - } else { - Toast.makeText(activity, R.string.no_app, Toast.LENGTH_SHORT).show(); - } - dismiss(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UserThingSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UserThingSortTypeBottomSheetFragment.java deleted file mode 100644 index 2d6b7cae..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BottomSheetFragment/UserThingSortTypeBottomSheetFragment.java +++ /dev/null @@ -1,86 +0,0 @@ -package ml.docilealligator.infinityforreddit.BottomSheetFragment; - - -import android.app.Activity; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; - - -/** - * A simple {@link Fragment} subclass. - */ -public class UserThingSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { - - @BindView(R.id.new_type_text_view_user_thing_sort_type_bottom_sheet_fragment) - TextView newTypeTextView; - @BindView(R.id.hot_type_text_view_user_thing_sort_type_bottom_sheet_fragment) - TextView hotTypeTextView; - @BindView(R.id.top_type_text_view_user_thing_sort_type_bottom_sheet_fragment) - TextView topTypeTextView; - @BindView(R.id.controversial_type_text_view_user_thing_sort_type_bottom_sheet_fragment) - TextView controversialTypeTextView; - public UserThingSortTypeBottomSheetFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_user_thing_sort_type_bottom_sheet, container, false); - - ButterKnife.bind(this, rootView); - - Activity activity = getActivity(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { - rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); - } - - newTypeTextView.setOnClickListener(view -> { - if (activity != null) { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); - } - dismiss(); - }); - - hotTypeTextView.setOnClickListener(view -> { - if (activity != null) { - ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.HOT)); - } - dismiss(); - }); - - topTypeTextView.setOnClickListener(view -> { - if (activity != null) { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.TOP.name()); - } - dismiss(); - }); - - controversialTypeTextView.setOnClickListener(view -> { - if (activity != null) { - ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.CONTROVERSIAL.name()); - } - dismiss(); - }); - - return rootView; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/BroadcastReceiver/NetworkWifiStatusReceiver.java b/app/src/main/java/ml/docilealligator/infinityforreddit/BroadcastReceiver/NetworkWifiStatusReceiver.java deleted file mode 100644 index fb8d3ae4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/BroadcastReceiver/NetworkWifiStatusReceiver.java +++ /dev/null @@ -1,22 +0,0 @@ -package ml.docilealligator.infinityforreddit.BroadcastReceiver; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -public class NetworkWifiStatusReceiver extends BroadcastReceiver { - private NetworkWifiStatusReceiverListener networkWifiStatusReceiverListener; - - public interface NetworkWifiStatusReceiverListener { - void networkStatusChange(); - } - - public NetworkWifiStatusReceiver(NetworkWifiStatusReceiverListener listener) { - networkWifiStatusReceiverListener = listener; - } - - @Override - public void onReceive(Context context, Intent intent) { - networkWifiStatusReceiverListener.networkStatusChange(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/Comment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/Comment.java deleted file mode 100644 index 3e5b5328..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/Comment.java +++ /dev/null @@ -1,390 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.Utils.APIUtils; - -public class Comment implements Parcelable { - public static final int VOTE_TYPE_NO_VOTE = 0; - public static final int VOTE_TYPE_UPVOTE = 1; - public static final int VOTE_TYPE_DOWNVOTE = -1; - public static final Creator CREATOR = new Creator() { - @Override - public Comment createFromParcel(Parcel in) { - return new Comment(in); - } - - @Override - public Comment[] newArray(int size) { - return new Comment[size]; - } - }; - private String id; - private String fullName; - private String author; - private String authorFlair; - private String authorFlairHTML; - private String linkAuthor; - private long commentTimeMillis; - private String commentMarkdown; - private String commentRawText; - private String linkId; - private String subredditName; - private String parentId; - private int score; - private int voteType; - private boolean isSubmitter; - private String distinguished; - private String permalink; - private String awards; - private int depth; - private boolean collapsed; - private boolean hasReply; - private boolean scoreHidden; - private boolean saved; - private boolean isExpanded; - private boolean hasExpandedBefore; - private ArrayList children; - private ArrayList moreChildrenFullnames; - private int moreChildrenStartingIndex; - private boolean isPlaceHolder; - private boolean isLoadingMoreChildren; - private boolean loadMoreChildrenFailed; - - public Comment(String id, String fullName, String author, String authorFlair, - String authorFlairHTML, String linkAuthor, - long commentTimeMillis, String commentMarkdown, String commentRawText, - String linkId, String subredditName, String parentId, int score, - int voteType, boolean isSubmitter, String distinguished, String permalink, - String awards, int depth, boolean collapsed, boolean hasReply, - boolean scoreHidden, boolean saved) { - this.id = id; - this.fullName = fullName; - this.author = author; - this.authorFlair = authorFlair; - this.authorFlairHTML = authorFlairHTML; - this.linkAuthor = linkAuthor; - this.commentTimeMillis = commentTimeMillis; - this.commentMarkdown = commentMarkdown; - this.commentRawText = commentRawText; - this.linkId = linkId; - this.subredditName = subredditName; - this.parentId = parentId; - this.score = score; - this.voteType = voteType; - this.isSubmitter = isSubmitter; - this.distinguished = distinguished; - this.permalink = APIUtils.API_BASE_URI + permalink; - this.awards = awards; - this.depth = depth; - this.collapsed = collapsed; - this.hasReply = hasReply; - this.scoreHidden = scoreHidden; - this.saved = saved; - this.isExpanded = false; - this.hasExpandedBefore = false; - moreChildrenStartingIndex = 0; - isPlaceHolder = false; - } - - public Comment(String parentFullName, int depth) { - this.fullName = parentFullName; - this.depth = depth; - isPlaceHolder = true; - isLoadingMoreChildren = false; - loadMoreChildrenFailed = false; - } - - protected Comment(Parcel in) { - id = in.readString(); - fullName = in.readString(); - author = in.readString(); - authorFlair = in.readString(); - authorFlairHTML = in.readString(); - linkAuthor = in.readString(); - commentTimeMillis = in.readLong(); - commentMarkdown = in.readString(); - commentRawText = in.readString(); - linkId = in.readString(); - subredditName = in.readString(); - parentId = in.readString(); - score = in.readInt(); - voteType = in.readInt(); - isSubmitter = in.readByte() != 0; - distinguished = in.readString(); - permalink = in.readString(); - awards = in.readString(); - depth = in.readInt(); - collapsed = in.readByte() != 0; - hasReply = in.readByte() != 0; - scoreHidden = in.readByte() != 0; - isExpanded = in.readByte() != 0; - hasExpandedBefore = in.readByte() != 0; - children = in.readArrayList(Comment.class.getClassLoader()); - moreChildrenFullnames = in.readArrayList(Comment.class.getClassLoader()); - moreChildrenStartingIndex = in.readInt(); - isPlaceHolder = in.readByte() != 0; - isLoadingMoreChildren = in.readByte() != 0; - loadMoreChildrenFailed = in.readByte() != 0; - } - - public String getId() { - return id; - } - - public String getFullName() { - return fullName; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getAuthorFlair() { - return authorFlair; - } - - public String getAuthorFlairHTML() { - return authorFlairHTML; - } - - public String getLinkAuthor() { - return linkAuthor; - } - - public long getCommentTimeMillis() { - return commentTimeMillis; - } - - public String getCommentMarkdown() { - return commentMarkdown; - } - - public void setCommentMarkdown(String commentMarkdown) { - this.commentMarkdown = commentMarkdown; - } - - public String getCommentRawText() { - return commentRawText; - } - - public void setCommentRawText(String commentRawText) { - this.commentRawText = commentRawText; - } - - public String getLinkId() { - return linkId; - } - - public String getSubredditName() { - return subredditName; - } - - public String getParentId() { - return parentId; - } - - public void setParentId(String parentId) { - this.parentId = parentId; - } - - public int getScore() { - return score; - } - - public void setScore(int score) { - this.score = score; - } - - public boolean isSubmitter() { - return isSubmitter; - } - - public boolean isModerator() { - return distinguished != null && distinguished.equals("moderator"); - } - - public String getPermalink() { - return permalink; - } - - public String getAwards() { - return awards; - } - - public void addAwards(String newAwardsHTML) { - awards += newAwardsHTML; - } - - public int getDepth() { - return depth; - } - - public boolean isCollapsed() { - return collapsed; - } - - public boolean hasReply() { - return hasReply; - } - - public void setHasReply(boolean hasReply) { - this.hasReply = hasReply; - } - - public boolean isScoreHidden() { - return scoreHidden; - } - - public boolean isSaved() { - return saved; - } - - public void setSaved(boolean saved) { - this.saved = saved; - } - - public boolean isExpanded() { - return isExpanded; - } - - public void setExpanded(boolean isExpanded) { - this.isExpanded = isExpanded; - if (isExpanded && !hasExpandedBefore) { - hasExpandedBefore = true; - } - } - - public boolean hasExpandedBefore() { - return hasExpandedBefore; - } - - public int getVoteType() { - return voteType; - } - - public void setVoteType(int voteType) { - this.voteType = voteType; - } - - public ArrayList getChildren() { - return children; - } - - public void setChildren(ArrayList children) { - this.children = children; - } - - public void addChildren(ArrayList moreChildren) { - if (children == null || children.size() == 0) { - setChildren(moreChildren); - } else { - if (children.size() > 1 && children.get(children.size() - 1).isPlaceHolder) { - children.addAll(children.size() - 2, moreChildren); - } else { - children.addAll(moreChildren); - } - } - } - - public void addChild(Comment comment) { - addChild(comment, 0); - } - - public void addChild(Comment comment, int position) { - if (children == null) { - children = new ArrayList<>(); - } - children.add(position, comment); - } - - public ArrayList getMoreChildrenFullnames() { - return moreChildrenFullnames; - } - - public void setMoreChildrenFullnames(ArrayList moreChildrenFullnames) { - this.moreChildrenFullnames = moreChildrenFullnames; - } - - public boolean hasMoreChildrenFullnames() { - return moreChildrenFullnames != null; - } - - public void removeMoreChildrenFullnames() { - moreChildrenFullnames.clear(); - } - - public int getMoreChildrenStartingIndex() { - return moreChildrenStartingIndex; - } - - public void setMoreChildrenStartingIndex(int moreChildrenStartingIndex) { - this.moreChildrenStartingIndex = moreChildrenStartingIndex; - } - - public boolean isPlaceHolder() { - return isPlaceHolder; - } - - public boolean isLoadingMoreChildren() { - return isLoadingMoreChildren; - } - - public void setLoadingMoreChildren(boolean isLoadingMoreChildren) { - this.isLoadingMoreChildren = isLoadingMoreChildren; - } - - public boolean isLoadMoreChildrenFailed() { - return loadMoreChildrenFailed; - } - - public void setLoadMoreChildrenFailed(boolean loadMoreChildrenFailed) { - this.loadMoreChildrenFailed = loadMoreChildrenFailed; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(id); - parcel.writeString(fullName); - parcel.writeString(author); - parcel.writeString(authorFlair); - parcel.writeString(authorFlairHTML); - parcel.writeString(linkAuthor); - parcel.writeLong(commentTimeMillis); - parcel.writeString(commentMarkdown); - parcel.writeString(commentRawText); - parcel.writeString(linkId); - parcel.writeString(subredditName); - parcel.writeString(parentId); - parcel.writeInt(score); - parcel.writeInt(voteType); - parcel.writeByte((byte) (isSubmitter ? 1 : 0)); - parcel.writeString(distinguished); - parcel.writeString(permalink); - parcel.writeString(awards); - parcel.writeInt(depth); - parcel.writeByte((byte) (collapsed ? 1 : 0)); - parcel.writeByte((byte) (hasReply ? 1 : 0)); - parcel.writeByte((byte) (scoreHidden ? 1 : 0)); - parcel.writeByte((byte) (isExpanded ? 1 : 0)); - parcel.writeByte((byte) (hasExpandedBefore ? 1 : 0)); - parcel.writeList(children); - parcel.writeList(moreChildrenFullnames); - parcel.writeInt(moreChildrenStartingIndex); - parcel.writeByte((byte) (isPlaceHolder ? 1 : 0)); - parcel.writeByte((byte) (isLoadingMoreChildren ? 1 : 0)); - parcel.writeByte((byte) (loadMoreChildrenFailed ? 1 : 0)); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSource.java deleted file mode 100644 index 35a8ddd2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSource.java +++ /dev/null @@ -1,271 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import android.os.AsyncTask; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.PageKeyedDataSource; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class CommentDataSource extends PageKeyedDataSource { - - private Retrofit retrofit; - private Locale locale; - @Nullable - private String accessToken; - private String username; - private SortType sortType; - private boolean areSavedComments; - - private MutableLiveData paginationNetworkStateLiveData; - private MutableLiveData initialLoadStateLiveData; - private MutableLiveData hasPostLiveData; - - private LoadParams params; - private LoadCallback callback; - - CommentDataSource(Retrofit retrofit, Locale locale, @Nullable String accessToken, String username, SortType sortType, - boolean areSavedComments) { - this.retrofit = retrofit; - this.locale = locale; - this.accessToken = accessToken; - this.username = username; - this.sortType = sortType; - this.areSavedComments = areSavedComments; - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasPostLiveData = new MutableLiveData<>(); - } - - MutableLiveData getPaginationNetworkStateLiveData() { - return paginationNetworkStateLiveData; - } - - MutableLiveData getInitialLoadStateLiveData() { - return initialLoadStateLiveData; - } - - MutableLiveData hasPostLiveData() { - return hasPostLiveData; - } - - void retryLoadingMore() { - loadAfter(params, callback); - } - - @Override - public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { - initialLoadStateLiveData.postValue(NetworkState.LOADING); - - RedditAPI api = retrofit.create(RedditAPI.class); - Call commentsCall; - if (areSavedComments) { - if (sortType.getTime() != null) { - commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, - null, sortType.getType().value, sortType.getTime().value, - APIUtils.getOAuthHeader(accessToken)); - } else { - commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, - null, sortType.getType().value, APIUtils.getOAuthHeader(accessToken)); - } - } else { - if (accessToken == null) { - if (sortType.getTime() != null) { - commentsCall = api.getUserComments(username, null, sortType.getType().value, - sortType.getTime().value); - } else { - commentsCall = api.getUserComments(username, null, sortType.getType().value); - } - } else { - if (sortType.getTime() != null) { - commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), username, - null, sortType.getType().value, sortType.getTime().value); - } else { - commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), username, - null, sortType.getType().value); - } - } - } - commentsCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseCommentAsyncTask(response.body(), locale, new ParseCommentAsyncTask.ParseCommentAsyncTaskListener() { - @Override - public void parseSuccessful(ArrayList comments, String after) { - if (comments.size() == 0) { - hasPostLiveData.postValue(false); - } else { - hasPostLiveData.postValue(true); - } - - if (after == null || after.equals("") || after.equals("null")) { - callback.onResult(comments, null, null); - } else { - callback.onResult(comments, null, after); - } - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void parseFailed() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }).execute(); - } else { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } - - @Override - public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { - - } - - @Override - public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { - this.params = params; - this.callback = callback; - - paginationNetworkStateLiveData.postValue(NetworkState.LOADING); - - RedditAPI api = retrofit.create(RedditAPI.class); - Call commentsCall; - if (areSavedComments) { - if (sortType.getTime() != null) { - commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, params.key, - sortType.getType().value, sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); - } else { - commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, params.key, - sortType.getType().value, APIUtils.getOAuthHeader(accessToken)); - } - } else { - if (accessToken == null) { - if (sortType.getTime() != null) { - commentsCall = api.getUserComments(username, params.key, sortType.getType().value, - sortType.getTime().value); - } else { - commentsCall = api.getUserComments(username, params.key, sortType.getType().value); - } - } else { - if (sortType.getTime() != null) { - commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), - username, params.key, sortType.getType().value, sortType.getTime().value); - } else { - commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), - username, params.key, sortType.getType().value); - } - } - } - commentsCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseCommentAsyncTask(response.body(), locale, new ParseCommentAsyncTask.ParseCommentAsyncTaskListener() { - @Override - public void parseSuccessful(ArrayList comments, String after) { - if (after == null || after.equals("") || after.equals("null")) { - callback.onResult(comments, null); - } else { - callback.onResult(comments, after); - } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void parseFailed() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }).execute(); - } else { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); - } - }); - } - - private static class ParseCommentAsyncTask extends AsyncTask, ArrayList> { - private String after; - private Locale locale; - private JSONArray commentsJSONArray; - private boolean parseFailed; - private ParseCommentAsyncTaskListener parseCommentAsyncTaskListener; - - ParseCommentAsyncTask(String response, Locale locale, ParseCommentAsyncTaskListener parseCommentAsyncTaskListener) { - this.locale = locale; - this.parseCommentAsyncTaskListener = parseCommentAsyncTaskListener; - try { - JSONObject data = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY); - commentsJSONArray = data.getJSONArray(JSONUtils.CHILDREN_KEY); - after = data.getString(JSONUtils.AFTER_KEY); - parseFailed = false; - } catch (JSONException e) { - parseFailed = true; - e.printStackTrace(); - } - } - - @Override - protected ArrayList doInBackground(Void... voids) { - if (parseFailed) { - return null; - } - - ArrayList comments = new ArrayList<>(); - for (int i = 0; i < commentsJSONArray.length(); i++) { - try { - JSONObject commentJSON = commentsJSONArray.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - comments.add(ParseComment.parseSingleComment(commentJSON, 0, locale)); - } catch (JSONException ignored) { - } - } - return comments; - } - - @Override - protected void onPostExecute(ArrayList commentData) { - super.onPostExecute(commentData); - if (commentData != null) { - parseCommentAsyncTaskListener.parseSuccessful(commentData, after); - } else { - parseCommentAsyncTaskListener.parseFailed(); - } - } - - interface ParseCommentAsyncTaskListener { - void parseSuccessful(ArrayList comments, String after); - - void parseFailed(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSourceFactory.java deleted file mode 100644 index bd7e5831..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentDataSourceFactory.java +++ /dev/null @@ -1,56 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.DataSource; - -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -class CommentDataSourceFactory extends DataSource.Factory { - private Retrofit retrofit; - private Locale locale; - private String accessToken; - private String username; - private SortType sortType; - private boolean areSavedComments; - - private CommentDataSource commentDataSource; - private MutableLiveData commentDataSourceLiveData; - - CommentDataSourceFactory(Retrofit retrofit, Locale locale, @Nullable String accessToken, - String username, SortType sortType, - boolean areSavedComments) { - this.retrofit = retrofit; - this.locale = locale; - this.accessToken = accessToken; - this.username = username; - this.sortType = sortType; - this.areSavedComments = areSavedComments; - commentDataSourceLiveData = new MutableLiveData<>(); - } - - @NonNull - @Override - public DataSource create() { - commentDataSource = new CommentDataSource(retrofit, locale, accessToken, username, sortType, - areSavedComments); - commentDataSourceLiveData.postValue(commentDataSource); - return commentDataSource; - } - - public MutableLiveData getCommentDataSourceLiveData() { - return commentDataSourceLiveData; - } - - CommentDataSource getCommentDataSource() { - return commentDataSource; - } - - void changeSortType(SortType sortType) { - this.sortType = sortType; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentViewModel.java deleted file mode 100644 index 99832054..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/CommentViewModel.java +++ /dev/null @@ -1,105 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; -import androidx.paging.LivePagedListBuilder; -import androidx.paging.PagedList; - -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -public class CommentViewModel extends ViewModel { - private CommentDataSourceFactory commentDataSourceFactory; - private LiveData paginationNetworkState; - private LiveData initialLoadingState; - private LiveData hasCommentLiveData; - private LiveData> comments; - private MutableLiveData sortTypeLiveData; - - public CommentViewModel(Retrofit retrofit, Locale locale, String accessToken, String username, SortType sortType, - boolean areSavedComments) { - commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, accessToken, username, sortType, - areSavedComments); - - initialLoadingState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(), - CommentDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(), - CommentDataSource::getPaginationNetworkStateLiveData); - hasCommentLiveData = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(), - CommentDataSource::hasPostLiveData); - - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - comments = Transformations.switchMap(sortTypeLiveData, sort -> { - commentDataSourceFactory.changeSortType(sortTypeLiveData.getValue()); - return (new LivePagedListBuilder(commentDataSourceFactory, pagedListConfig)).build(); - }); - } - - public LiveData> getComments() { - return comments; - } - - public LiveData getPaginationNetworkState() { - return paginationNetworkState; - } - - public LiveData getInitialLoadingState() { - return initialLoadingState; - } - - public LiveData hasComment() { - return hasCommentLiveData; - } - - public void refresh() { - commentDataSourceFactory.getCommentDataSource().invalidate(); - } - - public void retryLoadingMore() { - commentDataSourceFactory.getCommentDataSource().retryLoadingMore(); - } - - public void changeSortType(SortType sortType) { - sortTypeLiveData.postValue(sortType); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Retrofit retrofit; - private Locale locale; - private String accessToken; - private String username; - private SortType sortType; - private boolean areSavedComments; - - public Factory(Retrofit retrofit, Locale locale, String accessToken, String username, - SortType sortType, boolean areSavedComments) { - this.retrofit = retrofit; - this.locale = locale; - this.accessToken = accessToken; - this.username = username; - this.sortType = sortType; - this.areSavedComments = areSavedComments; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new CommentViewModel(retrofit, locale, accessToken, username, sortType, areSavedComments); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchComment.java deleted file mode 100644 index 361a5746..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchComment.java +++ /dev/null @@ -1,138 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.ArrayList; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchComment { - public static void fetchComments(Retrofit retrofit, @Nullable String accessToken, String article, - String commentId, String sortType, boolean expandChildren, - Locale locale, FetchCommentListener fetchCommentListener) { - RedditAPI api = retrofit.create(RedditAPI.class); - Call comments; - if (accessToken == null) { - if (commentId == null) { - comments = api.getPostAndCommentsById(article, sortType); - } else { - comments = api.getPostAndCommentsSingleThreadById(article, commentId, sortType); - } - } else { - if (commentId == null) { - comments = api.getPostAndCommentsByIdOauth(article, sortType, APIUtils.getOAuthHeader(accessToken)); - } else { - comments = api.getPostAndCommentsSingleThreadByIdOauth(article, commentId, sortType, - APIUtils.getOAuthHeader(accessToken)); - } - } - - comments.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseComment.parseComment(response.body(), new ArrayList<>(), - locale, expandChildren, new ParseComment.ParseCommentListener() { - @Override - public void onParseCommentSuccess(ArrayList expandedComments, - String parentId, ArrayList moreChildrenFullnames) { - fetchCommentListener.onFetchCommentSuccess(expandedComments, parentId, - moreChildrenFullnames); - } - - @Override - public void onParseCommentFailed() { - fetchCommentListener.onFetchCommentFailed(); - } - }); - } else { - fetchCommentListener.onFetchCommentFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchCommentListener.onFetchCommentFailed(); - } - }); - } - - public static void fetchMoreComment(Retrofit retrofit, @Nullable String accessToken, - ArrayList allChildren, int startingIndex, - int depth, boolean expandChildren, Locale locale, - FetchMoreCommentListener fetchMoreCommentListener) { - if (allChildren == null) { - return; - } - - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < 100; i++) { - if (allChildren.size() <= startingIndex + i) { - break; - } - stringBuilder.append(allChildren.get(startingIndex + i)).append(","); - } - - if (stringBuilder.length() == 0) { - return; - } - - stringBuilder.deleteCharAt(stringBuilder.length() - 1); - - RedditAPI api = retrofit.create(RedditAPI.class); - Call moreComments; - if (accessToken == null) { - moreComments = api.getInfo(stringBuilder.toString()); - } else { - moreComments = api.getInfoOauth(stringBuilder.toString(), APIUtils.getOAuthHeader(accessToken)); - } - - moreComments.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, - depth, expandChildren, new ParseComment.ParseCommentListener() { - @Override - public void onParseCommentSuccess(ArrayList expandedComments, - String parentId, ArrayList moreChildrenFullnames) { - fetchMoreCommentListener.onFetchMoreCommentSuccess(expandedComments, - startingIndex + 100); - } - - @Override - public void onParseCommentFailed() { - fetchMoreCommentListener.onFetchMoreCommentFailed(); - } - }); - } else { - fetchMoreCommentListener.onFetchMoreCommentFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchMoreCommentListener.onFetchMoreCommentFailed(); - } - }); - } - - public interface FetchCommentListener { - void onFetchCommentSuccess(ArrayList expandedComments, String parentId, ArrayList children); - - void onFetchCommentFailed(); - } - - public interface FetchMoreCommentListener { - void onFetchMoreCommentSuccess(ArrayList expandedComments, int childrenStartingIndex); - - void onFetchMoreCommentFailed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchRemovedComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchRemovedComment.java deleted file mode 100644 index ad774da9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/FetchRemovedComment.java +++ /dev/null @@ -1,98 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import android.os.AsyncTask; - -import androidx.annotation.NonNull; - -import org.json.JSONException; -import org.json.JSONObject; - -import ml.docilealligator.infinityforreddit.API.PushshiftAPI; -import ml.docilealligator.infinityforreddit.Comment.Comment; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchRemovedComment { - - public static void fetchRemovedComment(Retrofit retrofit, Comment comment, FetchRemovedCommentListener listener) { - retrofit.create(PushshiftAPI.class).getRemovedComment(comment.getId()) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseCommentAsyncTask(response.body(), comment, listener).execute(); - } else { - listener.fetchFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - t.printStackTrace(); - listener.fetchFailed(); - } - }); - } - - private static Comment parseRemovedComment(JSONObject result, Comment comment) throws JSONException { - String id = result.getString(JSONUtils.ID_KEY); - String author = result.getString(JSONUtils.AUTHOR_KEY); - String body = Utils.modifyMarkdown(result.optString(JSONUtils.BODY_KEY).trim()); - - if ( id.equals(comment.getId()) && - (!author.equals(comment.getAuthor()) || - !body.equals(comment.getCommentRawText())) - ) { - comment.setAuthor(author); - comment.setCommentMarkdown(body); - comment.setCommentRawText(body); - return comment; - } else { - return null; - } - } - - public interface FetchRemovedCommentListener { - void fetchSuccess(Comment comment); - - void fetchFailed(); - } - - private static class ParseCommentAsyncTask extends AsyncTask { - - private String responseBody; - private FetchRemovedCommentListener listener; - Comment comment; - - public ParseCommentAsyncTask(String responseBody, Comment comment, FetchRemovedCommentListener listener) { - this.responseBody = responseBody; - this.comment = comment; - this.listener = listener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject commentJSON = new JSONObject(responseBody).getJSONArray(JSONUtils.DATA_KEY).getJSONObject(0); - comment = parseRemovedComment(commentJSON, comment); - } catch (JSONException e) { - e.printStackTrace(); - comment = null; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (comment != null) - listener.fetchSuccess(comment); - else - listener.fetchFailed(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/ParseComment.java deleted file mode 100644 index b3c2932f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/ParseComment.java +++ /dev/null @@ -1,324 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import android.os.AsyncTask; -import android.text.Html; - -import androidx.annotation.Nullable; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -import static ml.docilealligator.infinityforreddit.Comment.Comment.VOTE_TYPE_DOWNVOTE; -import static ml.docilealligator.infinityforreddit.Comment.Comment.VOTE_TYPE_NO_VOTE; -import static ml.docilealligator.infinityforreddit.Comment.Comment.VOTE_TYPE_UPVOTE; - -public class ParseComment { - public static void parseComment(String response, ArrayList commentData, Locale locale, - boolean expandChildren, ParseCommentListener parseCommentListener) { - try { - JSONArray childrenArray = new JSONArray(response); - String parentId = childrenArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) - .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY); - childrenArray = childrenArray.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - - new ParseCommentAsyncTask(childrenArray, commentData, locale, parentId, 0, expandChildren, parseCommentListener).execute(); - } catch (JSONException e) { - e.printStackTrace(); - parseCommentListener.onParseCommentFailed(); - } - } - - static void parseMoreComment(String response, ArrayList commentData, Locale locale, - int depth, boolean expandChildren, ParseCommentListener parseCommentListener) { - try { - JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - new ParseCommentAsyncTask(childrenArray, commentData, locale, null, depth, expandChildren, parseCommentListener).execute(); - } catch (JSONException e) { - e.printStackTrace(); - parseCommentListener.onParseCommentFailed(); - } - } - - static void parseSentComment(String response, int depth, Locale locale, - ParseSentCommentListener parseSentCommentListener) { - new ParseSentCommentAsyncTask(response, depth, locale, parseSentCommentListener).execute(); - } - - private static void parseCommentRecursion(JSONArray comments, ArrayList newCommentData, - ArrayList moreChildrenFullnames, int depth, Locale locale) throws JSONException { - int actualCommentLength; - - if (comments.length() == 0) { - return; - } - - JSONObject more = comments.getJSONObject(comments.length() - 1).getJSONObject(JSONUtils.DATA_KEY); - - //Maybe moreChildrenFullnames contain only commentsJSONArray and no more info - if (more.has(JSONUtils.COUNT_KEY)) { - JSONArray childrenArray = more.getJSONArray(JSONUtils.CHILDREN_KEY); - - for (int i = 0; i < childrenArray.length(); i++) { - moreChildrenFullnames.add("t1_" + childrenArray.getString(i)); - } - - actualCommentLength = comments.length() - 1; - } else { - actualCommentLength = comments.length(); - } - - for (int i = 0; i < actualCommentLength; i++) { - JSONObject data = comments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - Comment singleComment = parseSingleComment(data, depth, locale); - - if (data.get(JSONUtils.REPLIES_KEY) instanceof JSONObject) { - JSONArray childrenArray = data.getJSONObject(JSONUtils.REPLIES_KEY) - .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - ArrayList children = new ArrayList<>(); - ArrayList nextMoreChildrenFullnames = new ArrayList<>(); - parseCommentRecursion(childrenArray, children, nextMoreChildrenFullnames, singleComment.getDepth(), - locale); - singleComment.addChildren(children); - singleComment.setMoreChildrenFullnames(nextMoreChildrenFullnames); - } - - newCommentData.add(singleComment); - } - } - - private static void expandChildren(ArrayList comments, ArrayList visibleComments, - boolean setExpanded) { - for (Comment c : comments) { - visibleComments.add(c); - if (c.hasReply()) { - if (setExpanded) { - c.setExpanded(true); - } - expandChildren(c.getChildren(), visibleComments, setExpanded); - } else { - c.setExpanded(true); - } - if (c.hasMoreChildrenFullnames() && c.getMoreChildrenFullnames().size() > c.getMoreChildrenStartingIndex()) { - //Add a load more placeholder - Comment placeholder = new Comment(c.getFullName(), c.getDepth() + 1); - visibleComments.add(placeholder); - c.addChild(placeholder, c.getChildren().size()); - } - } - } - - static Comment parseSingleComment(JSONObject singleCommentData, int depth, Locale locale) throws JSONException { - String id = singleCommentData.getString(JSONUtils.ID_KEY); - String fullName = singleCommentData.getString(JSONUtils.NAME_KEY); - String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY); - StringBuilder authorFlairHTMLBuilder = new StringBuilder(); - if (singleCommentData.has(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY)) { - JSONArray flairArray = singleCommentData.getJSONArray(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY); - for (int i = 0; i < flairArray.length(); i++) { - JSONObject flairObject = flairArray.getJSONObject(i); - String e = flairObject.getString(JSONUtils.E_KEY); - if (e.equals("text")) { - authorFlairHTMLBuilder.append(Html.escapeHtml(flairObject.getString(JSONUtils.T_KEY))); - } else if (e.equals("emoji")) { - authorFlairHTMLBuilder.append(""); - } - } - } - String authorFlair = singleCommentData.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) ? "" : singleCommentData.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY); - String linkAuthor = singleCommentData.has(JSONUtils.LINK_AUTHOR_KEY) ? singleCommentData.getString(JSONUtils.LINK_AUTHOR_KEY) : null; - String linkId = singleCommentData.getString(JSONUtils.LINK_ID_KEY).substring(3); - String subredditName = singleCommentData.getString(JSONUtils.SUBREDDIT_KEY); - String parentId = singleCommentData.getString(JSONUtils.PARENT_ID_KEY); - boolean isSubmitter = singleCommentData.getBoolean(JSONUtils.IS_SUBMITTER_KEY); - String distinguished = singleCommentData.getString(JSONUtils.DISTINGUISHED_KEY); - String commentMarkdown = ""; - if (!singleCommentData.isNull(JSONUtils.BODY_KEY)) { - commentMarkdown = Utils.modifyMarkdown(singleCommentData.getString(JSONUtils.BODY_KEY).trim()); - } - String commentRawText = Utils.trimTrailingWhitespace( - Html.fromHtml(singleCommentData.getString(JSONUtils.BODY_HTML_KEY))).toString(); - String permalink = Html.fromHtml(singleCommentData.getString(JSONUtils.PERMALINK_KEY)).toString(); - StringBuilder awardingsBuilder = new StringBuilder(); - JSONArray awardingsArray = singleCommentData.getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); - for (int i = 0; i < awardingsArray.length(); i++) { - JSONObject award = awardingsArray.getJSONObject(i); - int count = award.getInt(JSONUtils.COUNT_KEY); - JSONArray icons = award.getJSONArray(JSONUtils.RESIZED_ICONS_KEY); - if (icons.length() > 4) { - String iconUrl = icons.getJSONObject(3).getString(JSONUtils.URL_KEY); - awardingsBuilder.append(" ").append("x").append(count).append(" "); - } else if (icons.length() > 0) { - String iconUrl = icons.getJSONObject(icons.length() - 1).getString(JSONUtils.URL_KEY); - awardingsBuilder.append(" ").append("x").append(count).append(" "); - } - } - int score = singleCommentData.getInt(JSONUtils.SCORE_KEY); - int voteType; - if (singleCommentData.isNull(JSONUtils.LIKES_KEY)) { - voteType = VOTE_TYPE_NO_VOTE; - } else { - voteType = singleCommentData.getBoolean(JSONUtils.LIKES_KEY) ? VOTE_TYPE_UPVOTE : VOTE_TYPE_DOWNVOTE; - score -= voteType; - } - long submitTime = singleCommentData.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; - boolean scoreHidden = singleCommentData.getBoolean(JSONUtils.SCORE_HIDDEN_KEY); - boolean saved = singleCommentData.getBoolean(JSONUtils.SAVED_KEY); - - if (singleCommentData.has(JSONUtils.DEPTH_KEY)) { - depth = singleCommentData.getInt(JSONUtils.DEPTH_KEY); - } - - boolean collapsed = singleCommentData.getBoolean(JSONUtils.COLLAPSED_KEY); - boolean hasReply = !(singleCommentData.get(JSONUtils.REPLIES_KEY) instanceof String); - - return new Comment(id, fullName, author, authorFlair, authorFlairHTMLBuilder.toString(), - linkAuthor, submitTime, commentMarkdown, commentRawText, - linkId, subredditName, parentId, score, voteType, isSubmitter, distinguished, - permalink, awardingsBuilder.toString(),depth, collapsed, hasReply, scoreHidden, saved); - } - - @Nullable - private static String parseSentCommentErrorMessage(String response) { - try { - JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); - - if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { - JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) - .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); - if (error.length() != 0) { - String errorString; - if (error.length() >= 2) { - errorString = error.getString(1); - } else { - errorString = error.getString(0); - } - return errorString.substring(0, 1).toUpperCase() + errorString.substring(1); - } else { - return null; - } - } else { - return null; - } - } catch (JSONException e) { - e.printStackTrace(); - } - - return null; - } - - public interface ParseCommentListener { - void onParseCommentSuccess(ArrayList expandedComments, String parentId, - ArrayList moreChildrenFullnames); - - void onParseCommentFailed(); - } - - interface ParseSentCommentListener { - void onParseSentCommentSuccess(Comment comment); - - void onParseSentCommentFailed(@Nullable String errorMessage); - } - - private static class ParseCommentAsyncTask extends AsyncTask { - private JSONArray commentsJSONArray; - private ArrayList comments; - private ArrayList newComments; - private ArrayList expandedNewComments; - private ArrayList moreChildrenFullnames; - private Locale locale; - private String parentId; - private int depth; - private boolean expandChildren; - private ParseCommentListener parseCommentListener; - private boolean parseFailed; - - ParseCommentAsyncTask(JSONArray commentsJSONArray, ArrayList comments, Locale locale, - @Nullable String parentId, int depth, boolean expandChildren, - ParseCommentListener parseCommentListener) { - this.commentsJSONArray = commentsJSONArray; - this.comments = comments; - newComments = new ArrayList<>(); - expandedNewComments = new ArrayList<>(); - moreChildrenFullnames = new ArrayList<>(); - this.locale = locale; - this.parentId = parentId; - this.depth = depth; - this.expandChildren = expandChildren; - parseFailed = false; - this.parseCommentListener = parseCommentListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - parseCommentRecursion(commentsJSONArray, newComments, moreChildrenFullnames, depth, locale); - expandChildren(newComments, expandedNewComments, expandChildren); - } catch (JSONException e) { - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - if (expandChildren) { - comments.addAll(expandedNewComments); - } else { - comments.addAll(newComments); - } - parseCommentListener.onParseCommentSuccess(comments, parentId, moreChildrenFullnames); - } else { - parseCommentListener.onParseCommentFailed(); - } - } - } - - private static class ParseSentCommentAsyncTask extends AsyncTask { - private String response; - private int depth; - private Locale locale; - private ParseSentCommentListener parseSentCommentListener; - private boolean parseFailed; - private String errorMessage; - private Comment comment; - - ParseSentCommentAsyncTask(String response, int depth, Locale locale, ParseSentCommentListener parseSentCommentListener) { - this.response = response; - this.depth = depth; - this.locale = locale; - this.parseSentCommentListener = parseSentCommentListener; - parseFailed = false; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject sentCommentData = new JSONObject(response); - comment = parseSingleComment(sentCommentData, depth, locale); - } catch (JSONException e) { - e.printStackTrace(); - errorMessage = parseSentCommentErrorMessage(response); - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - parseSentCommentListener.onParseSentCommentFailed(errorMessage); - } else { - parseSentCommentListener.onParseSentCommentSuccess(comment); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/SendComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/SendComment.java deleted file mode 100644 index 6991364f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Comment/SendComment.java +++ /dev/null @@ -1,61 +0,0 @@ -package ml.docilealligator.infinityforreddit.Comment; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class SendComment { - - public static void sendComment(String commentMarkdown, String thingFullname, int parentDepth, - Locale locale, Retrofit oauthRetrofit, String accessToken, - SendCommentListener sendCommentListener) { - Map headers = APIUtils.getOAuthHeader(accessToken); - Map params = new HashMap<>(); - params.put(APIUtils.API_TYPE_KEY, "json"); - params.put(APIUtils.RETURN_RTJSON_KEY, "true"); - params.put(APIUtils.TEXT_KEY, commentMarkdown); - params.put(APIUtils.THING_ID_KEY, thingFullname); - - oauthRetrofit.create(RedditAPI.class).sendCommentOrReplyToMessage(headers, params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseComment.parseSentComment(response.body(), parentDepth, locale, new ParseComment.ParseSentCommentListener() { - @Override - public void onParseSentCommentSuccess(Comment comment) { - sendCommentListener.sendCommentSuccess(comment); - } - - @Override - public void onParseSentCommentFailed(@Nullable String errorMessage) { - sendCommentListener.sendCommentFailed(errorMessage); - } - }); - } else { - sendCommentListener.sendCommentFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - sendCommentListener.sendCommentFailed(t.getMessage()); - } - }); - } - - public interface SendCommentListener { - void sendCommentSuccess(Comment comment); - - void sendCommentFailed(String errorMessage); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomTheme.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomTheme.java deleted file mode 100644 index 78288933..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomTheme.java +++ /dev/null @@ -1,280 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomTheme; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.PrimaryKey; - -import com.google.gson.Gson; - -import java.util.ArrayList; - -@Entity(tableName = "custom_themes") -public class CustomTheme { - @PrimaryKey - @NonNull - @ColumnInfo(name = "name") - public String name; - @ColumnInfo(name = "is_light_theme") - public boolean isLightTheme; - @ColumnInfo(name = "is_dark_theme") - public boolean isDarkTheme; - @ColumnInfo(name = "is_amoled_theme") - public boolean isAmoledTheme; - @ColumnInfo(name = "color_primary") - public int colorPrimary; - @ColumnInfo(name = "color_primary_dark") - public int colorPrimaryDark; - @ColumnInfo(name = "color_accent") - public int colorAccent; - @ColumnInfo(name = "color_primary_light_theme") - public int colorPrimaryLightTheme; - @ColumnInfo(name = "primary_text_color") - public int primaryTextColor; - @ColumnInfo(name = "secondary_text_color") - public int secondaryTextColor; - @ColumnInfo(name = "post_title_color") - public int postTitleColor; - @ColumnInfo(name = "post_content_color") - public int postContentColor; - @ColumnInfo(name = "comment_color") - public int commentColor; - @ColumnInfo(name = "button_text_color") - public int buttonTextColor; - @ColumnInfo(name = "background_color") - public int backgroundColor; - @ColumnInfo(name = "card_view_background_color") - public int cardViewBackgroundColor; - @ColumnInfo(name = "comment_background_color") - public int commentBackgroundColor; - @ColumnInfo(name = "bottom_app_bar_background_color") - public int bottomAppBarBackgroundColor; - @ColumnInfo(name = "primary_icon_color") - public int primaryIconColor; - @ColumnInfo(name = "bottom_app_bar_icon_color") - public int bottomAppBarIconColor; - @ColumnInfo(name = "post_icon_and_info_color") - public int postIconAndInfoColor; - @ColumnInfo(name = "comment_icon_and_info_color") - public int commentIconAndInfoColor; - @ColumnInfo(name = "toolbar_primary_text_and_icon_color") - public int toolbarPrimaryTextAndIconColor; - @ColumnInfo(name = "toolbar_secondary_text_color") - public int toolbarSecondaryTextColor; - @ColumnInfo(name = "circular_progress_bar_background") - public int circularProgressBarBackground; - @ColumnInfo(name = "tab_layout_with_expanded_collapsing_toolbar_tab_background") - public int tabLayoutWithExpandedCollapsingToolbarTabBackground; - @ColumnInfo(name = "tab_layout_with_expanded_collapsing_toolbar_text_color") - public int tabLayoutWithExpandedCollapsingToolbarTextColor; - @ColumnInfo(name = "tab_layout_with_expanded_collapsing_toolbar_tab_indicator") - public int tabLayoutWithExpandedCollapsingToolbarTabIndicator; - @ColumnInfo(name = "tab_layout_with_collapsed_collapsing_toolbar_tab_background") - public int tabLayoutWithCollapsedCollapsingToolbarTabBackground; - @ColumnInfo(name = "tab_layout_with_collapsed_collapsing_toolbar_text_color") - public int tabLayoutWithCollapsedCollapsingToolbarTextColor; - @ColumnInfo(name = "tab_layout_with_collapsed_collapsing_toolbar_tab_indicator") - public int tabLayoutWithCollapsedCollapsingToolbarTabIndicator; - @ColumnInfo(name = "nav_bar_color") - public int navBarColor; - @ColumnInfo(name = "upvoted") - public int upvoted; - @ColumnInfo(name = "downvoted") - public int downvoted; - @ColumnInfo(name = "post_type_background_color") - public int postTypeBackgroundColor; - @ColumnInfo(name = "post_type_text_color") - public int postTypeTextColor; - @ColumnInfo(name = "spoiler_background_color") - public int spoilerBackgroundColor; - @ColumnInfo(name = "spoiler_text_color") - public int spoilerTextColor; - @ColumnInfo(name = "nsfw_background_color") - public int nsfwBackgroundColor; - @ColumnInfo(name = "nsfw_text_color") - public int nsfwTextColor; - @ColumnInfo(name = "flair_background_color") - public int flairBackgroundColor; - @ColumnInfo(name = "flair_text_color") - public int flairTextColor; - @ColumnInfo(name = "awards_background_color") - public int awardsBackgroundColor; - @ColumnInfo(name = "awards_text_color") - public int awardsTextColor; - @ColumnInfo(name = "archived_tint") - public int archivedTint; - @ColumnInfo(name = "locked_icon_tint") - public int lockedIconTint; - @ColumnInfo(name = "crosspost_icon_tint") - public int crosspostIconTint; - @ColumnInfo(name = "stickied_post_icon_tint") - public int stickiedPostIconTint; - @ColumnInfo(name = "no_preview_post_type_icon_tint") - public int noPreviewPostTypeIconTint; - @ColumnInfo(name = "subscribed") - public int subscribed; - @ColumnInfo(name = "unsubscribed") - public int unsubscribed; - @ColumnInfo(name = "username") - public int username; - @ColumnInfo(name = "subreddit") - public int subreddit; - @ColumnInfo(name = "author_flair_text_color") - public int authorFlairTextColor; - @ColumnInfo(name = "submitter") - public int submitter; - @ColumnInfo(name = "moderator") - public int moderator; - @ColumnInfo(name = "single_comment_thread_background_color") - public int singleCommentThreadBackgroundColor; - @ColumnInfo(name = "unread_message_background_color") - public int unreadMessageBackgroundColor; - @ColumnInfo(name = "divider_color") - public int dividerColor; - @ColumnInfo(name = "no_preview_link_background_color") - public int noPreviewPostTypeBackgroundColor; - @ColumnInfo(name = "vote_and_reply_unavailable_button_color") - public int voteAndReplyUnavailableButtonColor; - @ColumnInfo(name = "comment_vertical_bar_color_1") - public int commentVerticalBarColor1; - @ColumnInfo(name = "comment_vertical_bar_color_2") - public int commentVerticalBarColor2; - @ColumnInfo(name = "comment_vertical_bar_color_3") - public int commentVerticalBarColor3; - @ColumnInfo(name = "comment_vertical_bar_color_4") - public int commentVerticalBarColor4; - @ColumnInfo(name = "comment_vertical_bar_color_5") - public int commentVerticalBarColor5; - @ColumnInfo(name = "comment_vertical_bar_color_6") - public int commentVerticalBarColor6; - @ColumnInfo(name = "comment_vertical_bar_color_7") - public int commentVerticalBarColor7; - @ColumnInfo(name = "fab_icon_color") - public int fabIconColor; - @ColumnInfo(name = "chip_text_color") - public int chipTextColor; - @ColumnInfo(name = "link_color") - public int linkColor; - @ColumnInfo(name = "received_message_text_color") - public int receivedMessageTextColor; - @ColumnInfo(name = "sent_message_text_color") - public int sentMessageTextColor; - @ColumnInfo(name = "received_message_background_color") - public int receivedMessageBackgroundColor; - @ColumnInfo(name = "sent_message_background_color") - public int sentMessageBackgroundColor; - @ColumnInfo(name = "send_message_icon_color") - public int sendMessageIconColor; - @ColumnInfo(name = "fully_collapsed_comment_background_color") - public int fullyCollapsedCommentBackgroundColor; - @ColumnInfo(name = "awarded_comment_background_color") - public int awardedCommentBackgroundColor; - @ColumnInfo(name = "is_light_status_bar") - public boolean isLightStatusBar; - @ColumnInfo(name = "is_light_nav_bar") - public boolean isLightNavBar; - @ColumnInfo(name = "is_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface") - public boolean isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface; - - public CustomTheme() {} - - public CustomTheme(@NonNull String name) { - this.name = name; - } - - public String getJSONModel() { - Gson gson = new Gson(); - return gson.toJson(this); - } - - public static CustomTheme convertSettingsItemsToCustomTheme(ArrayList customThemeSettingsItems, String themeName) { - CustomTheme customTheme = new CustomTheme(themeName); - - if (customThemeSettingsItems.isEmpty()) { - return customTheme; - } - - customTheme.isLightTheme = customThemeSettingsItems.get(0).isEnabled; - customTheme.isDarkTheme = customThemeSettingsItems.get(1).isEnabled; - customTheme.isAmoledTheme = customThemeSettingsItems.get(2).isEnabled; - customTheme.colorPrimary = customThemeSettingsItems.get(3).colorValue; - customTheme.colorPrimaryDark = customThemeSettingsItems.get(4).colorValue; - customTheme.colorAccent = customThemeSettingsItems.get(5).colorValue; - customTheme.colorPrimaryLightTheme = customThemeSettingsItems.get(6).colorValue; - customTheme.primaryTextColor = customThemeSettingsItems.get(7).colorValue; - customTheme.secondaryTextColor = customThemeSettingsItems.get(8).colorValue; - customTheme.postTitleColor = customThemeSettingsItems.get(9).colorValue; - customTheme.postContentColor = customThemeSettingsItems.get(10).colorValue; - customTheme.commentColor = customThemeSettingsItems.get(11).colorValue; - customTheme.buttonTextColor = customThemeSettingsItems.get(12).colorValue; - customTheme.chipTextColor = customThemeSettingsItems.get(13).colorValue; - customTheme.linkColor = customThemeSettingsItems.get(14).colorValue; - customTheme.receivedMessageTextColor = customThemeSettingsItems.get(15).colorValue; - customTheme.sentMessageTextColor = customThemeSettingsItems.get(16).colorValue; - customTheme.backgroundColor = customThemeSettingsItems.get(17).colorValue; - customTheme.cardViewBackgroundColor = customThemeSettingsItems.get(18).colorValue; - customTheme.commentBackgroundColor = customThemeSettingsItems.get(19).colorValue; - customTheme.fullyCollapsedCommentBackgroundColor = customThemeSettingsItems.get(20).colorValue; - customTheme.awardedCommentBackgroundColor = customThemeSettingsItems.get(21).colorValue; - customTheme.receivedMessageBackgroundColor = customThemeSettingsItems.get(22).colorValue; - customTheme.sentMessageBackgroundColor = customThemeSettingsItems.get(23).colorValue; - customTheme.bottomAppBarBackgroundColor = customThemeSettingsItems.get(24).colorValue; - customTheme.primaryIconColor = customThemeSettingsItems.get(25).colorValue; - customTheme.bottomAppBarIconColor = customThemeSettingsItems.get(26).colorValue; - customTheme.postIconAndInfoColor = customThemeSettingsItems.get(27).colorValue; - customTheme.commentIconAndInfoColor = customThemeSettingsItems.get(28).colorValue; - customTheme.fabIconColor = customThemeSettingsItems.get(29).colorValue; - customTheme.sendMessageIconColor = customThemeSettingsItems.get(30).colorValue; - customTheme.toolbarPrimaryTextAndIconColor = customThemeSettingsItems.get(31).colorValue; - customTheme.toolbarSecondaryTextColor = customThemeSettingsItems.get(32).colorValue; - customTheme.circularProgressBarBackground = customThemeSettingsItems.get(33).colorValue; - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = customThemeSettingsItems.get(34).colorValue; - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = customThemeSettingsItems.get(35).colorValue; - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(36).colorValue; - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = customThemeSettingsItems.get(37).colorValue; - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = customThemeSettingsItems.get(38).colorValue; - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(39).colorValue; - customTheme.upvoted = customThemeSettingsItems.get(40).colorValue; - customTheme.downvoted = customThemeSettingsItems.get(41).colorValue; - customTheme.postTypeBackgroundColor = customThemeSettingsItems.get(42).colorValue; - customTheme.postTypeTextColor = customThemeSettingsItems.get(43).colorValue; - customTheme.spoilerBackgroundColor = customThemeSettingsItems.get(44).colorValue; - customTheme.spoilerTextColor = customThemeSettingsItems.get(45).colorValue; - customTheme.nsfwBackgroundColor = customThemeSettingsItems.get(46).colorValue; - customTheme.nsfwTextColor = customThemeSettingsItems.get(47).colorValue; - customTheme.flairBackgroundColor = customThemeSettingsItems.get(48).colorValue; - customTheme.flairTextColor = customThemeSettingsItems.get(49).colorValue; - customTheme.awardsBackgroundColor = customThemeSettingsItems.get(50).colorValue; - customTheme.awardsTextColor = customThemeSettingsItems.get(51).colorValue; - customTheme.archivedTint = customThemeSettingsItems.get(52).colorValue; - customTheme.lockedIconTint = customThemeSettingsItems.get(53).colorValue; - customTheme.crosspostIconTint = customThemeSettingsItems.get(54).colorValue; - customTheme.stickiedPostIconTint = customThemeSettingsItems.get(55).colorValue; - customTheme.noPreviewPostTypeIconTint = customThemeSettingsItems.get(56).colorValue; - customTheme.subscribed = customThemeSettingsItems.get(57).colorValue; - customTheme.unsubscribed = customThemeSettingsItems.get(58).colorValue; - customTheme.username = customThemeSettingsItems.get(59).colorValue; - customTheme.subreddit = customThemeSettingsItems.get(60).colorValue; - customTheme.authorFlairTextColor = customThemeSettingsItems.get(61).colorValue; - customTheme.submitter = customThemeSettingsItems.get(62).colorValue; - customTheme.moderator = customThemeSettingsItems.get(63).colorValue; - customTheme.singleCommentThreadBackgroundColor = customThemeSettingsItems.get(64).colorValue; - customTheme.unreadMessageBackgroundColor = customThemeSettingsItems.get(65).colorValue; - customTheme.dividerColor = customThemeSettingsItems.get(66).colorValue; - customTheme.noPreviewPostTypeBackgroundColor = customThemeSettingsItems.get(67).colorValue; - customTheme.voteAndReplyUnavailableButtonColor = customThemeSettingsItems.get(68).colorValue; - customTheme.commentVerticalBarColor1 = customThemeSettingsItems.get(69).colorValue; - customTheme.commentVerticalBarColor2 = customThemeSettingsItems.get(70).colorValue; - customTheme.commentVerticalBarColor3 = customThemeSettingsItems.get(71).colorValue; - customTheme.commentVerticalBarColor4 = customThemeSettingsItems.get(72).colorValue; - customTheme.commentVerticalBarColor5 = customThemeSettingsItems.get(73).colorValue; - customTheme.commentVerticalBarColor6 = customThemeSettingsItems.get(74).colorValue; - customTheme.commentVerticalBarColor7 = customThemeSettingsItems.get(75).colorValue; - customTheme.navBarColor = customThemeSettingsItems.get(76).colorValue; - customTheme.isLightStatusBar = customThemeSettingsItems.get(77).isEnabled; - customTheme.isLightNavBar = customThemeSettingsItems.get(78).isEnabled; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = customThemeSettingsItems.get(79).isEnabled; - - return customTheme; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeDao.java deleted file mode 100644 index 68b4de13..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeDao.java +++ /dev/null @@ -1,57 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomTheme; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -import java.util.List; - -@Dao -public interface CustomThemeDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(CustomTheme customTheme); - - @Query("SELECT * FROM custom_themes") - LiveData> getAllCustomThemes(); - - @Query("SELECT * FROM custom_themes WHERE is_light_theme = 1 LIMIT 1") - CustomTheme getLightCustomTheme(); - - @Query("SELECT * FROM custom_themes WHERE is_dark_theme = 1 LIMIT 1") - CustomTheme getDarkCustomTheme(); - - @Query("SELECT * FROM custom_themes WHERE is_amoled_theme = 1 LIMIT 1") - CustomTheme getAmoledCustomTheme(); - - @Query("SELECT * FROM custom_themes WHERE is_light_theme = 1 LIMIT 1") - LiveData getLightCustomThemeLiveData(); - - @Query("SELECT * FROM custom_themes WHERE is_dark_theme = 1 LIMIT 1") - LiveData getDarkCustomThemeLiveData(); - - @Query("SELECT * FROM custom_themes WHERE is_amoled_theme = 1 LIMIT 1") - LiveData getAmoledCustomThemeLiveData(); - - @Query("SELECT * FROM custom_themes WHERE name = :name COLLATE NOCASE LIMIT 1") - CustomTheme getCustomTheme(String name); - - @Query("UPDATE custom_themes SET is_light_theme = 0 WHERE is_light_theme = 1") - void unsetLightTheme(); - - @Query("UPDATE custom_themes SET is_dark_theme = 0 WHERE is_dark_theme = 1") - void unsetDarkTheme(); - - @Query("UPDATE custom_themes SET is_amoled_theme = 0 WHERE is_amoled_theme = 1") - void unsetAmoledTheme(); - - @Query("DELETE FROM custom_themes WHERE name = :name") - void deleteCustomTheme(String name); - - @Query("UPDATE custom_themes SET name = :newName WHERE name = :oldName") - void updateName(String oldName, String newName); - - @Query("DELETE FROM custom_themes") - void deleteAllCustomThemes(); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeRepository.java deleted file mode 100644 index 2084bd5b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeRepository.java +++ /dev/null @@ -1,37 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomTheme; - -import androidx.lifecycle.LiveData; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class CustomThemeRepository { - private LiveData> mAllCustomThemes; - private LiveData mCurrentLightCustomTheme; - private LiveData mCurrentDarkCustomTheme; - private LiveData mCurrentAmoledCustomTheme; - - CustomThemeRepository(RedditDataRoomDatabase redditDataRoomDatabase) { - mAllCustomThemes = redditDataRoomDatabase.customThemeDao().getAllCustomThemes(); - mCurrentLightCustomTheme = redditDataRoomDatabase.customThemeDao().getLightCustomThemeLiveData(); - mCurrentDarkCustomTheme = redditDataRoomDatabase.customThemeDao().getDarkCustomThemeLiveData(); - mCurrentAmoledCustomTheme = redditDataRoomDatabase.customThemeDao().getAmoledCustomThemeLiveData(); - } - - LiveData> getAllCustomThemes() { - return mAllCustomThemes; - } - - LiveData getCurrentLightCustomTheme() { - return mCurrentLightCustomTheme; - } - - LiveData getCurrentDarkCustomTheme() { - return mCurrentDarkCustomTheme; - } - - LiveData getCurrentAmoledCustomTheme() { - return mCurrentAmoledCustomTheme; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeSettingsItem.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeSettingsItem.java deleted file mode 100644 index 059b575a..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeSettingsItem.java +++ /dev/null @@ -1,398 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomTheme; - -import android.content.Context; -import android.os.Build; -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.R; - -public class CustomThemeSettingsItem implements Parcelable { - public String itemName; - public String itemDetails; - public int colorValue; - public boolean isEnabled; - - private CustomThemeSettingsItem(String itemName, String itemDetails, int colorValue) { - this.itemName = itemName; - this.itemDetails = itemDetails; - this.colorValue = colorValue; - } - - private CustomThemeSettingsItem(String itemName, boolean isEnabled) { - this.itemName = itemName; - this.isEnabled = isEnabled; - } - - protected CustomThemeSettingsItem(Parcel in) { - itemName = in.readString(); - itemDetails = in.readString(); - colorValue = in.readInt(); - isEnabled = in.readByte() != 0; - } - - public static final Creator CREATOR = new Creator() { - @Override - public CustomThemeSettingsItem createFromParcel(Parcel in) { - return new CustomThemeSettingsItem(in); - } - - @Override - public CustomThemeSettingsItem[] newArray(int size) { - return new CustomThemeSettingsItem[size]; - } - }; - - public static ArrayList convertCustomThemeToSettingsItem(Context context, - CustomTheme customTheme, - int androidVersion) { - ArrayList customThemeSettingsItems = new ArrayList<>(); - - if (customTheme == null) { - return customThemeSettingsItems; - } - - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_is_light_theme), - customTheme.isLightTheme - )); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_is_dark_theme), - customTheme.isDarkTheme - )); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_is_amoled_theme), - customTheme.isAmoledTheme - )); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_color_primary), - context.getString(R.string.theme_item_color_primary_detail), - customTheme.colorPrimary)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_color_primary_dark), - context.getString(R.string.theme_item_color_primary_dark_detail), - customTheme.colorPrimaryDark)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_color_accent), - context.getString(R.string.theme_item_color_accent_detail), - customTheme.colorAccent)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_color_primary_light_theme), - context.getString(R.string.theme_item_color_primary_light_theme_detail), - customTheme.colorPrimaryLightTheme)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_primary_text_color), - context.getString(R.string.theme_item_primary_text_color_detail), - customTheme.primaryTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_secondary_text_color), - context.getString(R.string.theme_item_secondary_text_color_detail), - customTheme.secondaryTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_post_title_color), - context.getString(R.string.theme_item_post_title_color_detail), - customTheme.postTitleColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_post_content_color), - context.getString(R.string.theme_item_post_content_color_detail), - customTheme.postContentColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_color), - context.getString(R.string.theme_item_comment_color_detail), - customTheme.commentColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_button_text_color), - context.getString(R.string.theme_item_button_text_color_detail), - customTheme.buttonTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_chip_text_color), - context.getString(R.string.theme_item_chip_text_color_detail), - customTheme.chipTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_link_color), - context.getString(R.string.theme_item_link_color_detail), - customTheme.linkColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_received_message_text_color), - context.getString(R.string.theme_item_received_message_text_color_detail), - customTheme.receivedMessageTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_sent_message_text_color), - context.getString(R.string.theme_item_sent_message_text_color_detail), - customTheme.sentMessageTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_background_color), - context.getString(R.string.theme_item_background_color_detail), - customTheme.backgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_card_view_background_color), - context.getString(R.string.theme_item_card_view_background_color_detail), - customTheme.cardViewBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_background_color), - context.getString(R.string.theme_item_comment_background_color_detail), - customTheme.commentBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_fully_collapsed_comment_background_color), - context.getString(R.string.theme_item_fully_collapsed_comment_background_color_detail), - customTheme.fullyCollapsedCommentBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_awarded_comment_background_color), - context.getString(R.string.theme_item_awarded_comment_background_color_detail), - customTheme.awardedCommentBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_received_message_background_color), - context.getString(R.string.theme_item_received_message_background_color_detail), - customTheme.receivedMessageBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_sent_message_background_color), - context.getString(R.string.theme_item_sent_message_background_color_detail), - customTheme.sentMessageBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_bottom_app_bar_background_color), - context.getString(R.string.theme_item_bottom_app_bar_background_color_detail), - customTheme.bottomAppBarBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_primary_icon_color), - context.getString(R.string.theme_item_primary_icon_color_detail), - customTheme.primaryIconColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_bottom_app_bar_icon_color), - context.getString(R.string.theme_item_bottom_app_bar_icon_color_detail), - customTheme.bottomAppBarIconColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_post_icon_and_info_color), - context.getString(R.string.theme_item_post_icon_and_info_color_detail), - customTheme.postIconAndInfoColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_icon_and_info_color), - context.getString(R.string.theme_item_comment_icon_and_info_color_detail), - customTheme.commentIconAndInfoColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_fab_icon_color), - context.getString(R.string.theme_item_fab_icon_color_detail), - customTheme.fabIconColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_send_message_icon_color), - context.getString(R.string.theme_item_send_message_icon_color_detail), - customTheme.sendMessageIconColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_toolbar_primary_text_and_icon_color), - context.getString(R.string.theme_item_toolbar_primary_text_and_icon_color_detail), - customTheme.toolbarPrimaryTextAndIconColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_toolbar_secondary_text_color), - context.getString(R.string.theme_item_toolbar_secondary_text_color_detail), - customTheme.toolbarSecondaryTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_circular_progress_bar_background_color), - context.getString(R.string.theme_item_circular_progress_bar_background_color_detail), - customTheme.circularProgressBarBackground)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background), - context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background_detail), - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color), - context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color_detail), - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator), - context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator_detail), - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background), - context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background_detail), - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color), - context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail), - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator), - context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail), - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_upvoted_color), - context.getString(R.string.theme_item_upvoted_color_detail), - customTheme.upvoted)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_downvoted_color), - context.getString(R.string.theme_item_downvoted_color_detail), - customTheme.downvoted)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_post_type_background_color), - context.getString(R.string.theme_item_post_type_background_color_detail), - customTheme.postTypeBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_post_type_text_color), - context.getString(R.string.theme_item_post_type_text_color_detail), - customTheme.postTypeTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_spoiler_background_color), - context.getString(R.string.theme_item_spoiler_background_color_detail), - customTheme.spoilerBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_spoiler_text_color), - context.getString(R.string.theme_item_spoiler_text_color_detail), - customTheme.spoilerTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_nsfw_background_color), - context.getString(R.string.theme_item_nsfw_background_color_detail), - customTheme.nsfwBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_nsfw_text_color), - context.getString(R.string.theme_item_nsfw_text_color_detail), - customTheme.nsfwTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_flair_background_color), - context.getString(R.string.theme_item_flair_background_color_detail), - customTheme.flairBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_flair_text_color), - context.getString(R.string.theme_item_flair_text_color_detail), - customTheme.flairTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_awards_background_color), - context.getString(R.string.theme_item_awards_background_color_detail), - customTheme.awardsBackgroundColor - )); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_awards_text_color), - context.getString(R.string.theme_item_awards_text_color_detail), - customTheme.awardsTextColor - )); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_archived_tint), - context.getString(R.string.theme_item_archived_tint_detail), - customTheme.archivedTint)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_locked_icon_tint), - context.getString(R.string.theme_item_locked_icon_tint_detail), - customTheme.lockedIconTint)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_crosspost_icon_tint), - context.getString(R.string.theme_item_crosspost_icon_tint_detail), - customTheme.crosspostIconTint)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_stickied_post_icon_tint), - context.getString(R.string.theme_item_stickied_post_icon_tint_detail), - customTheme.stickiedPostIconTint)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_no_preview_post_type_icon_tint), - context.getString(R.string.theme_item_no_preview_post_type_icon_tint_detail), - customTheme.noPreviewPostTypeIconTint - )); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_subscribed_color), - context.getString(R.string.theme_item_subscribed_color_detail), - customTheme.subscribed)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_unsubscribed_color), - context.getString(R.string.theme_item_unsubscribed_color_detail), - customTheme.unsubscribed)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_username_color), - context.getString(R.string.theme_item_username_color_detail), - customTheme.username)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_subreddit_color), - context.getString(R.string.theme_item_subreddit_color_detail), - customTheme.subreddit)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_author_flair_text_color), - context.getString(R.string.theme_item_author_flair_text_color_detail), - customTheme.authorFlairTextColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_submitter_color), - context.getString(R.string.theme_item_submitter_color_detail), - customTheme.submitter)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_moderator_color), - context.getString(R.string.theme_item_moderator_color_detail), - customTheme.moderator)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_single_comment_thread_background_color), - context.getString(R.string.theme_item_single_comment_thread_background_color_detail), - customTheme.singleCommentThreadBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_unread_message_background_color), - context.getString(R.string.theme_item_unread_message_background_color_detail), - customTheme.unreadMessageBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_divider_color), - context.getString(R.string.theme_item_divider_color_detail), - customTheme.dividerColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_no_preview_post_type_background_color), - context.getString(R.string.theme_item_no_preview_post_type_background_color_detail), - customTheme.noPreviewPostTypeBackgroundColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_vote_and_reply_unavailable_button_color), - context.getString(R.string.theme_item_vote_and_reply_unavailable_button_color_detail), - customTheme.voteAndReplyUnavailableButtonColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_vertical_bar_color_1), - context.getString(R.string.theme_item_comment_vertical_bar_color_1_detail), - customTheme.commentVerticalBarColor1)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_vertical_bar_color_2), - context.getString(R.string.theme_item_comment_vertical_bar_color_2_detail), - customTheme.commentVerticalBarColor2)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_vertical_bar_color_3), - context.getString(R.string.theme_item_comment_vertical_bar_color_3_detail), - customTheme.commentVerticalBarColor3)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_vertical_bar_color_4), - context.getString(R.string.theme_item_comment_vertical_bar_color_4_detail), - customTheme.commentVerticalBarColor4)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_vertical_bar_color_5), - context.getString(R.string.theme_item_comment_vertical_bar_color_5_detail), - customTheme.commentVerticalBarColor5)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_vertical_bar_color_6), - context.getString(R.string.theme_item_comment_vertical_bar_color_6_detail), - customTheme.commentVerticalBarColor6)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_comment_vertical_bar_color_7), - context.getString(R.string.theme_item_comment_vertical_bar_color_7_detail), - customTheme.commentVerticalBarColor7)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_nav_bar_color), - context.getString(R.string.theme_item_nav_bar_color_detail), - customTheme.navBarColor)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_light_status_bar), - customTheme.isLightStatusBar)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_light_nav_bar), - customTheme.isLightNavBar)); - customThemeSettingsItems.add(new CustomThemeSettingsItem( - context.getString(R.string.theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface), - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface)); - if (androidVersion < Build.VERSION_CODES.O) { - customThemeSettingsItems.get(customThemeSettingsItems.size() - 2).itemDetails = context.getString(R.string.theme_item_available_on_android_8); - } - if (androidVersion < Build.VERSION_CODES.M) { - customThemeSettingsItems.get(customThemeSettingsItems.size() - 3).itemDetails = context.getString(R.string.theme_item_available_on_android_6); - } - return customThemeSettingsItems; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(itemName); - parcel.writeString(itemDetails); - parcel.writeInt(colorValue); - parcel.writeByte((byte) (isEnabled ? 1 : 0)); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeViewModel.java deleted file mode 100644 index be8f044d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeViewModel.java +++ /dev/null @@ -1,55 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomTheme; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class CustomThemeViewModel extends ViewModel { - private LiveData> mAllCustomThemes; - private LiveData mCurrentLightTheme; - private LiveData mCurrentDarkTheme; - private LiveData mCurrentAmoledTheme; - - public CustomThemeViewModel(RedditDataRoomDatabase redditDataRoomDatabase) { - CustomThemeRepository customThemeRepository = new CustomThemeRepository(redditDataRoomDatabase); - mAllCustomThemes = customThemeRepository.getAllCustomThemes(); - mCurrentLightTheme = customThemeRepository.getCurrentLightCustomTheme(); - mCurrentDarkTheme = customThemeRepository.getCurrentDarkCustomTheme(); - mCurrentAmoledTheme = customThemeRepository.getCurrentAmoledCustomTheme(); - } - - public LiveData> getAllCustomThemes() { - return mAllCustomThemes; - } - - public LiveData getCurrentLightThemeLiveData() { - return mCurrentLightTheme; - } - - public LiveData getCurrentDarkThemeLiveData() { - return mCurrentDarkTheme; - } - - public LiveData getCurrentAmoledThemeLiveData() { - return mCurrentAmoledTheme; - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private RedditDataRoomDatabase mRedditDataRoomDatabase; - - public Factory(RedditDataRoomDatabase redditDataRoomDatabase) { - mRedditDataRoomDatabase = redditDataRoomDatabase; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new CustomThemeViewModel(mRedditDataRoomDatabase); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeWrapper.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeWrapper.java deleted file mode 100644 index d8e53dcf..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomTheme/CustomThemeWrapper.java +++ /dev/null @@ -1,1427 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomTheme; - -import android.content.Context; -import android.content.SharedPreferences; -import android.graphics.Color; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; - -import static ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils.AMOLED; -import static ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils.DARK; - -public class CustomThemeWrapper { - private SharedPreferences lightThemeSharedPreferences; - private SharedPreferences darkThemeSharedPreferences; - private SharedPreferences amoledThemeSharedPreferences; - private int themeType; - - public CustomThemeWrapper(SharedPreferences lightThemeSharedPreferences, - SharedPreferences darkThemeSharedPreferences, - SharedPreferences amoledThemeSharedPreferences) { - this.lightThemeSharedPreferences = lightThemeSharedPreferences; - this.darkThemeSharedPreferences = darkThemeSharedPreferences; - this.amoledThemeSharedPreferences = amoledThemeSharedPreferences; - } - - private SharedPreferences getThemeSharedPreferences() { - switch (themeType) { - case DARK: - return darkThemeSharedPreferences; - case AMOLED: - return amoledThemeSharedPreferences; - default: - return lightThemeSharedPreferences; - } - } - - private int getDefaultColor(String normalHex, String darkHex, String amoledDarkHex) { - switch (themeType) { - case DARK: - return Color.parseColor(darkHex); - case AMOLED: - return Color.parseColor(amoledDarkHex); - default: - return Color.parseColor(normalHex); - } - } - - public void setThemeType(int themeType) { - this.themeType = themeType; - } - - public int getColorPrimary() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY, - getDefaultColor("#1565C0", "#242424", "#000000")); - } - - public int getColorPrimaryDark() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_DARK, - getDefaultColor("#0D47A1", "#121212", "#000000")); - } - - public int getColorAccent() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); - } - - public int getColorPrimaryLightTheme() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, - getDefaultColor("#1565C0", "#1565C0", "#1565C0")); - } - - public int getPrimaryTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.PRIMARY_TEXT_COLOR, - getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); - } - - public int getSecondaryTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SECONDARY_TEXT_COLOR, - getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); - } - - public int getPostTitleColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_TITLE_COLOR, - getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); - } - - public int getPostContentColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_CONTENT_COLOR, - getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); - } - - public int getCommentColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_COLOR, - getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); - } - - public int getButtonTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BUTTON_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BACKGROUND_COLOR, - getDefaultColor("#FFFFFF", "#121212", "#000000")); - } - - public int getCardViewBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CARD_VIEW_BACKGROUND_COLOR, - getDefaultColor("#FFFFFF", "#242424", "#000000")); - } - - public int getCommentBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_BACKGROUND_COLOR, - getDefaultColor("#FFFFFF", "#242424", "#000000")); - } - - public int getBottomAppBarBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_BACKGROUND_COLOR, - getDefaultColor("#FFFFFF", "#121212", "#000000")); - } - - public int getPrimaryIconColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.PRIMARY_ICON_COLOR, - getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); - } - - public int getBottomAppBarIconColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_ICON_COLOR, - getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); - } - - public int getPostIconAndInfoColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_ICON_AND_INFO_COLOR, - getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); - } - - public int getCommentIconAndInfoColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_ICON_AND_INFO_COLOR, - getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); - } - - public int getToolbarPrimaryTextAndIconColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getToolbarSecondaryTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TOOLBAR_SECONDARY_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getCircularProgressBarBackground() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CIRCULAR_PROGRESS_BAR_BACKGROUND, - getDefaultColor("#FFFFFF", "#242424", "#000000")); - } - - public int getTabLayoutWithExpandedCollapsingToolbarTabBackground() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, - getDefaultColor("#FFFFFF", "#242424", "#000000")); - } - - public int getTabLayoutWithExpandedCollapsingToolbarTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR, - getDefaultColor("#1565C0", "#FFFFFF", "#FFFFFF")); - } - - public int getTabLayoutWithExpandedCollapsingToolbarTabIndicator() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR, - getDefaultColor("#1565C0", "#FFFFFF", "#FFFFFF")); - } - - public int getTabLayoutWithCollapsedCollapsingToolbarTabBackground() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, - getDefaultColor("#1565C0", "#242424", "#000000")); - } - - public int getTabLayoutWithCollapsedCollapsingToolbarTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getTabLayoutWithCollapsedCollapsingToolbarTabIndicator() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getUpvoted() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UPVOTED, - getDefaultColor("#E91E63", "#E91E63", "#E91E63")); - } - - public int getDownvoted() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.DOWNVOTED, - getDefaultColor("#007DDE", "#007DDE", "#007DDE")); - } - - public int getPostTypeBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_TYPE_BACKGROUND_COLOR, - getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); - } - - public int getPostTypeTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_TYPE_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getSpoilerBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SPOILER_BACKGROUND_COLOR, - getDefaultColor("#EE02EB", "#EE02EB", "#EE02EB")); - } - - public int getSpoilerTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SPOILER_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getNsfwBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NSFW_BACKGROUND_COLOR, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); - } - - public int getNsfwTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NSFW_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getFlairBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FLAIR_BACKGROUND_COLOR, - getDefaultColor("#00AA8C", "#00AA8C", "#00AA8C")); - } - - public int getFlairTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FLAIR_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getAwardsBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AWARDS_BACKGROUND_COLOR, - getDefaultColor("#EEAB02", "#EEAB02", "#EEAB02")); - } - - public int getAwardsTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AWARDS_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getArchivedIconTint() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.ARCHIVED_ICON_TINT, - getDefaultColor("#B4009F", "#B4009F", "#B4009F")); - } - - public int getLockedIconTint() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.LOCKED_ICON_TINT, - getDefaultColor("#EE7302", "#EE7302", "#EE7302")); - } - - public int getCrosspostIconTint() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CROSSPOST_ICON_TINT, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); - } - - public int getStickiedPostIconTint() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.STICKIED_POST_ICON_TINT, - getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); - } - - public int getNoPreviewPostTypeIconTint() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NO_PREVIEW_POST_TYPE_ICON_TINT, - getDefaultColor("#808080", "#808080", "#808080")); - } - - public int getSubscribed() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBSCRIBED, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); - } - - public int getUnsubscribed() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UNSUBSCRIBED, - getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); - } - - public int getUsername() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.USERNAME, - getDefaultColor("#0D47A1", "#1E88E5", "#1E88E5")); - } - - public int getSubreddit() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBREDDIT, - getDefaultColor("#E91E63", "#E91E63", "#E91E63")); - } - - public int getAuthorFlairTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AUTHOR_FLAIR_TEXT_COLOR, - getDefaultColor("#EE02C4", "#EE02C4", "#EE02C4")); - } - - public int getSubmitter() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBMITTER, - getDefaultColor("#EE8A02", "#EE8A02", "#EE8A02")); - } - - public int getModerator() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.MODERATOR, - getDefaultColor("#00BA81", "#00BA81", "#00BA81")); - } - - public int getSingleCommentThreadBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SINGLE_COMMENT_THREAD_BACKGROUND_COLOR, - getDefaultColor("#B3E5F9", "#123E77", "#123E77")); - } - - public int getUnreadMessageBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UNREAD_MESSAGE_BACKGROUND_COLOR, - getDefaultColor("#B3E5F9", "#123E77", "#123E77")); - } - - public int getDividerColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.DIVIDER_COLOR, - getDefaultColor("#E0E0E0", "#69666C", "#69666C")); - } - - public int getNoPreviewPostTypeBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NO_PREVIEW_POST_TYPE_BACKGROUND_COLOR, - getDefaultColor("#E0E0E0", "#424242", "#424242")); - } - - public int getVoteAndReplyUnavailableButtonColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.VOTE_AND_REPLY_UNAVAILABLE_BUTTON_COLOR, - getDefaultColor("#F0F0F0", "#3C3C3C", "#3C3C3C")); - } - - public int getCommentVerticalBarColor1() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_1, - getDefaultColor("#1565C0", "#1565C0", "#1565C0")); - } - - public int getCommentVerticalBarColor2() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_2, - getDefaultColor("#EE02BE", "#C300B3", "#C300B3")); - } - - public int getCommentVerticalBarColor3() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_3, - getDefaultColor("#02DFEE", "#00B8DA", "#00B8DA")); - } - - public int getCommentVerticalBarColor4() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_4, - getDefaultColor("#EED502", "#EDCA00", "#EDCA00")); - } - - public int getCommentVerticalBarColor5() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_5, - getDefaultColor("#EE0220", "#EE0219", "#EE0219")); - } - - public int getCommentVerticalBarColor6() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_6, - getDefaultColor("#02EE6E", "#00B925", "#00B925")); - } - - public int getCommentVerticalBarColor7() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_7, - getDefaultColor("#EE4602", "#EE4602", "#EE4602")); - } - - public int getFABIconColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FAB_ICON_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getChipTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CHIP_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getLinkColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.LINK_COLOR, - getDefaultColor("#FF4081", "#FF4081", "#FF4081")); - } - - public int getReceivedMessageTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.RECEIVED_MESSAGE_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getSentMessageTextColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SENT_MESSAGE_TEXT_COLOR, - getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); - } - - public int getReceivedMessageBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.RECEIVED_MESSAGE_BACKROUND_COLOR, - getDefaultColor("#4185F4", "#4185F4", "#4185F4")); - } - - public int getSentMessageBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SENT_MESSAGE_BACKGROUND_COLOR, - getDefaultColor("#31BF7D", "#31BF7D", "#31BF7D")); - } - - public int getSendMessageIconColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SEND_MESSAGE_ICON_COLOR, - getDefaultColor("#4185F4", "#4185F4", "#4185F4")); - } - - public int getFullyCollapsedCommentBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FULLY_COLLAPSED_COMMENT_BACKGROUND_COLOR, - getDefaultColor("#8EDFBA", "#21C561", "#21C561")); - } - - public int getAwardedCommentBackgroundColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AWARDED_COMMENT_BACKGROUND_COLOR, - getDefaultColor("#FFFFFF", "#242424", "#000000")); - } - - public int getNavBarColor() { - return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NAV_BAR_COLOR, - getDefaultColor("#FFFFFF", "#121212", "#000000")); - } - - public boolean isLightStatusBar() { - return getThemeSharedPreferences().getBoolean(CustomThemeSharedPreferencesUtils.LIGHT_STATUS_BAR, false); - } - - public boolean isLightNavBar() { - return getThemeSharedPreferences().getBoolean(CustomThemeSharedPreferencesUtils.LIGHT_NAV_BAR, - themeType == CustomThemeSharedPreferencesUtils.LIGHT); - } - - public boolean isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface() { - return getThemeSharedPreferences().getBoolean( - CustomThemeSharedPreferencesUtils.CHANGE_STATUS_BAR_ICON_COLOR_AFTER_TOOLBAR_COLLAPSED_IN_IMMERSIVE_INTERFACE, - themeType == CustomThemeSharedPreferencesUtils.LIGHT); - } - - public static CustomTheme getPredefinedCustomTheme(Context context, String name) { - if (name.equals(context.getString(R.string.theme_name_indigo_dark))) { - return getIndigoDark(context); - } else if (name.equals(context.getString(R.string.theme_name_indigo_amoled))) { - return getIndigoAmoled(context); - } else if (name.equals(context.getString(R.string.theme_name_white))) { - return getWhite(context); - } else if (name.equals(context.getString(R.string.theme_name_white_dark))) { - return getWhiteDark(context); - } else if (name.equals(context.getString(R.string.theme_name_white_amoled))) { - return getWhiteAmoled(context); - } else if (name.equals(context.getString(R.string.theme_name_red))) { - return getRed(context); - } else if (name.equals(context.getString(R.string.theme_name_red_dark))) { - return getRedDark(context); - } else if (name.equals(context.getString(R.string.theme_name_red_amoled))) { - return getRedAmoled(context); - } else if (name.equals(context.getString(R.string.theme_name_dracula))) { - return getDracula(context); - } else if (name.equals(context.getString(R.string.theme_name_calm_pastel))) { - return getCalmPastel(context); - } else { - return getIndigo(context); - } - } - - public static ArrayList getPredefinedThemes(Context context) { - ArrayList customThemes = new ArrayList<>(); - customThemes.add(getIndigo(context)); - customThemes.add(getIndigoDark(context)); - customThemes.add(getIndigoAmoled(context)); - customThemes.add(getWhite(context)); - customThemes.add(getWhiteDark(context)); - customThemes.add(getWhiteAmoled(context)); - customThemes.add(getRed(context)); - customThemes.add(getRedDark(context)); - customThemes.add(getRedAmoled(context)); - customThemes.add(getDracula(context)); - customThemes.add(getCalmPastel(context)); - return customThemes; - } - - public static CustomTheme getIndigo(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_indigo)); - customTheme.isLightTheme = true; - customTheme.isDarkTheme = false; - customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#1565C0"); - customTheme.colorPrimaryDark = Color.parseColor("#0D47A1"); - customTheme.colorAccent = Color.parseColor("#FF4081"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); - customTheme.primaryTextColor = Color.parseColor("#000000"); - customTheme.secondaryTextColor = Color.parseColor("#8A000000"); - customTheme.postTitleColor = Color.parseColor("#000000"); - customTheme.postContentColor = Color.parseColor("#8A000000"); - customTheme.commentColor = Color.parseColor("#000000"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#FFFFFF"); - customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.primaryIconColor = Color.parseColor("#000000"); - customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); - customTheme.postIconAndInfoColor = Color.parseColor("#8A000000"); - customTheme.commentIconAndInfoColor = Color.parseColor("#8A000000"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#1565C0"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#1565C0"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#1565C0"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#B3E5F9"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#B3E5F9"); - customTheme.dividerColor = Color.parseColor("#E0E0E0"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.navBarColor = Color.parseColor("#FFFFFF"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = true; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = true; - - return customTheme; - } - - public static CustomTheme getIndigoDark(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_indigo_dark)); - customTheme.isLightTheme = false; - customTheme.isDarkTheme = true; - customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#242424"); - customTheme.colorPrimaryDark = Color.parseColor("#121212"); - customTheme.colorAccent = Color.parseColor("#FF4081"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); - customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); - customTheme.postTitleColor = Color.parseColor("#FFFFFF"); - customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentColor = Color.parseColor("#FFFFFF"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#121212"); - customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); - customTheme.commentBackgroundColor = Color.parseColor("#242424"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); - customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); - customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); - customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); - customTheme.dividerColor = Color.parseColor("#69666C"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#242424"); - customTheme.navBarColor = Color.parseColor("#121212"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = false; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - public static CustomTheme getIndigoAmoled(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_indigo_amoled)); - customTheme.isLightTheme = false; - customTheme.isDarkTheme = false; - customTheme.isAmoledTheme = true; - customTheme.colorPrimary = Color.parseColor("#000000"); - customTheme.colorPrimaryDark = Color.parseColor("#000000"); - customTheme.colorAccent = Color.parseColor("#FF4081"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); - customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); - customTheme.postTitleColor = Color.parseColor("#FFFFFF"); - customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentColor = Color.parseColor("#FFFFFF"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#000000"); - customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); - customTheme.commentBackgroundColor = Color.parseColor("#000000"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); - customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); - customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); - customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); - customTheme.dividerColor = Color.parseColor("#69666C"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#000000"); - customTheme.navBarColor = Color.parseColor("#000000"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = false; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - private static CustomTheme getWhite(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_white)); - customTheme.isLightTheme = true; - customTheme.isDarkTheme = false; - customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#FFFFFF"); - customTheme.colorPrimaryDark = Color.parseColor("#FFFFFF"); - customTheme.colorAccent = Color.parseColor("#000000"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#FFFFFF"); - customTheme.primaryTextColor = Color.parseColor("#000000"); - customTheme.secondaryTextColor = Color.parseColor("#8A000000"); - customTheme.postTitleColor = Color.parseColor("#000000"); - customTheme.postContentColor = Color.parseColor("#8A000000"); - customTheme.commentColor = Color.parseColor("#000000"); - customTheme.buttonTextColor = Color.parseColor("#000000"); - customTheme.backgroundColor = Color.parseColor("#FFFFFF"); - customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.primaryIconColor = Color.parseColor("#000000"); - customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); - customTheme.postIconAndInfoColor = Color.parseColor("#3C4043"); - customTheme.commentIconAndInfoColor = Color.parseColor("#3C4043"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#3C4043"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#3C4043"); - customTheme.circularProgressBarBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#B3E5F9"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#B3E5F9"); - customTheme.dividerColor = Color.parseColor("#E0E0E0"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#000000"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.navBarColor = Color.parseColor("#FFFFFF"); - customTheme.isLightStatusBar = true; - customTheme.isLightNavBar = true; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - private static CustomTheme getWhiteDark(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_white_dark)); - customTheme.isLightTheme = false; - customTheme.isDarkTheme = true; - customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#242424"); - customTheme.colorPrimaryDark = Color.parseColor("#121212"); - customTheme.colorAccent = Color.parseColor("#FFFFFF"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#121212"); - customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); - customTheme.postTitleColor = Color.parseColor("#FFFFFF"); - customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentColor = Color.parseColor("#FFFFFF"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#121212"); - customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); - customTheme.commentBackgroundColor = Color.parseColor("#242424"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); - customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); - customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); - customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); - customTheme.dividerColor = Color.parseColor("#69666C"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#242424"); - customTheme.navBarColor = Color.parseColor("#121212"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = false; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - private static CustomTheme getWhiteAmoled(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_white_amoled)); - customTheme.isLightTheme = false; - customTheme.isDarkTheme = false; - customTheme.isAmoledTheme = true; - customTheme.colorPrimary = Color.parseColor("#000000"); - customTheme.colorPrimaryDark = Color.parseColor("#000000"); - customTheme.colorAccent = Color.parseColor("#FFFFFF"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#000000"); - customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); - customTheme.postTitleColor = Color.parseColor("#FFFFFF"); - customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentColor = Color.parseColor("#FFFFFF"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#000000"); - customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); - customTheme.commentBackgroundColor = Color.parseColor("#000000"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); - customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); - customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); - customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); - customTheme.dividerColor = Color.parseColor("#69666C"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#000000"); - customTheme.navBarColor = Color.parseColor("#000000"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = false; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - private static CustomTheme getRed(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_red)); - customTheme.isLightTheme = true; - customTheme.isDarkTheme = false; - customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#EE0270"); - customTheme.colorPrimaryDark = Color.parseColor("#C60466"); - customTheme.colorAccent = Color.parseColor("#02EE80"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#EE0270"); - customTheme.primaryTextColor = Color.parseColor("#000000"); - customTheme.secondaryTextColor = Color.parseColor("#8A000000"); - customTheme.postTitleColor = Color.parseColor("#000000"); - customTheme.postContentColor = Color.parseColor("#8A000000"); - customTheme.commentColor = Color.parseColor("#000000"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#FFFFFF"); - customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.primaryIconColor = Color.parseColor("#000000"); - customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); - customTheme.postIconAndInfoColor = Color.parseColor("#8A000000"); - customTheme.commentIconAndInfoColor = Color.parseColor("#8A000000"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#EE0270"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#EE0270"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#EE0270"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#B3E5F9"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#B3E5F9"); - customTheme.dividerColor = Color.parseColor("#E0E0E0"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#FFFFFF"); - customTheme.navBarColor = Color.parseColor("#FFFFFF"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = true; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = true; - - return customTheme; - } - - private static CustomTheme getRedDark(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_red_dark)); - customTheme.isLightTheme = false; - customTheme.isDarkTheme = true; - customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#242424"); - customTheme.colorPrimaryDark = Color.parseColor("#121212"); - customTheme.colorAccent = Color.parseColor("#02EE80"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#EE0270"); - customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); - customTheme.postTitleColor = Color.parseColor("#FFFFFF"); - customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentColor = Color.parseColor("#FFFFFF"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#121212"); - customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); - customTheme.commentBackgroundColor = Color.parseColor("#242424"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); - customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); - customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); - customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); - customTheme.dividerColor = Color.parseColor("#69666C"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#242424"); - customTheme.navBarColor = Color.parseColor("#121212"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = false; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - private static CustomTheme getRedAmoled(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_red_amoled)); - customTheme.isLightTheme = false; - customTheme.isDarkTheme = false; - customTheme.isAmoledTheme = true; - customTheme.colorPrimary = Color.parseColor("#000000"); - customTheme.colorPrimaryDark = Color.parseColor("#000000"); - customTheme.colorAccent = Color.parseColor("#02EE80"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#EE0270"); - customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); - customTheme.postTitleColor = Color.parseColor("#FFFFFF"); - customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentColor = Color.parseColor("#FFFFFF"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#000000"); - customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); - customTheme.commentBackgroundColor = Color.parseColor("#000000"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); - customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); - customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#1565C0"); - customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); - customTheme.dividerColor = Color.parseColor("#69666C"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#000000"); - customTheme.navBarColor = Color.parseColor("#000000"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = false; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - private static CustomTheme getDracula(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_dracula)); - customTheme.isLightTheme = true; - customTheme.isDarkTheme = true; - customTheme.isAmoledTheme = true; - customTheme.colorPrimary = Color.parseColor("#393A59"); - customTheme.colorPrimaryDark = Color.parseColor("#393A59"); - customTheme.colorAccent = Color.parseColor("#F8F8F2"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#393A59"); - customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); - customTheme.postTitleColor = Color.parseColor("#FFFFFF"); - customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); - customTheme.commentColor = Color.parseColor("#FFFFFF"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#282A36"); - customTheme.cardViewBackgroundColor = Color.parseColor("#393A59"); - customTheme.commentBackgroundColor = Color.parseColor("#393A59"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#393A59"); - customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); - customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); - customTheme.postIconAndInfoColor = Color.parseColor("#FFFFFF"); - customTheme.commentIconAndInfoColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); - customTheme.circularProgressBarBackground = Color.parseColor("#393A59"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#393A59"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#393A59"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); - customTheme.upvoted = Color.parseColor("#FF008C"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#1E88E5"); - customTheme.subreddit = Color.parseColor("#FF4B9C"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#5F5B85"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#5F5B85"); - customTheme.dividerColor = Color.parseColor("#69666C"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#6272A4"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#777C82"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#8BE9FD"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#50FA7B"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#FFB86C"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#FF79C6"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#BD93F9"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#FF5555"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#F1FA8C"); - customTheme.fabIconColor = Color.parseColor("#FFFFFF"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#393A59"); - customTheme.navBarColor = Color.parseColor("#393A59"); - customTheme.isLightStatusBar = false; - customTheme.isLightNavBar = false; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } - - private static CustomTheme getCalmPastel(Context context) { - CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_calm_pastel)); - customTheme.isLightTheme = true; - customTheme.isDarkTheme = false; - customTheme.isAmoledTheme = false; - customTheme.colorPrimary = Color.parseColor("#D48AE0"); - customTheme.colorPrimaryDark = Color.parseColor("#D476E0"); - customTheme.colorAccent = Color.parseColor("#775EFF"); - customTheme.colorPrimaryLightTheme = Color.parseColor("#D48AE0"); - customTheme.primaryTextColor = Color.parseColor("#000000"); - customTheme.secondaryTextColor = Color.parseColor("#8A000000"); - customTheme.postTitleColor = Color.parseColor("#000000"); - customTheme.postContentColor = Color.parseColor("#8A000000"); - customTheme.commentColor = Color.parseColor("#000000"); - customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); - customTheme.backgroundColor = Color.parseColor("#DAD0DE"); - customTheme.cardViewBackgroundColor = Color.parseColor("#C0F0F4"); - customTheme.commentBackgroundColor = Color.parseColor("#C0F0F4"); - customTheme.bottomAppBarBackgroundColor = Color.parseColor("#D48AE0"); - customTheme.primaryIconColor = Color.parseColor("#000000"); - customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); - customTheme.postIconAndInfoColor = Color.parseColor("#000000"); - customTheme.commentIconAndInfoColor = Color.parseColor("#000000"); - customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#3C4043"); - customTheme.toolbarSecondaryTextColor = Color.parseColor("#3C4043"); - customTheme.circularProgressBarBackground = Color.parseColor("#D48AE0"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#D48AE0"); - customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#D48AE0"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#D48AE0"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); - customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); - customTheme.upvoted = Color.parseColor("#E91E63"); - customTheme.downvoted = Color.parseColor("#007DDE"); - customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); - customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); - customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); - customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); - customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); - customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); - customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); - customTheme.flairTextColor = Color.parseColor("#FFFFFF"); - customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); - customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); - customTheme.archivedTint = Color.parseColor("#B4009F"); - customTheme.lockedIconTint = Color.parseColor("#EE7302"); - customTheme.crosspostIconTint = Color.parseColor("#FF4081"); - customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); - customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); - customTheme.subscribed = Color.parseColor("#FF4081"); - customTheme.unsubscribed = Color.parseColor("#0D47A1"); - customTheme.username = Color.parseColor("#0D47A1"); - customTheme.subreddit = Color.parseColor("#E91E63"); - customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); - customTheme.submitter = Color.parseColor("#EE8A02"); - customTheme.moderator = Color.parseColor("#00BA81"); - customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#25D5E5"); - customTheme.unreadMessageBackgroundColor = Color.parseColor("#25D5E5"); - customTheme.dividerColor = Color.parseColor("#E0E0E0"); - customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); - customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); - customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); - customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); - customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); - customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); - customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); - customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); - customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); - customTheme.fabIconColor = Color.parseColor("#000000"); - customTheme.chipTextColor = Color.parseColor("#FFFFFF"); - customTheme.linkColor = Color.parseColor("#FF4081"); - customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); - customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); - customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); - customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); - customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); - customTheme.awardedCommentBackgroundColor = Color.parseColor("#C0F0F4"); - customTheme.navBarColor = Color.parseColor("#D48AE0"); - customTheme.isLightStatusBar = true; - customTheme.isLightNavBar = true; - customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; - - return customTheme; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioBigImageView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioBigImageView.java deleted file mode 100644 index 43114665..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioBigImageView.java +++ /dev/null @@ -1,60 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomView; - -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; - -import com.github.piasy.biv.view.BigImageView; - -public class AspectRatioBigImageView extends BigImageView { - private float ratio; - - public AspectRatioBigImageView(Context context) { - super(context); - ratio = 1.0F; - } - - public AspectRatioBigImageView(Context context, AttributeSet attrs) { - super(context, attrs); - this.ratio = 1.0F; - this.init(context, attrs); - } - - public AspectRatioBigImageView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - this.ratio = 1.0F; - this.init(context, attrs); - } - - public final float getRatio() { - return this.ratio; - } - - public final void setRatio(float var1) { - this.ratio = var1; - } - - private void init(Context context, AttributeSet attrs) { - if (attrs != null) { - TypedArray a = context.obtainStyledAttributes(attrs, com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView); - this.ratio = a.getFloat(com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView_ari_ratio, 1.0F); - a.recycle(); - } - - } - - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int width = this.getMeasuredWidth(); - int height = this.getMeasuredHeight(); - if (width != 0 || height != 0) { - if (width > 0) { - height = (int) ((float) width * this.ratio); - } else { - width = (int) ((float) height / this.ratio); - } - - this.setMeasuredDimension(width, height); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioGifImageView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioGifImageView.java deleted file mode 100644 index f77f5bd8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioGifImageView.java +++ /dev/null @@ -1,54 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomView; - -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; - -import pl.droidsonroids.gif.GifImageView; - -public class AspectRatioGifImageView extends GifImageView { - private float ratio; - - public AspectRatioGifImageView(Context context) { - super(context); - this.ratio = 1.0F; - } - - public AspectRatioGifImageView(Context context, AttributeSet attrs) { - super(context, attrs); - this.ratio = 1.0F; - this.init(context, attrs); - } - - public final float getRatio() { - return this.ratio; - } - - public final void setRatio(float var1) { - this.ratio = var1; - } - - private void init(Context context, AttributeSet attrs) { - if (attrs != null) { - TypedArray a = context.obtainStyledAttributes(attrs, com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView); - this.ratio = a.getFloat(com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView_ari_ratio, 1.0F); - a.recycle(); - } - - } - - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int width = this.getMeasuredWidth(); - int height = this.getMeasuredHeight(); - if (width != 0 || height != 0) { - if (width > 0) { - height = (int) ((float) width * this.ratio); - } else { - width = (int) ((float) height / this.ratio); - } - - this.setMeasuredDimension(width, height); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioSubsamplingScaleImageView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioSubsamplingScaleImageView.java deleted file mode 100644 index 9877e697..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/AspectRatioSubsamplingScaleImageView.java +++ /dev/null @@ -1,54 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomView; - -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; - -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; - -public class AspectRatioSubsamplingScaleImageView extends SubsamplingScaleImageView { - private float ratio; - - public AspectRatioSubsamplingScaleImageView(Context context) { - super(context); - ratio = 1.0F; - } - - public AspectRatioSubsamplingScaleImageView(Context context, AttributeSet attr) { - super(context, attr); - this.ratio = 1.0F; - this.init(context, attr); - } - - public final float getRatio() { - return this.ratio; - } - - public final void setRatio(float var1) { - this.ratio = var1; - } - - private void init(Context context, AttributeSet attrs) { - if (attrs != null) { - TypedArray a = context.obtainStyledAttributes(attrs, com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView); - this.ratio = a.getFloat(com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView_ari_ratio, 1.0F); - a.recycle(); - } - - } - - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - int width = this.getMeasuredWidth(); - int height = this.getMeasuredHeight(); - if (width != 0 || height != 0) { - if (width > 0) { - height = (int) ((float) width * this.ratio); - } else { - width = (int) ((float) height / this.ratio); - } - - this.setMeasuredDimension(width, height); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java deleted file mode 100644 index ff3f9423..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/ColorPickerDialog.java +++ /dev/null @@ -1,153 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomView; - -import android.content.Context; -import android.graphics.Color; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.SeekBar; -import android.widget.Toast; - -import androidx.appcompat.app.AlertDialog; - -import ml.docilealligator.infinityforreddit.R; - -public class ColorPickerDialog extends AlertDialog { - private View colorView; - private EditText colorValueEditText; - private SeekBar seekBarA; - private SeekBar seekBarR; - private SeekBar seekBarG; - private SeekBar seekBarB; - private Button cancelButton; - private Button okButton; - private int colorValue; - private boolean changeColorValueEditText = true; - private ColorPickerListener colorPickerListener; - - public interface ColorPickerListener { - void onColorPicked(int color); - } - - public ColorPickerDialog(Context context, int color, ColorPickerListener colorPickerListener) { - super(context); - - View rootView = getLayoutInflater().inflate(R.layout.color_picker, null); - colorView = rootView.findViewById(R.id.color_view_color_picker); - colorValueEditText = rootView.findViewById(R.id.color_edit_text_color_picker); - seekBarA = rootView.findViewById(R.id.a_seek_bar_color_picker); - seekBarR = rootView.findViewById(R.id.r_seek_bar_color_picker); - seekBarG = rootView.findViewById(R.id.g_seek_bar_color_picker); - seekBarB = rootView.findViewById(R.id.b_seek_bar_color_picker); - cancelButton = rootView.findViewById(R.id.cancel_button_color_picker); - okButton = rootView.findViewById(R.id.ok_button_color_picker); - - colorView.setBackgroundColor(color); - colorValueEditText.setText(Integer.toHexString(color).toUpperCase()); - colorValueEditText.addTextChangedListener(new TextWatcher() { - @Override - public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { - - } - - @Override - public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { - - } - - @Override - public void afterTextChanged(Editable editable) { - String s = editable.toString(); - if (s.length() == 6) { - try { - changeColorValueEditText = false; - colorValue = Color.parseColor("#" + s); - colorView.setBackgroundColor(colorValue); - seekBarA.setProgress(255); - seekBarR.setProgress(Integer.parseInt(s.substring(0, 2), 16)); - seekBarG.setProgress(Integer.parseInt(s.substring(2, 4), 16)); - seekBarB.setProgress(Integer.parseInt(s.substring(4, 6), 16)); - changeColorValueEditText = true; - } catch (IllegalArgumentException ignored) { - - } - } else if (s.length() == 8) { - try { - changeColorValueEditText = false; - colorValue = Color.parseColor("#" + s); - colorView.setBackgroundColor(colorValue); - seekBarA.setProgress(Integer.parseInt(s.substring(0, 2), 16)); - seekBarR.setProgress(Integer.parseInt(s.substring(2, 4), 16)); - seekBarG.setProgress(Integer.parseInt(s.substring(4, 6), 16)); - seekBarB.setProgress(Integer.parseInt(s.substring(6, 8), 16)); - changeColorValueEditText = true; - } catch (IllegalArgumentException ignored) { - - } - } - } - }); - - String colorHex = Integer.toHexString(color); - if (colorHex.length() == 8) { - colorValue = Color.parseColor("#" + colorHex); - seekBarA.setProgress(Integer.parseInt(colorHex.substring(0, 2), 16)); - seekBarR.setProgress(Integer.parseInt(colorHex.substring(2, 4), 16)); - seekBarG.setProgress(Integer.parseInt(colorHex.substring(4, 6), 16)); - seekBarB.setProgress(Integer.parseInt(colorHex.substring(6, 8), 16)); - } else if (colorHex.length() == 6) { - colorValue = Color.parseColor("#" + colorHex); - seekBarA.setProgress(255); - seekBarR.setProgress(Integer.parseInt(colorHex.substring(0, 2), 16)); - seekBarG.setProgress(Integer.parseInt(colorHex.substring(2, 4), 16)); - seekBarB.setProgress(Integer.parseInt(colorHex.substring(4, 6), 16)); - } - setOnSeekBarChangeListener(seekBarA); - setOnSeekBarChangeListener(seekBarR); - setOnSeekBarChangeListener(seekBarG); - setOnSeekBarChangeListener(seekBarB); - - cancelButton.setOnClickListener(view -> dismiss()); - okButton.setOnClickListener(view -> { - try { - colorValue = Color.parseColor("#" + colorValueEditText.getText().toString()); - colorPickerListener.onColorPicked(colorValue); - dismiss(); - } catch (IllegalArgumentException e) { - Toast.makeText(context, R.string.invalid_color, Toast.LENGTH_SHORT).show(); - } - }); - - setView(rootView); - } - - private void setOnSeekBarChangeListener(SeekBar seekBar) { - seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - if (changeColorValueEditText) { - int aValue = seekBarA.getProgress(); - int rValue = seekBarR.getProgress(); - int gValue = seekBarG.getProgress(); - int bValue = seekBarB.getProgress(); - String colorHex = String.format("%02x%02x%02x%02x", aValue, rValue, gValue, bValue).toUpperCase(); - colorValue = Color.parseColor("#" + colorHex); - colorView.setBackgroundColor(colorValue); - colorValueEditText.setText(colorHex); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/CustomToroContainer.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/CustomToroContainer.java deleted file mode 100644 index 40e3fe3e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/CustomToroContainer.java +++ /dev/null @@ -1,27 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomView; - -import android.content.Context; -import android.util.AttributeSet; - -import androidx.annotation.Nullable; - -import im.ene.toro.widget.Container; - -public class CustomToroContainer extends Container { - public CustomToroContainer(Context context) { - super(context); - } - - public CustomToroContainer(Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - } - - public CustomToroContainer(Context context, @Nullable AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - } - - @Override - public void onWindowVisibilityChanged(int visibility) { - super.onWindowVisibilityChanged(visibility); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java deleted file mode 100644 index 286aaf4c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/LollipopBugFixedWebView.java +++ /dev/null @@ -1,28 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomView; - -import android.content.Context; -import android.content.res.Configuration; -import android.os.Build; -import android.util.AttributeSet; -import android.webkit.WebView; - -public class LollipopBugFixedWebView extends WebView{ - public LollipopBugFixedWebView(Context context) { - super(getFixedContext(context)); - } - - public LollipopBugFixedWebView(Context context, AttributeSet attrs) { - super(getFixedContext(context), attrs); - } - - public LollipopBugFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) { - super(getFixedContext(context), attrs, defStyleAttr); - } - - // To fix Android Lollipop WebView problem create a new configuration on that Android version only - private static Context getFixedContext(Context context) { - if (Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22) // Android Lollipop 5.0 & 5.1 - return context.createConfigurationContext(new Configuration()); - return context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/MarkwonLinearLayoutManager.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/MarkwonLinearLayoutManager.java deleted file mode 100644 index 56f3dddc..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CustomView/MarkwonLinearLayoutManager.java +++ /dev/null @@ -1,42 +0,0 @@ -package ml.docilealligator.infinityforreddit.CustomView; - -import android.content.Context; -import android.view.View; -import android.view.ViewTreeObserver; -import android.widget.HorizontalScrollView; - -import androidx.recyclerview.widget.LinearLayoutManager; - -public class MarkwonLinearLayoutManager extends LinearLayoutManager { - public interface HorizontalScrollViewScrolledListener { - void onScrolledLeft(); - void onScrolledRight(); - } - - private HorizontalScrollViewScrolledListener horizontalScrollViewScrolledListener; - - public MarkwonLinearLayoutManager(Context context, HorizontalScrollViewScrolledListener horizontalScrollViewScrolledListener) { - super(context); - this.horizontalScrollViewScrolledListener = horizontalScrollViewScrolledListener; - } - - @Override - public void addView(View child) { - super.addView(child); - if (child instanceof HorizontalScrollView) { - child.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { - private int x = 0; - @Override - public void onScrollChanged() { - if (child.getScrollX() < x) { - horizontalScrollViewScrolledListener.onScrolledLeft(); - } else { - horizontalScrollViewScrolledListener.onScrolledRight(); - } - - x = child.getScrollX(); - } - }); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/DeleteThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/DeleteThing.java index 9e06de80..0d0d0b0e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/DeleteThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/DeleteThing.java @@ -5,8 +5,8 @@ import androidx.annotation.NonNull; import java.util.HashMap; import java.util.Map; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeAutoplayNsfwVideosEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeAutoplayNsfwVideosEvent.java deleted file mode 100644 index 47af8163..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeAutoplayNsfwVideosEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeAutoplayNsfwVideosEvent { - public boolean autoplayNsfwVideos; - - public ChangeAutoplayNsfwVideosEvent(boolean autoplayNsfwVideos) { - this.autoplayNsfwVideos = autoplayNsfwVideos; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java deleted file mode 100644 index be9349ba..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeCompactLayoutToolbarHiddenByDefaultEvent { - public boolean compactLayoutToolbarHiddenByDefault; - - public ChangeCompactLayoutToolbarHiddenByDefaultEvent(boolean compactLayoutToolbarHiddenByDefault) { - this.compactLayoutToolbarHiddenByDefault = compactLayoutToolbarHiddenByDefault; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeConfirmToExitEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeConfirmToExitEvent.java deleted file mode 100644 index 9371c9ac..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeConfirmToExitEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeConfirmToExitEvent { - public boolean confirmToExit; - - public ChangeConfirmToExitEvent(boolean confirmToExit) { - this.confirmToExit = confirmToExit; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDataSavingModeEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDataSavingModeEvent.java deleted file mode 100644 index 2be45caf..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDataSavingModeEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeDataSavingModeEvent { - public String dataSavingMode; - - public ChangeDataSavingModeEvent(String dataSavingMode) { - this.dataSavingMode = dataSavingMode; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDefaultPostLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDefaultPostLayoutEvent.java deleted file mode 100644 index 2a5819fb..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDefaultPostLayoutEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeDefaultPostLayoutEvent { - public int defaultPostLayout; - - public ChangeDefaultPostLayoutEvent(int defaultPostLayout) { - this.defaultPostLayout = defaultPostLayout; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableImagePreviewEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableImagePreviewEvent.java deleted file mode 100644 index 85c7122d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableImagePreviewEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeDisableImagePreviewEvent { - public boolean disableImagePreview; - - public ChangeDisableImagePreviewEvent(boolean disableImagePreview) { - this.disableImagePreview = disableImagePreview; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableSwipingBetweenTabsEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableSwipingBetweenTabsEvent.java deleted file mode 100644 index 371954e8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeDisableSwipingBetweenTabsEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeDisableSwipingBetweenTabsEvent { - public boolean disableSwipingBetweenTabs; - - public ChangeDisableSwipingBetweenTabsEvent(boolean disableSwipingBetweenTabs) { - this.disableSwipingBetweenTabs = disableSwipingBetweenTabs; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeEnableSwipeActionSwitchEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeEnableSwipeActionSwitchEvent.java deleted file mode 100644 index 5c67246f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeEnableSwipeActionSwitchEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeEnableSwipeActionSwitchEvent { - public boolean enableSwipeAction; - - public ChangeEnableSwipeActionSwitchEvent(boolean enableSwipeAction) { - this.enableSwipeAction = enableSwipeAction; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLockBottomAppBarEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLockBottomAppBarEvent.java deleted file mode 100644 index 45d483c6..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLockBottomAppBarEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeLockBottomAppBarEvent { - public boolean lockBottomAppBar; - - public ChangeLockBottomAppBarEvent(boolean lockBottomAppBar) { - this.lockBottomAppBar = lockBottomAppBar; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLongPressToHideToolbarInCompactLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLongPressToHideToolbarInCompactLayoutEvent.java deleted file mode 100644 index 1d1cfcdf..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeLongPressToHideToolbarInCompactLayoutEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeLongPressToHideToolbarInCompactLayoutEvent { - public boolean longPressToHideToolbarInCompactLayout; - - public ChangeLongPressToHideToolbarInCompactLayoutEvent(boolean longPressToHideToolbarInCompactLayout) { - this.longPressToHideToolbarInCompactLayout = longPressToHideToolbarInCompactLayout; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteAutoplayingVideosEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteAutoplayingVideosEvent.java deleted file mode 100644 index 421be2a1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteAutoplayingVideosEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeMuteAutoplayingVideosEvent { - public boolean muteAutoplayingVideos; - - public ChangeMuteAutoplayingVideosEvent(boolean muteAutoplayingVideos) { - this.muteAutoplayingVideos = muteAutoplayingVideos; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteNSFWVideoEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteNSFWVideoEvent.java deleted file mode 100644 index 92e26562..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeMuteNSFWVideoEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeMuteNSFWVideoEvent { - public boolean muteNSFWVideo; - - public ChangeMuteNSFWVideoEvent(boolean muteNSFWVideo) { - this.muteNSFWVideo = muteNSFWVideo; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWBlurEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWBlurEvent.java deleted file mode 100644 index 9bd868b4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWBlurEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeNSFWBlurEvent { - public boolean needBlurNSFW; - - public ChangeNSFWBlurEvent(boolean needBlurNSFW) { - this.needBlurNSFW = needBlurNSFW; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWEvent.java deleted file mode 100644 index ba19f652..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNSFWEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeNSFWEvent { - public boolean nsfw; - - public ChangeNSFWEvent(boolean nsfw) { - this.nsfw = nsfw; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNetworkStatusEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNetworkStatusEvent.java deleted file mode 100644 index 7fe86dee..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeNetworkStatusEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeNetworkStatusEvent { - public int connectedNetwork; - - public ChangeNetworkStatusEvent(int connectedNetwork) { - this.connectedNetwork = connectedNetwork; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangePostLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangePostLayoutEvent.java deleted file mode 100644 index a02b1373..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangePostLayoutEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangePostLayoutEvent { - public int postLayout; - - public ChangePostLayoutEvent(int postLayout) { - this.postLayout = postLayout; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeRequireAuthToAccountSectionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeRequireAuthToAccountSectionEvent.java deleted file mode 100644 index d8455db5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeRequireAuthToAccountSectionEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeRequireAuthToAccountSectionEvent { - public boolean requireAuthToAccountSection; - - public ChangeRequireAuthToAccountSectionEvent(boolean requireAuthToAccountSection) { - this.requireAuthToAccountSection = requireAuthToAccountSection; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSavePostFeedScrolledPositionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSavePostFeedScrolledPositionEvent.java deleted file mode 100644 index 5dd363eb..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSavePostFeedScrolledPositionEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeSavePostFeedScrolledPositionEvent { - public boolean savePostFeedScrolledPosition; - - public ChangeSavePostFeedScrolledPositionEvent(boolean savePostFeedScrolledPosition) { - this.savePostFeedScrolledPosition = savePostFeedScrolledPosition; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowAbsoluteNumberOfVotesEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowAbsoluteNumberOfVotesEvent.java deleted file mode 100644 index c0547c20..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowAbsoluteNumberOfVotesEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeShowAbsoluteNumberOfVotesEvent { - public boolean showAbsoluteNumberOfVotes; - - public ChangeShowAbsoluteNumberOfVotesEvent(boolean showAbsoluteNumberOfVotes) { - this.showAbsoluteNumberOfVotes = showAbsoluteNumberOfVotes; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowElapsedTimeEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowElapsedTimeEvent.java deleted file mode 100644 index 2b715833..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeShowElapsedTimeEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeShowElapsedTimeEvent { - public boolean showElapsedTime; - - public ChangeShowElapsedTimeEvent(boolean showElapsedTime) { - this.showElapsedTime = showElapsedTime; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSpoilerBlurEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSpoilerBlurEvent.java deleted file mode 100644 index 24644b8d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSpoilerBlurEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeSpoilerBlurEvent { - public boolean needBlurSpoiler; - - public ChangeSpoilerBlurEvent(boolean needBlurSpoiler) { - this.needBlurSpoiler = needBlurSpoiler; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeStartAutoplayVisibleAreaOffsetEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeStartAutoplayVisibleAreaOffsetEvent.java deleted file mode 100644 index 34fc48a9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeStartAutoplayVisibleAreaOffsetEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeStartAutoplayVisibleAreaOffsetEvent { - public double startAutoplayVisibleAreaOffset; - - public ChangeStartAutoplayVisibleAreaOffsetEvent(double startAutoplayVisibleAreaOffset) { - this.startAutoplayVisibleAreaOffset = startAutoplayVisibleAreaOffset; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionEvent.java deleted file mode 100644 index fabda6ff..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeSwipeActionEvent { - public int swipeLeftAction; - public int swipeRightAction; - - public ChangeSwipeActionEvent(int swipeLeftAction, int swipeRightAction) { - this.swipeLeftAction = swipeLeftAction; - this.swipeRightAction = swipeRightAction; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionThresholdEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionThresholdEvent.java deleted file mode 100644 index d040e0fe..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeSwipeActionThresholdEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeSwipeActionThresholdEvent { - public float swipeActionThreshold; - - public ChangeSwipeActionThresholdEvent(float swipeActionThreshold) { - this.swipeActionThreshold = swipeActionThreshold; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeTimeFormatEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeTimeFormatEvent.java deleted file mode 100644 index 440e0171..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeTimeFormatEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeTimeFormatEvent { - public String timeFormat; - - public ChangeTimeFormatEvent(String timeFormat) { - this.timeFormat = timeFormat; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVibrateWhenActionTriggeredEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVibrateWhenActionTriggeredEvent.java deleted file mode 100644 index bef491d6..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVibrateWhenActionTriggeredEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeVibrateWhenActionTriggeredEvent { - public boolean vibrateWhenActionTriggered; - - public ChangeVibrateWhenActionTriggeredEvent(boolean vibrateWhenActionTriggered) { - this.vibrateWhenActionTriggered = vibrateWhenActionTriggered; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVideoAutoplayEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVideoAutoplayEvent.java deleted file mode 100644 index 76e7a589..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVideoAutoplayEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeVideoAutoplayEvent { - public String autoplay; - - public ChangeVideoAutoplayEvent(String autoplay) { - this.autoplay = autoplay; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVoteButtonsPositionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVoteButtonsPositionEvent.java deleted file mode 100644 index 00f506ab..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ChangeVoteButtonsPositionEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ChangeVoteButtonsPositionEvent { - public boolean voteButtonsOnTheRight; - - public ChangeVoteButtonsPositionEvent(boolean voteButtonsOnTheRight) { - this.voteButtonsOnTheRight = voteButtonsOnTheRight; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadMediaEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadMediaEvent.java deleted file mode 100644 index 174b49ea..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadMediaEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class DownloadMediaEvent { - public boolean isSuccessful; - - public DownloadMediaEvent(boolean isSuccessful) { - this.isSuccessful = isSuccessful; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadRedditVideoEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadRedditVideoEvent.java deleted file mode 100644 index 2edb279e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/DownloadRedditVideoEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class DownloadRedditVideoEvent { - public boolean isSuccessful; - - public DownloadRedditVideoEvent(boolean isSuccessful) { - this.isSuccessful = isSuccessful; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/GoBackToMainPageEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/GoBackToMainPageEvent.java deleted file mode 100644 index 8457d6dc..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/GoBackToMainPageEvent.java +++ /dev/null @@ -1,4 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class GoBackToMainPageEvent { -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToDetailActivity.java deleted file mode 100644 index bb935590..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToDetailActivity.java +++ /dev/null @@ -1,11 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -import ml.docilealligator.infinityforreddit.Post.Post; - -public class PostUpdateEventToDetailActivity { - public final Post post; - - public PostUpdateEventToDetailActivity(Post post) { - this.post = post; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToPostList.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToPostList.java deleted file mode 100644 index f37ae7bc..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/PostUpdateEventToPostList.java +++ /dev/null @@ -1,13 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -import ml.docilealligator.infinityforreddit.Post.Post; - -public class PostUpdateEventToPostList { - public final Post post; - public final int positionInList; - - public PostUpdateEventToPostList(Post post, int positionInList) { - this.post = post; - this.positionInList = positionInList; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RecreateActivityEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RecreateActivityEvent.java deleted file mode 100644 index 35fe54a1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RecreateActivityEvent.java +++ /dev/null @@ -1,4 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class RecreateActivityEvent { -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RefreshMultiRedditsEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RefreshMultiRedditsEvent.java deleted file mode 100644 index 0b0ccf3f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RefreshMultiRedditsEvent.java +++ /dev/null @@ -1,4 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class RefreshMultiRedditsEvent { -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RepliedToPrivateMessageEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RepliedToPrivateMessageEvent.java deleted file mode 100644 index 59d82f3c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/RepliedToPrivateMessageEvent.java +++ /dev/null @@ -1,13 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -import ml.docilealligator.infinityforreddit.Message.Message; - -public class RepliedToPrivateMessageEvent { - public Message newReply; - public int messagePosition; - - public RepliedToPrivateMessageEvent(Message newReply, int messagePosition) { - this.newReply = newReply; - this.messagePosition = messagePosition; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowDividerInCompactLayoutPreferenceEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowDividerInCompactLayoutPreferenceEvent.java deleted file mode 100644 index eb53c58e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowDividerInCompactLayoutPreferenceEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ShowDividerInCompactLayoutPreferenceEvent { - public boolean showDividerInCompactLayout; - - public ShowDividerInCompactLayoutPreferenceEvent(boolean showDividerInCompactLayout) { - this.showDividerInCompactLayout = showDividerInCompactLayout; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowThumbnailOnTheRightInCompactLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowThumbnailOnTheRightInCompactLayoutEvent.java deleted file mode 100644 index f1010773..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/ShowThumbnailOnTheRightInCompactLayoutEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class ShowThumbnailOnTheRightInCompactLayoutEvent { - public boolean showThumbnailOnTheRightInCompactLayout; - - public ShowThumbnailOnTheRightInCompactLayoutEvent(boolean showThumbnailOnTheRightInCompactLayout) { - this.showThumbnailOnTheRightInCompactLayout = showThumbnailOnTheRightInCompactLayout; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitCrosspostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitCrosspostEvent.java deleted file mode 100644 index 55b4a5bd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitCrosspostEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -import ml.docilealligator.infinityforreddit.Post.Post; - -public class SubmitCrosspostEvent { - public boolean postSuccess; - public Post post; - public String errorMessage; - - public SubmitCrosspostEvent(boolean postSuccess, Post post, String errorMessage) { - this.postSuccess = postSuccess; - this.post = post; - this.errorMessage = errorMessage; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitImagePostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitImagePostEvent.java deleted file mode 100644 index 7c0f5064..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitImagePostEvent.java +++ /dev/null @@ -1,11 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class SubmitImagePostEvent { - public boolean postSuccess; - public String errorMessage; - - public SubmitImagePostEvent(boolean postSuccess, String errorMessage) { - this.postSuccess = postSuccess; - this.errorMessage = errorMessage; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitTextOrLinkPostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitTextOrLinkPostEvent.java deleted file mode 100644 index 0e164b60..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitTextOrLinkPostEvent.java +++ /dev/null @@ -1,15 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -import ml.docilealligator.infinityforreddit.Post.Post; - -public class SubmitTextOrLinkPostEvent { - public boolean postSuccess; - public Post post; - public String errorMessage; - - public SubmitTextOrLinkPostEvent(boolean postSuccess, Post post, String errorMessage) { - this.postSuccess = postSuccess; - this.post = post; - this.errorMessage = errorMessage; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitVideoOrGifPostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitVideoOrGifPostEvent.java deleted file mode 100644 index b6f96dc9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SubmitVideoOrGifPostEvent.java +++ /dev/null @@ -1,13 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class SubmitVideoOrGifPostEvent { - public boolean postSuccess; - public boolean errorProcessingVideoOrGif; - public String errorMessage; - - public SubmitVideoOrGifPostEvent(boolean postSuccess, boolean errorProcessingVideoOrGif, String errorMessage) { - this.postSuccess = postSuccess; - this.errorProcessingVideoOrGif = errorProcessingVideoOrGif; - this.errorMessage = errorMessage; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SwitchAccountEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SwitchAccountEvent.java deleted file mode 100644 index 18f267c2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Event/SwitchAccountEvent.java +++ /dev/null @@ -1,12 +0,0 @@ -package ml.docilealligator.infinityforreddit.Event; - -public class SwitchAccountEvent { - public String excludeActivityClassName; - - public SwitchAccountEvent() { - } - - public SwitchAccountEvent(String excludeActivityClassName) { - this.excludeActivityClassName = excludeActivityClassName; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FavoriteThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FavoriteThing.java index 0333a6df..1bc7b002 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FavoriteThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FavoriteThing.java @@ -5,11 +5,11 @@ import androidx.annotation.NonNull; import java.util.HashMap; import java.util.Map; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertSubscribedThingsAsyncTask; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.asynctasks.InsertSubscribedThingsAsyncTask; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchFlairs.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchFlairs.java index b00d52d3..42384e78 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchFlairs.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchFlairs.java @@ -9,9 +9,9 @@ import org.json.JSONException; import java.util.ArrayList; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java index 4567fe85..32769529 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchGfycatOrRedgifsVideoLinks.java @@ -7,8 +7,8 @@ import androidx.annotation.NonNull; import org.json.JSONException; import org.json.JSONObject; -import ml.docilealligator.infinityforreddit.API.GfycatAPI; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import ml.docilealligator.infinityforreddit.apis.GfycatAPI; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMyInfo.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMyInfo.java index 739cea6f..b1ac07eb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMyInfo.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchMyInfo.java @@ -8,9 +8,9 @@ import androidx.annotation.NonNull; import org.json.JSONException; import org.json.JSONObject; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Retrofit; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java index 877c614c..69f0fa58 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchRules.java @@ -10,9 +10,9 @@ import org.json.JSONObject; import java.util.ArrayList; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java index 7f2a4773..d40291c0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchSubscribedThing.java @@ -4,11 +4,11 @@ import androidx.annotation.NonNull; import java.util.ArrayList; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java index 5d3586bc..86ae73cb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java @@ -11,9 +11,9 @@ import org.json.JSONObject; import java.util.ArrayList; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontFamily.java deleted file mode 100644 index f24786fa..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontFamily.java +++ /dev/null @@ -1,36 +0,0 @@ -package ml.docilealligator.infinityforreddit.Font; - -import ml.docilealligator.infinityforreddit.R; - -public enum ContentFontFamily { - Default(R.style.ContentFontFamily, "Default"), - BalsamiqSans(R.style.ContentFontFamily_BalsamiqSans, "BalsamiqSansBold"), - BalsamiqSansBold(R.style.ContentFontFamily_BalsamiqSansBold, "BalsamiqSansBold"), - NotoSans(R.style.ContentFontFamily_NotoSans, "NotoSans"), - NotoSansBold(R.style.ContentFontFamily_NotoSansBold, "NotoSansBold"), - RobotoCondensed(R.style.ContentFontFamily_RobotoCondensed, "RobotoCondensed"), - RobotoCondensedBold(R.style.ContentFontFamily_RobotoCondensedBold, "RobotoCondensedBold"), - HarmoniaSans(R.style.ContentFontFamily_HarmoniaSans, "HarmoniaSans"), - HarmoniaSansBold(R.style.ContentFontFamily_HarmoniaSansBold, "HarmoniaSansBold"), - Inter(R.style.ContentFontFamily_Inter, "Inter"), - InterBold(R.style.ContentFontFamily_InterBold, "InterBold"), - Manrope(R.style.ContentFontFamily_Manrope, "Manrope"), - ManropeBold(R.style.ContentFontFamily_ManropeBold, "ManropeBold"), - Sriracha(R.style.ContentFontFamily_Sriracha, "Sriracha"); - - private int resId; - private String title; - - ContentFontFamily(int resId, String title) { - this.resId = resId; - this.title = title; - } - - public int getResId() { - return resId; - } - - public String getTitle() { - return title; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontStyle.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontStyle.java deleted file mode 100644 index 654cff07..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/ContentFontStyle.java +++ /dev/null @@ -1,27 +0,0 @@ -package ml.docilealligator.infinityforreddit.Font; - -import ml.docilealligator.infinityforreddit.R; - -public enum ContentFontStyle { - Small(R.style.ContentFontStyle_Small, "Small"), - Normal(R.style.ContentFontStyle_Normal, "Normal"), - Large(R.style.ContentFontStyle_Large, "Large"), - XLarge(R.style.ContentFontStyle_XLarge, "XLarge"), - XXLarge(R.style.ContentFontStyle_XXLarge, "XXLarge"); - - private int resId; - private String title; - - ContentFontStyle(int resId, String title) { - this.resId = resId; - this.title = title; - } - - public int getResId() { - return resId; - } - - public String getTitle() { - return title; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontFamily.java deleted file mode 100644 index 09198c8f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontFamily.java +++ /dev/null @@ -1,36 +0,0 @@ -package ml.docilealligator.infinityforreddit.Font; - -import ml.docilealligator.infinityforreddit.R; - -public enum FontFamily { - Default(R.style.FontFamily, "Default"), - BalsamiqSans(R.style.FontFamily_BalsamiqSans, "BalsamiqSans"), - BalsamiqSansBold(R.style.FontFamily_BalsamiqSansBold, "BalsamiqSansBold"), - NotoSans(R.style.FontFamily_NotoSans, "NotoSans"), - NotoSansBold(R.style.FontFamily_NotoSansBold, "NotoSansBold"), - RobotoCondensed(R.style.FontFamily_RobotoCondensed, "RobotoCondensed"), - RobotoCondensedBold(R.style.FontFamily_RobotoCondensedBold, "RobotoCondensedBold"), - HarmoniaSans(R.style.FontFamily_HarmoniaSans, "HarmoniaSans"), - HarmoniaSansBold(R.style.FontFamily_HarmoniaSansBold, "HarmoniaSansBold"), - Inter(R.style.FontFamily_Inter, "Inter"), - InterBold(R.style.FontFamily_InterBold, "InterBold"), - Manrope(R.style.FontFamily_Manrope, "Manrope"), - ManropeBold(R.style.FontFamily_ManropeBold, "ManropeBold"), - Sriracha(R.style.FontFamily_Sriracha, "Sriracha"); - - private int resId; - private String title; - - FontFamily(int resId, String title) { - this.resId = resId; - this.title = title; - } - - public int getResId() { - return resId; - } - - public String getTitle() { - return title; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontStyle.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontStyle.java deleted file mode 100644 index 101b17b4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/FontStyle.java +++ /dev/null @@ -1,26 +0,0 @@ -package ml.docilealligator.infinityforreddit.Font; - -import ml.docilealligator.infinityforreddit.R; - -public enum FontStyle { - Small(R.style.FontStyle_Small, "Small"), - Normal(R.style.FontStyle_Normal, "Normal"), - Large(R.style.FontStyle_Large, "Large"), - XLarge(R.style.FontStyle_XLarge, "XLarge"); - - private int resId; - private String title; - - FontStyle(int resId, String title) { - this.resId = resId; - this.title = title; - } - - public int getResId() { - return resId; - } - - public String getTitle() { - return title; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontFamily.java deleted file mode 100644 index eff158d0..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontFamily.java +++ /dev/null @@ -1,36 +0,0 @@ -package ml.docilealligator.infinityforreddit.Font; - -import ml.docilealligator.infinityforreddit.R; - -public enum TitleFontFamily { - Default(R.style.TitleFontFamily, "Default"), - BalsamiqSans(R.style.TitleFontFamily_BalsamiqSans, "BalsamiqSans"), - BalsamiqSansBold(R.style.TitleFontFamily_BalsamiqSansBold, "BalsamiqSansBold"), - NotoSans(R.style.TitleFontFamily_NotoSans, "NotoSans"), - NotoSansBold(R.style.TitleFontFamily_NotoSansBold, "NotoSansBold"), - RobotoCondensed(R.style.TitleFontFamily_RobotoCondensed, "RobotoCondensed"), - RobotoCondensedBold(R.style.TitleFontFamily_RobotoCondensedBold, "RobotoCondensedBold"), - HarmoniaSans(R.style.TitleFontFamily_HarmoniaSans, "HarmoniaSans"), - HarmoniaSansBold(R.style.TitleFontFamily_HarmoniaSansBold, "HarmoniaSansBold"), - Inter(R.style.TitleFontFamily_Inter, "Inter"), - InterBold(R.style.TitleFontFamily_InterBold, "InterBold"), - Manrope(R.style.TitleFontFamily_Manrope, "Manrope"), - ManropeBold(R.style.TitleFontFamily_ManropeBold, "ManropeBold"), - Sriracha(R.style.TitleFontFamily_Sriracha, "Sriracha"); - - private int resId; - private String title; - - TitleFontFamily(int resId, String title) { - this.resId = resId; - this.title = title; - } - - public int getResId() { - return resId; - } - - public String getTitle() { - return title; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontStyle.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontStyle.java deleted file mode 100644 index 9ac48525..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Font/TitleFontStyle.java +++ /dev/null @@ -1,26 +0,0 @@ -package ml.docilealligator.infinityforreddit.Font; - -import ml.docilealligator.infinityforreddit.R; - -public enum TitleFontStyle { - Small(R.style.TitleFontStyle_Small, "Small"), - Normal(R.style.TitleFontStyle_Normal, "Normal"), - Large(R.style.TitleFontStyle_Large, "Large"), - XLarge(R.style.TitleFontStyle_XLarge, "XLarge"); - - private int resId; - private String title; - - TitleFontStyle(int resId, String title) { - this.resId = resId; - this.title = title; - } - - public int getResId() { - return resId; - } - - public String getTitle() { - return title; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ChangePullToRefreshEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ChangePullToRefreshEvent.java deleted file mode 100644 index ea1d2234..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ChangePullToRefreshEvent.java +++ /dev/null @@ -1,9 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -public class ChangePullToRefreshEvent { - public boolean pullToRefresh; - - public ChangePullToRefreshEvent(boolean pullToRefresh) { - this.pullToRefresh = pullToRefresh; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/CommentsListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/CommentsListingFragment.java deleted file mode 100644 index e04b3716..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/CommentsListingFragment.java +++ /dev/null @@ -1,416 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.Bundle; -import android.view.HapticFeedbackConstants; -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.coordinatorlayout.widget.CoordinatorLayout; -import androidx.core.content.res.ResourcesCompat; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Adapter.CommentsListingRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; -import ml.docilealligator.infinityforreddit.Comment.CommentViewModel; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Retrofit; - - -/** - * A simple {@link Fragment} subclass. - */ -public class CommentsListingFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_USERNAME = "EN"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - public static final String EXTRA_ARE_SAVED_COMMENTS = "EISC"; - - private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; - private static final String ACCESS_TOKEN_STATE = "ATS"; - - @BindView(R.id.coordinator_layout_comments_listing_fragment) - CoordinatorLayout mCoordinatorLayout; - @BindView(R.id.swipe_refresh_layout_view_comments_listing_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_comments_listing_fragment) - RecyclerView mCommentRecyclerView; - @BindView(R.id.fetch_comments_info_linear_layout_comments_listing_fragment) - LinearLayout mFetchCommentInfoLinearLayout; - @BindView(R.id.fetch_comments_info_image_view_comments_listing_fragment) - ImageView mFetchCommentInfoImageView; - @BindView(R.id.fetch_comments_info_text_view_comments_listing_fragment) - TextView mFetchCommentInfoTextView; - CommentViewModel mCommentViewModel; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - CustomThemeWrapper customThemeWrapper; - private boolean mNullAccessToken = false; - private String mAccessToken; - private RequestManager mGlide; - private Activity mActivity; - private LinearLayoutManager mLinearLayoutManager; - private CommentsListingRecyclerViewAdapter mAdapter; - private SortType sortType; - private ColorDrawable backgroundSwipeRight; - private ColorDrawable backgroundSwipeLeft; - private Drawable drawableSwipeRight; - private Drawable drawableSwipeLeft; - private int swipeLeftAction; - private int swipeRightAction; - private float swipeActionThreshold; - private ItemTouchHelper touchHelper; - - public CommentsListingFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_comments_listing, container, false); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - applyTheme(); - - mGlide = Glide.with(mActivity); - - Resources resources = getResources(); - - if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { - mCommentRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { - mCommentRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); - } - } - - boolean enableSwipeAction = mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false); - boolean 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 CommentsListingRecyclerViewAdapter.CommentViewHolder)) { - return makeMovementFlags(0, 0); - } - int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; - return makeMovementFlags(0, swipeFlags); - } - - @Override - public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { - return false; - } - - @Override - public boolean isItemViewSwipeEnabled() { - return true; - } - - @Override - public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { - if (touchHelper != null) { - touchHelper.attachToRecyclerView(null); - touchHelper.attachToRecyclerView(mCommentRecyclerView); - if (mAdapter != null) { - mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); - } - } - } - - @Override - public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { - super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); - - View itemView = viewHolder.itemView; - int horizontalOffset = (int) Utils.convertDpToPixel(16, mActivity); - if (dX > 0) { - if (dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { - if (!exceedThreshold) { - exceedThreshold = true; - if (vibrateWhenActionTriggered) { - viewHolder.itemView.setHapticFeedbackEnabled(true); - viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } - backgroundSwipeRight.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); - } else { - exceedThreshold = false; - backgroundSwipeRight.setBounds(0, 0, 0, 0); - } - - drawableSwipeRight.setBounds(itemView.getLeft() + ((int) dX) - horizontalOffset - drawableSwipeRight.getIntrinsicWidth(), - (itemView.getBottom() + itemView.getTop() - drawableSwipeRight.getIntrinsicHeight()) / 2, - itemView.getLeft() + ((int) dX) - horizontalOffset, - (itemView.getBottom() + itemView.getTop() + drawableSwipeRight.getIntrinsicHeight()) / 2); - backgroundSwipeRight.draw(c); - drawableSwipeRight.draw(c); - } else if (dX < 0) { - if (-dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { - if (!exceedThreshold) { - exceedThreshold = true; - if (vibrateWhenActionTriggered) { - viewHolder.itemView.setHapticFeedbackEnabled(true); - viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } - backgroundSwipeLeft.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); - } else { - exceedThreshold = false; - backgroundSwipeLeft.setBounds(0, 0, 0, 0); - } - drawableSwipeLeft.setBounds(itemView.getRight() + ((int) dX) + horizontalOffset, - (itemView.getBottom() + itemView.getTop() - drawableSwipeLeft.getIntrinsicHeight()) / 2, - itemView.getRight() + ((int) dX) + horizontalOffset + drawableSwipeLeft.getIntrinsicWidth(), - (itemView.getBottom() + itemView.getTop() + drawableSwipeLeft.getIntrinsicHeight()) / 2); - backgroundSwipeLeft.draw(c); - drawableSwipeLeft.draw(c); - } - } - - @Override - public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { - return swipeActionThreshold; - } - }); - - if (enableSwipeAction) { - touchHelper.attachToRecyclerView(mCommentRecyclerView); - } - - if (savedInstanceState == null) { - getCurrentAccountAndBindView(resources); - } else { - mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); - mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); - - if (!mNullAccessToken && mAccessToken == null) { - getCurrentAccountAndBindView(resources); - } else { - bindView(resources); - } - } - - return rootView; - } - - private void getCurrentAccountAndBindView(Resources resources) { - new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { - if (account == null) { - mNullAccessToken = true; - } else { - mAccessToken = account.getAccessToken(); - } - bindView(resources); - }).execute(); - } - - private void bindView(Resources resources) { - mLinearLayoutManager = new LinearLayoutManager(mActivity); - mCommentRecyclerView.setLayoutManager(mLinearLayoutManager); - - mAdapter = new CommentsListingRecyclerViewAdapter(mActivity, mOauthRetrofit, customThemeWrapper, - getResources().getConfiguration().locale, mSharedPreferences, - getArguments().getString(EXTRA_ACCESS_TOKEN), getArguments().getString(EXTRA_ACCOUNT_NAME), - () -> mCommentViewModel.retryLoadingMore()); - - String username = getArguments().getString(EXTRA_USERNAME); - String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_USER_COMMENT, SortType.Type.NEW.name()); - if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { - String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_USER_COMMENT, SortType.Time.ALL.name()); - sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase()), SortType.Time.valueOf(sortTime.toUpperCase())); - } else { - sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase())); - } - - mCommentRecyclerView.setAdapter(mAdapter); - - CommentViewModel.Factory factory; - - if (mAccessToken == null) { - factory = new CommentViewModel.Factory(mRetrofit, - resources.getConfiguration().locale, null, username, sortType, - getArguments().getBoolean(EXTRA_ARE_SAVED_COMMENTS)); - } else { - factory = new CommentViewModel.Factory(mOauthRetrofit, - resources.getConfiguration().locale, mAccessToken, username, sortType, - getArguments().getBoolean(EXTRA_ARE_SAVED_COMMENTS)); - } - - mCommentViewModel = new ViewModelProvider(this, factory).get(CommentViewModel.class); - mCommentViewModel.getComments().observe(getViewLifecycleOwner(), comments -> mAdapter.submitList(comments)); - - mCommentViewModel.hasComment().observe(getViewLifecycleOwner(), hasComment -> { - mSwipeRefreshLayout.setRefreshing(false); - if (hasComment) { - mFetchCommentInfoLinearLayout.setVisibility(View.GONE); - } else { - mFetchCommentInfoLinearLayout.setOnClickListener(view -> { - //Do nothing - }); - showErrorView(R.string.no_comments); - } - }); - - mCommentViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { - if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { - mSwipeRefreshLayout.setRefreshing(false); - } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchCommentInfoLinearLayout.setOnClickListener(view -> refresh()); - showErrorView(R.string.load_comments_failed); - } else { - mSwipeRefreshLayout.setRefreshing(true); - } - }); - - mCommentViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> mAdapter.setNetworkState(networkState)); - - mSwipeRefreshLayout.setOnRefreshListener(() -> mCommentViewModel.refresh()); - } - - public void changeSortType(SortType sortType) { - mCommentViewModel.changeSortType(sortType); - this.sortType = sortType; - } - - private void initializeSwipeActionDrawable() { - if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getDownvoted()); - drawableSwipeRight = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); - } else { - backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getUpvoted()); - drawableSwipeRight = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); - } - - if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getUpvoted()); - drawableSwipeLeft = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); - } else { - backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getDownvoted()); - drawableSwipeLeft = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.mActivity = (Activity) context; - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString(ACCESS_TOKEN_STATE, mAccessToken); - outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); - } - - @Override - public void refresh() { - mFetchCommentInfoLinearLayout.setVisibility(View.GONE); - mCommentViewModel.refresh(); - mAdapter.setNetworkState(null); - } - - @Override - public void applyTheme() { - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); - mFetchCommentInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); - } - - private void showErrorView(int stringResId) { - if (mActivity != null && isAdded()) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchCommentInfoLinearLayout.setVisibility(View.VISIBLE); - mFetchCommentInfoTextView.setText(stringResId); - mGlide.load(R.drawable.error_image).into(mFetchCommentInfoImageView); - } - } - - public void goBackToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } - - public SortType getSortType() { - return sortType; - } - - public void giveAward(String awardsHTML, int position) { - if (mAdapter != null) { - mAdapter.giveAward(awardsHTML, position); - } - } - - public void editComment(String commentMarkdown, int position) { - if (mAdapter != null) { - mAdapter.editComment(commentMarkdown, position); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/FollowedUsersListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/FollowedUsersListingFragment.java deleted file mode 100644 index 98b49d2e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/FollowedUsersListingFragment.java +++ /dev/null @@ -1,175 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.os.Build; -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 androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import me.zhanghai.android.fastscroll.FastScrollerBuilder; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Activity.SubscribedThingListingActivity; -import ml.docilealligator.infinityforreddit.Adapter.FollowedUsersRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserViewModel; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - - -/** - * A simple {@link Fragment} subclass. - */ -public class FollowedUsersListingFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - - @BindView(R.id.swipe_refresh_layout_followed_users_listing_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_followed_users_listing_fragment) - RecyclerView mRecyclerView; - @BindView(R.id.no_subscriptions_linear_layout_followed_users_listing_fragment) - LinearLayout mLinearLayout; - @BindView(R.id.no_subscriptions_image_view_followed_users_listing_fragment) - ImageView mImageView; - @BindView(R.id.error_text_view_followed_users_listing_fragment) - TextView mErrorTextView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - CustomThemeWrapper customThemeWrapper; - SubscribedUserViewModel mSubscribedUserViewModel; - private Activity mActivity; - private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; - - public FollowedUsersListingFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_followed_users_listing, container, false); - - ButterKnife.bind(this, rootView); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - applyTheme(); - - Resources resources = getResources(); - - if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { - mRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { - mRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); - } - } - - mGlide = Glide.with(this); - - mLinearLayoutManager = new LinearLayoutManager(mActivity); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - FollowedUsersRecyclerViewAdapter adapter = new FollowedUsersRecyclerViewAdapter(mActivity, - mOauthRetrofit, mRedditDataRoomDatabase, customThemeWrapper, - getArguments().getString(EXTRA_ACCESS_TOKEN)); - mRecyclerView.setAdapter(adapter); - new FastScrollerBuilder(mRecyclerView).build(); - - mSubscribedUserViewModel = new ViewModelProvider(this, - new SubscribedUserViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, getArguments().getString(EXTRA_ACCOUNT_NAME))) - .get(SubscribedUserViewModel.class); - - mSubscribedUserViewModel.getAllSubscribedUsers().observe(this, subscribedUserData -> { - mSwipeRefreshLayout.setRefreshing(false); - if (subscribedUserData == null || subscribedUserData.size() == 0) { - mRecyclerView.setVisibility(View.GONE); - mLinearLayout.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.error_image).into(mImageView); - } else { - mLinearLayout.setVisibility(View.GONE); - mRecyclerView.setVisibility(View.VISIBLE); - mGlide.clear(mImageView); - } - adapter.setSubscribedUsers(subscribedUserData); - }); - - mSubscribedUserViewModel.getAllFavoriteSubscribedUsers().observe(this, favoriteSubscribedUserData -> { - mSwipeRefreshLayout.setRefreshing(false); - if (favoriteSubscribedUserData != null && favoriteSubscribedUserData.size() > 0) { - mLinearLayout.setVisibility(View.GONE); - mRecyclerView.setVisibility(View.VISIBLE); - mGlide.clear(mImageView); - } - adapter.setFavoriteSubscribedUsers(favoriteSubscribedUserData); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mActivity = (Activity) context; - } - - @Override - public void stopRefreshProgressbar() { - mSwipeRefreshLayout.setRefreshing(false); - } - - @Override - public void applyTheme() { - if (mActivity instanceof SubscribedThingListingActivity) { - mSwipeRefreshLayout.setOnRefreshListener(() -> ((SubscribedThingListingActivity) mActivity).loadSubscriptions(true)); - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); - } else { - mSwipeRefreshLayout.setEnabled(false); - } - mErrorTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); - } - - public void goBackToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/InboxFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/InboxFragment.java deleted file mode 100644 index 56f4c2a0..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/InboxFragment.java +++ /dev/null @@ -1,197 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.content.Context; -import android.content.SharedPreferences; -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 androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.DividerItemDecoration; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; - -import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Adapter.MessageRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.RepliedToPrivateMessageEvent; -import ml.docilealligator.infinityforreddit.Message.FetchMessage; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Message.MessageViewModel; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import retrofit2.Retrofit; - -public class InboxFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_MESSAGE_WHERE = "EMT"; - @BindView(R.id.swipe_refresh_layout_inbox_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_inbox_fragment) - RecyclerView mRecyclerView; - @BindView(R.id.fetch_messages_info_linear_layout_inbox_fragment) - LinearLayout mFetchMessageInfoLinearLayout; - @BindView(R.id.fetch_messages_info_image_view_inbox_fragment) - ImageView mFetchMessageInfoImageView; - @BindView(R.id.fetch_messages_info_text_view_inbox_fragment) - TextView mFetchMessageInfoTextView; - MessageViewModel mMessageViewModel; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String mAccessToken; - private String mWhere; - private MessageRecyclerViewAdapter mAdapter; - private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; - private BaseActivity mActivity; - - public InboxFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_inbox, container, false); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - EventBus.getDefault().register(this); - - applyTheme(); - - Bundle arguments = getArguments(); - if (arguments == null) { - return rootView; - } - mAccessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); - mGlide = Glide.with(this); - - if (mActivity.isImmersiveInterface()) { - mRecyclerView.setPadding(0, 0, 0, mActivity.getNavBarHeight()); - } - - mWhere = arguments.getString(EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); - mAdapter = new MessageRecyclerViewAdapter(mActivity, mOauthRetrofit, mCustomThemeWrapper, - mAccessToken, mWhere, () -> mMessageViewModel.retryLoadingMore()); - mLinearLayoutManager = new LinearLayoutManager(mActivity); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - mRecyclerView.setAdapter(mAdapter); - DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mActivity, mLinearLayoutManager.getOrientation()); - mRecyclerView.addItemDecoration(dividerItemDecoration); - - MessageViewModel.Factory factory = new MessageViewModel.Factory(mOauthRetrofit, - getResources().getConfiguration().locale, mAccessToken, mWhere); - mMessageViewModel = new ViewModelProvider(this, factory).get(MessageViewModel.class); - mMessageViewModel.getMessages().observe(getViewLifecycleOwner(), messages -> mAdapter.submitList(messages)); - - mMessageViewModel.hasMessage().observe(getViewLifecycleOwner(), hasMessage -> { - mSwipeRefreshLayout.setRefreshing(false); - if (hasMessage) { - mFetchMessageInfoLinearLayout.setVisibility(View.GONE); - } else { - mFetchMessageInfoLinearLayout.setOnClickListener(null); - showErrorView(R.string.no_messages); - } - }); - - mMessageViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { - if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { - mSwipeRefreshLayout.setRefreshing(false); - } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchMessageInfoLinearLayout.setOnClickListener(view -> { - mFetchMessageInfoLinearLayout.setVisibility(View.GONE); - mMessageViewModel.refresh(); - mAdapter.setNetworkState(null); - }); - showErrorView(R.string.load_messages_failed); - } else { - mSwipeRefreshLayout.setRefreshing(true); - } - }); - - mMessageViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> { - mAdapter.setNetworkState(networkState); - }); - - mSwipeRefreshLayout.setOnRefreshListener(this::onRefresh); - - return rootView; - } - - private void showErrorView(int stringResId) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchMessageInfoLinearLayout.setVisibility(View.VISIBLE); - mFetchMessageInfoTextView.setText(stringResId); - mGlide.load(R.drawable.error_image).into(mFetchMessageInfoImageView); - } - - @Override - public void applyTheme() { - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); - mFetchMessageInfoTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); - } - - public void goBackToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } - - private void onRefresh() { - mMessageViewModel.refresh(); - mAdapter.setNetworkState(null); - } - - @Override - public void onDestroy() { - super.onDestroy(); - EventBus.getDefault().unregister(this); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mActivity = (BaseActivity) context; - } - - @Subscribe - public void onRepliedToPrivateMessageEvent(RepliedToPrivateMessageEvent repliedToPrivateMessageEvent) { - if (mAdapter != null && mWhere.equals(FetchMessage.WHERE_MESSAGES)) { - mAdapter.updateMessageReply(repliedToPrivateMessageEvent.newReply, repliedToPrivateMessageEvent.messagePosition); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/MultiRedditListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/MultiRedditListingFragment.java deleted file mode 100644 index 21bde76a..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/MultiRedditListingFragment.java +++ /dev/null @@ -1,181 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.os.Build; -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 androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import me.zhanghai.android.fastscroll.FastScrollerBuilder; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Activity.SubscribedThingListingActivity; -import ml.docilealligator.infinityforreddit.Adapter.MultiRedditListingRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiRedditViewModel; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - -public class MultiRedditListingFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - - @BindView(R.id.swipe_refresh_layout_multi_reddit_listing_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_multi_reddit_listing_fragment) - RecyclerView mRecyclerView; - @BindView(R.id.fetch_multi_reddit_listing_info_linear_layout_multi_reddit_listing_fragment) - LinearLayout mErrorLinearLayout; - @BindView(R.id.fetch_multi_reddit_listing_info_image_view_multi_reddit_listing_fragment) - ImageView mErrorImageView; - @BindView(R.id.fetch_multi_reddit_listing_info_text_view_multi_reddit_listing_fragment) - TextView mErrorTextView; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - - public MultiRedditViewModel mMultiRedditViewModel; - private SubscribedThingListingActivity mActivity; - private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; - - public MultiRedditListingFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_multi_reddit_listing, container, false); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - applyTheme(); - - if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { - mRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).getNavBarHeight()); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true)) { - Resources resources = getResources(); - int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); - if (navBarResourceId > 0) { - mRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); - } - } - - String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); - - mGlide = Glide.with(this); - - mLinearLayoutManager = new LinearLayoutManager(mActivity); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - MultiRedditListingRecyclerViewAdapter adapter = new MultiRedditListingRecyclerViewAdapter(mActivity, - mOauthRetrofit, mRedditDataRoomDatabase, mCustomThemeWrapper, accessToken, accountName); - mRecyclerView.setAdapter(adapter); - mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); - if (dy > 0) { - mActivity.fab.hide(); - } else { - mActivity.fab.show(); - } - } - }); - new FastScrollerBuilder(mRecyclerView).build(); - - mMultiRedditViewModel = new ViewModelProvider(this, - new MultiRedditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName)) - .get(MultiRedditViewModel.class); - - mMultiRedditViewModel.getAllMultiReddits().observe(getViewLifecycleOwner(), subscribedUserData -> { - if (subscribedUserData == null || subscribedUserData.size() == 0) { - mRecyclerView.setVisibility(View.GONE); - mErrorLinearLayout.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.error_image).into(mErrorImageView); - } else { - mErrorLinearLayout.setVisibility(View.GONE); - mRecyclerView.setVisibility(View.VISIBLE); - mGlide.clear(mErrorImageView); - } - adapter.setMultiReddits(subscribedUserData); - }); - - mMultiRedditViewModel.getAllFavoriteMultiReddits().observe(getViewLifecycleOwner(), favoriteSubscribedUserData -> { - if (favoriteSubscribedUserData != null && favoriteSubscribedUserData.size() > 0) { - mErrorLinearLayout.setVisibility(View.GONE); - mRecyclerView.setVisibility(View.VISIBLE); - mGlide.clear(mErrorImageView); - } - adapter.setFavoriteMultiReddits(favoriteSubscribedUserData); - }); - - return rootView; - } - - public void goBackToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mActivity = (SubscribedThingListingActivity) context; - } - - @Override - public void applyTheme() { - if (mActivity instanceof SubscribedThingListingActivity) { - mSwipeRefreshLayout.setOnRefreshListener(() -> ((SubscribedThingListingActivity) mActivity).loadSubscriptions(true)); - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); - } else { - mSwipeRefreshLayout.setEnabled(false); - } - - mErrorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); - } - - @Override - public void stopRefreshProgressbar() { - mSwipeRefreshLayout.setRefreshing(false); - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java deleted file mode 100644 index 482ebb21..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/PostFragment.java +++ /dev/null @@ -1,1457 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - - -import android.content.Context; -import android.content.Intent; -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.util.DisplayMetrics; -import android.view.HapticFeedbackConstants; -import android.view.KeyEvent; -import android.view.LayoutInflater; -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.appcompat.app.AppCompatActivity; -import androidx.coordinatorlayout.widget.CoordinatorLayout; -import androidx.core.content.res.ResourcesCompat; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.paging.PagedList; -import androidx.recyclerview.widget.ItemTouchHelper; -import androidx.recyclerview.widget.LinearLayoutManager; -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.Locale; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import im.ene.toro.exoplayer.ExoCreator; -import im.ene.toro.media.PlaybackInfo; -import im.ene.toro.media.VolumeInfo; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Activity.FilteredThingActivity; -import ml.docilealligator.infinityforreddit.Activity.MainActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; -import ml.docilealligator.infinityforreddit.Adapter.PostRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.CustomView.CustomToroContainer; -import ml.docilealligator.infinityforreddit.Event.ChangeAutoplayNsfwVideosEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeCompactLayoutToolbarHiddenByDefaultEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeDataSavingModeEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeDefaultPostLayoutEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeDisableImagePreviewEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeEnableSwipeActionSwitchEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeLongPressToHideToolbarInCompactLayoutEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeMuteAutoplayingVideosEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeMuteNSFWVideoEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWBlurEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeNetworkStatusEvent; -import ml.docilealligator.infinityforreddit.Event.ChangePostLayoutEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSavePostFeedScrolledPositionEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeShowAbsoluteNumberOfVotesEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeShowElapsedTimeEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSpoilerBlurEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeStartAutoplayVisibleAreaOffsetEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSwipeActionEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSwipeActionThresholdEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeTimeFormatEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeVibrateWhenActionTriggeredEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeVideoAutoplayEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeVoteButtonsPositionEvent; -import ml.docilealligator.infinityforreddit.Event.PostUpdateEventToPostList; -import ml.docilealligator.infinityforreddit.Event.ShowDividerInCompactLayoutPreferenceEvent; -import ml.docilealligator.infinityforreddit.Event.ShowThumbnailOnTheRightInCompactLayoutEvent; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Post.PostDataSource; -import ml.docilealligator.infinityforreddit.Post.PostViewModel; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SubredditFilter.FetchSubredditFilters; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Retrofit; - -import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; -import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; - - -/** - * A simple {@link Fragment} subclass. - */ -public class PostFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_NAME = "EN"; - public static final String EXTRA_USER_NAME = "EUN"; - public static final String EXTRA_USER_WHERE = "EUW"; - public static final String EXTRA_QUERY = "EQ"; - public static final String EXTRA_POST_TYPE = "EPT"; - public static final String EXTRA_FILTER = "EF"; - public static final int EXTRA_NO_FILTER = -2; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - - private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; - private static final String RECYCLER_VIEW_POSITION_STATE = "RVPS"; - private static final String SUBREDDIT_FILTER_LIST_STATE = "SFLS"; - - @BindView(R.id.swipe_refresh_layout_post_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_post_fragment) - CustomToroContainer mPostRecyclerView; - @BindView(R.id.fetch_post_info_linear_layout_post_fragment) - LinearLayout mFetchPostInfoLinearLayout; - @BindView(R.id.fetch_post_info_image_view_post_fragment) - ImageView mFetchPostInfoImageView; - @BindView(R.id.fetch_post_info_text_view_post_fragment) - TextView mFetchPostInfoTextView; - PostViewModel mPostViewModel; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("gfycat") - Retrofit mGfycatRetrofit; - @Inject - @Named("redgifs") - Retrofit mRedgifsRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences mNsfwAndSpoilerSharedPreferences; - @Inject - CustomThemeWrapper customThemeWrapper; - @Inject - ExoCreator exoCreator; - @Inject - @Named("post_feed_scrolled_position_cache") - SharedPreferences postFeedScrolledPositionSharedPreferences; - private RequestManager mGlide; - private AppCompatActivity activity; - private LinearLayoutManager mLinearLayoutManager; - private StaggeredGridLayoutManager mStaggeredGridLayoutManager; - private int postType; - private boolean isInLazyMode = false; - private boolean isLazyModePaused = false; - private boolean hasPost = false; - private boolean isShown = false; - private boolean savePostFeedScrolledPosition; - private PostRecyclerViewAdapter mAdapter; - private RecyclerView.SmoothScroller smoothScroller; - private Window window; - private Handler lazyModeHandler; - private LazyModeRunnable lazyModeRunnable; - private CountDownTimer resumeLazyModeCountDownTimer; - private float lazyModeInterval; - private String accountName; - private String subredditName; - private String username; - private String multiRedditPath; - private int maxPosition = -1; - private int postLayout; - private SortType sortType; - 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 subredditFilterList; - - public PostFragment() { - // Required empty public constructor - } - - @Override - public void onResume() { - super.onResume(); - isShown = true; - if (mPostRecyclerView.getAdapter() != null) { - ((PostRecyclerViewAdapter) mPostRecyclerView.getAdapter()).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; - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_post, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - EventBus.getDefault().register(this); - - applyTheme(); - - 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 instanceof BaseActivity && ((BaseActivity) 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)); - } - } - - DisplayMetrics displayMetrics = new DisplayMetrics(); - activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); - int windowWidth = displayMetrics.widthPixels; - - int nColumns; - if (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { - nColumns = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT, "1")); - } else { - nColumns = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE, "2")); - } - - if (nColumns == 1) { - mLinearLayoutManager = new LinearLayoutManager(activity); - mPostRecyclerView.setLayoutManager(mLinearLayoutManager); - } else { - mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); - mPostRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); - StaggeredGridLayoutManagerItemOffsetDecoration itemDecoration = - new StaggeredGridLayoutManagerItemOffsetDecoration(activity, R.dimen.staggeredLayoutManagerItemOffset); - mPostRecyclerView.addItemDecoration(itemDecoration); - windowWidth /= 2; - } - - mGlide = Glide.with(activity); - - lazyModeRunnable = new LazyModeRunnable() { - - @Override - public void run() { - if (isInLazyMode && !isLazyModePaused) { - 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); - - if (savedInstanceState != null) { - int recyclerViewPosition = savedInstanceState.getInt(RECYCLER_VIEW_POSITION_STATE); - if (recyclerViewPosition > 0) { - mPostRecyclerView.scrollToPosition(recyclerViewPosition); - } - - isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - subredditFilterList = savedInstanceState.getParcelableArrayList(SUBREDDIT_FILTER_LIST_STATE); - } - - mPostRecyclerView.setOnTouchListener((view, motionEvent) -> { - if (isInLazyMode) { - pauseLazyMode(true); - } - return false; - }); - - if (activity instanceof MainActivity) { - mPostRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (dy > 0) { - ((MainActivity) activity).postScrollDown(); - } else if (dy < 0) { - ((MainActivity) activity).postScrollUp(); - } - - } - }); - } else if (activity instanceof ViewSubredditDetailActivity) { - mPostRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (dy > 0) { - ((ViewSubredditDetailActivity) activity).contentScrollDown(); - } else if (dy < 0) { - ((ViewSubredditDetailActivity) activity).contentScrollUp(); - } - - } - }); - } - - postType = getArguments().getInt(EXTRA_POST_TYPE); - - int filter = getArguments().getInt(EXTRA_FILTER); - String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); - accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); - int defaultPostLayout = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.DEFAULT_POST_LAYOUT_KEY, "0")); - savePostFeedScrolledPosition = mSharedPreferences.getBoolean(SharedPreferencesUtils.SAVE_FRONT_PAGE_SCROLLED_POSITION, false); - Locale locale = getResources().getConfiguration().locale; - - if (postType == PostDataSource.TYPE_SEARCH) { - subredditName = getArguments().getString(EXTRA_NAME); - String query = getArguments().getString(EXTRA_QUERY); - - String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SEARCH_POST, SortType.Type.RELEVANCE.name()); - String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_SEARCH_POST, SortType.Time.ALL.name()); - sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); - postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST, defaultPostLayout); - - mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, - windowWidth, accessToken, accountName, postType, postLayout, true, - mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { - @Override - public void retryLoadingMore() { - mPostViewModel.retryLoadingMore(); - } - - @Override - public void typeChipClicked(int filter) { - Intent intent = new Intent(activity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, subredditName); - intent.putExtra(FilteredThingActivity.EXTRA_QUERY, query); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); - startActivity(intent); - } - - @Override - public void currentlyBindItem(int position) { - if (maxPosition < position) { - maxPosition = position; - } - } - - @Override - public void delayTransition() { - TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); - } - }); - - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw)).get(PostViewModel.class); - } else if (postType == PostDataSource.TYPE_SUBREDDIT) { - subredditName = getArguments().getString(EXTRA_NAME); - String sort; - String sortTime = null; - - sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SUBREDDIT_POST_BASE + subredditName, SortType.Type.HOT.name()); - if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { - sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_SUBREDDIT_POST_BASE + subredditName, SortType.Time.ALL.name()); - } - boolean displaySubredditName = subredditName != null && (subredditName.equals("popular") || subredditName.equals("all")); - postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + subredditName, defaultPostLayout); - - if(sortTime != null) { - sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); - } else { - sortType = new SortType(SortType.Type.valueOf(sort)); - } - - mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, - windowWidth, accessToken, accountName, postType, postLayout, displaySubredditName, - mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { - @Override - public void retryLoadingMore() { - mPostViewModel.retryLoadingMore(); - } - - @Override - public void typeChipClicked(int filter) { - Intent intent = new Intent(activity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, subredditName); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); - startActivity(intent); - } - - @Override - public void currentlyBindItem(int position) { - if (maxPosition < position) { - maxPosition = position; - } - } - - @Override - public void delayTransition() { - TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); - } - }); - - if (subredditName.equals("all") || subredditName.equals("popular")) { - if (subredditFilterList != null) { - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList)).get(PostViewModel.class); - } else { - FetchSubredditFilters.fetchSubredditFilters(mRedditDataRoomDatabase, subredditFilters -> { - if (activity != null) { - subredditFilterList = subredditFilters; - mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilters)).get(PostViewModel.class); - - bindPostViewModel(); - } - }); - } - } else { - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw)).get(PostViewModel.class); - } - } else if(postType == PostDataSource.TYPE_MULTI_REDDIT) { - multiRedditPath = getArguments().getString(EXTRA_NAME); - String sort; - String sortTime = null; - - sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_MULTI_REDDIT_POST_BASE + multiRedditPath, - SortType.Type.HOT.name()); - if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { - sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_MULTI_REDDIT_POST_BASE + multiRedditPath, - SortType.Time.ALL.name()); - } - postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + multiRedditPath, - defaultPostLayout); - - if(sortTime != null) { - sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); - } else { - sortType = new SortType(SortType.Type.valueOf(sort)); - } - - mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, - windowWidth, accessToken, accountName, postType, postLayout, true, - mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { - @Override - public void retryLoadingMore() { - mPostViewModel.retryLoadingMore(); - } - - @Override - public void typeChipClicked(int filter) { - Intent intent = new Intent(activity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, multiRedditPath); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); - startActivity(intent); - } - - @Override - public void currentlyBindItem(int position) { - if (maxPosition < position) { - maxPosition = position; - } - } - - @Override - public void delayTransition() { - TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); - } - }); - - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, - postFeedScrolledPositionSharedPreferences, multiRedditPath, postType, sortType, filter, nsfw)).get(PostViewModel.class); - } else if (postType == PostDataSource.TYPE_USER) { - username = getArguments().getString(EXTRA_USER_NAME); - String where = getArguments().getString(EXTRA_USER_WHERE); - if (where != null && where.equals(PostDataSource.USER_WHERE_SUBMITTED)) { - CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mFetchPostInfoLinearLayout.getLayoutParams(); - params.height = ViewGroup.LayoutParams.WRAP_CONTENT; - mFetchPostInfoLinearLayout.setLayoutParams(params); - } - - String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_USER_POST_BASE + username, SortType.Type.NEW.name()); - if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { - String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_USER_POST_BASE + username, SortType.Time.ALL.name()); - sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); - } else { - sortType = new SortType(SortType.Type.valueOf(sort)); - } - postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + username, defaultPostLayout); - - mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, - windowWidth, accessToken, accountName, postType, postLayout, true, - mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { - @Override - public void retryLoadingMore() { - mPostViewModel.retryLoadingMore(); - } - - @Override - public void typeChipClicked(int filter) { - Intent intent = new Intent(activity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, username); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); - intent.putExtra(FilteredThingActivity.EXTRA_USER_WHERE, where); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); - startActivity(intent); - } - - @Override - public void currentlyBindItem(int position) { - if (maxPosition < position) { - maxPosition = position; - } - } - - @Override - public void delayTransition() { - TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); - } - }); - - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, - postFeedScrolledPositionSharedPreferences, username, postType, sortType, where, filter, nsfw)).get(PostViewModel.class); - } else { - String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_BEST_POST, SortType.Type.BEST.name()); - if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { - String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_BEST_POST, SortType.Time.ALL.name()); - sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); - } else { - sortType = new SortType(SortType.Type.valueOf(sort)); - } - postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, defaultPostLayout); - - mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, - mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, - windowWidth, accessToken, accountName, postType, postLayout, true, - mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { - @Override - public void retryLoadingMore() { - mPostViewModel.retryLoadingMore(); - } - - @Override - public void typeChipClicked(int filter) { - Intent intent = new Intent(activity, FilteredThingActivity.class); - intent.putExtra(FilteredThingActivity.EXTRA_NAME, activity.getString(R.string.best)); - intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); - intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); - startActivity(intent); - } - - @Override - public void currentlyBindItem(int position) { - if (maxPosition < position) { - maxPosition = position; - } - } - - @Override - public void delayTransition() { - TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); - } - }); - - mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(mOauthRetrofit, accessToken, - accountName, getResources().getConfiguration().locale, mSharedPreferences, postFeedScrolledPositionSharedPreferences, - postType, sortType, filter, nsfw)).get(PostViewModel.class); - } - - if (activity instanceof ActivityToolbarInterface) { - ((ActivityToolbarInterface) activity).displaySortType(); - } - - vibrateWhenActionTriggered = mSharedPreferences.getBoolean(SharedPreferencesUtils.VIBRATE_WHEN_ACTION_TRIGGERED, true); - swipeActionThreshold = Float.parseFloat(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_ACTION_THRESHOLD, "0.3")); - swipeRightAction = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_RIGHT_ACTION, "1")); - swipeLeftAction = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_LEFT_ACTION, "0")); - initializeSwipeActionDrawable(); - - touchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { - boolean exceedThreshold = false; - - @Override - public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { - if (!(viewHolder instanceof PostRecyclerViewAdapter.PostBaseViewHolder) && - !(viewHolder instanceof PostRecyclerViewAdapter.PostCompactBaseViewHolder)) { - return makeMovementFlags(0, 0); - } - int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; - return makeMovementFlags(0, swipeFlags); - } - - @Override - public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { - return false; - } - - @Override - public boolean isItemViewSwipeEnabled() { - return true; - } - - @Override - public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { - if (touchHelper != null) { - touchHelper.attachToRecyclerView(null); - touchHelper.attachToRecyclerView(mPostRecyclerView); - if (mAdapter != null) { - mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); - } - } - } - - @Override - public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { - super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); - - View itemView = viewHolder.itemView; - int horizontalOffset = (int) Utils.convertDpToPixel(16, activity); - if (dX > 0) { - if (dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { - if (!exceedThreshold) { - exceedThreshold = true; - if (vibrateWhenActionTriggered) { - viewHolder.itemView.setHapticFeedbackEnabled(true); - viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } - backgroundSwipeRight.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); - } else { - exceedThreshold = false; - backgroundSwipeRight.setBounds(0, 0, 0, 0); - } - - drawableSwipeRight.setBounds(itemView.getLeft() + ((int) dX) - horizontalOffset - drawableSwipeRight.getIntrinsicWidth(), - (itemView.getBottom() + itemView.getTop() - drawableSwipeRight.getIntrinsicHeight()) / 2, - itemView.getLeft() + ((int) dX) - horizontalOffset, - (itemView.getBottom() + itemView.getTop() + drawableSwipeRight.getIntrinsicHeight()) / 2); - backgroundSwipeRight.draw(c); - drawableSwipeRight.draw(c); - } else if (dX < 0) { - if (-dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { - if (!exceedThreshold) { - exceedThreshold = true; - if (vibrateWhenActionTriggered) { - viewHolder.itemView.setHapticFeedbackEnabled(true); - viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); - } - } - backgroundSwipeLeft.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); - } else { - exceedThreshold = false; - backgroundSwipeLeft.setBounds(0, 0, 0, 0); - } - drawableSwipeLeft.setBounds(itemView.getRight() + ((int) dX) + horizontalOffset, - (itemView.getBottom() + itemView.getTop() - drawableSwipeLeft.getIntrinsicHeight()) / 2, - itemView.getRight() + ((int) dX) + horizontalOffset + drawableSwipeLeft.getIntrinsicWidth(), - (itemView.getBottom() + itemView.getTop() + drawableSwipeLeft.getIntrinsicHeight()) / 2); - backgroundSwipeLeft.draw(c); - drawableSwipeLeft.draw(c); - } - } - - @Override - public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { - return swipeActionThreshold; - } - }); - - if (nColumns == 1 && mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false)) { - touchHelper.attachToRecyclerView(mPostRecyclerView); - } - mPostRecyclerView.setAdapter(mAdapter); - mPostRecyclerView.setCacheManager(mAdapter); - mPostRecyclerView.setPlayerInitializer(order -> { - VolumeInfo volumeInfo = new VolumeInfo(true, 0f); - return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo); - }); - - if (mPostViewModel != null) { - bindPostViewModel(); - } - - return rootView; - } - - private void bindPostViewModel() { - mPostViewModel.getPosts().observe(getViewLifecycleOwner(), posts -> mAdapter.submitList(posts)); - - mPostViewModel.hasPost().observe(getViewLifecycleOwner(), hasPost -> { - this.hasPost = hasPost; - mSwipeRefreshLayout.setRefreshing(false); - if (hasPost) { - mFetchPostInfoLinearLayout.setVisibility(View.GONE); - } else { - if (isInLazyMode) { - stopLazyMode(); - } - - mFetchPostInfoLinearLayout.setOnClickListener(view -> { - }); - showErrorView(R.string.no_posts); - } - }); - - mPostViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { - if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { - mSwipeRefreshLayout.setRefreshing(false); - } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchPostInfoLinearLayout.setOnClickListener(view -> refresh()); - showErrorView(R.string.load_posts_error); - } else { - mSwipeRefreshLayout.setRefreshing(true); - } - }); - - mPostViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> mAdapter.setNetworkState(networkState)); - } - - public void changeSortType(SortType sortType) { - switch (postType) { - case PostDataSource.TYPE_FRONT_PAGE: - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_BEST_POST, sortType.getType().name()).apply(); - if (sortType.getTime() != null) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_BEST_POST, sortType.getTime().name()).apply(); - } - break; - case PostDataSource.TYPE_SUBREDDIT: - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SUBREDDIT_POST_BASE + subredditName, sortType.getType().name()).apply(); - if (sortType.getTime() != null) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_SUBREDDIT_POST_BASE + subredditName, sortType.getTime().name()).apply(); - } - break; - case PostDataSource.TYPE_USER: - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_USER_POST_BASE + username, sortType.getType().name()).apply(); - if(sortType.getTime() != null) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_USER_POST_BASE + username, sortType.getTime().name()).apply(); - } - break; - case PostDataSource.TYPE_SEARCH: - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SEARCH_POST, sortType.getType().name()).apply(); - if(sortType.getTime() != null) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_SEARCH_POST, sortType.getTime().name()).apply(); - } - break; - case PostDataSource.TYPE_MULTI_REDDIT: - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_MULTI_REDDIT_POST_BASE + multiRedditPath, - sortType.getType().name()).apply(); - if (sortType.getTime() != null) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_MULTI_REDDIT_POST_BASE + multiRedditPath, - sortType.getTime().name()).apply(); - } - break; - } - if (mFetchPostInfoLinearLayout.getVisibility() != View.GONE) { - mFetchPostInfoLinearLayout.setVisibility(View.GONE); - mGlide.clear(mFetchPostInfoImageView); - } - mAdapter.removeFooter(); - hasPost = false; - if (isInLazyMode) { - stopLazyMode(); - } - this.sortType = sortType; - mPostViewModel.changeSortType(sortType); - } - - private void initializeSwipeActionDrawable() { - if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { - backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getDownvoted()); - drawableSwipeRight = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); - } else { - backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getUpvoted()); - drawableSwipeRight = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); - } - - if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { - backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getUpvoted()); - drawableSwipeLeft = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); - } else { - backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getDownvoted()); - drawableSwipeLeft = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (AppCompatActivity) context; - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putParcelableArrayList(SUBREDDIT_FILTER_LIST_STATE, subredditFilterList); - if (mLinearLayoutManager != null) { - outState.putInt(RECYCLER_VIEW_POSITION_STATE, mLinearLayoutManager.findFirstVisibleItemPosition()); - } else if (mStaggeredGridLayoutManager != null) { - int[] into = new int[2]; - outState.putInt(RECYCLER_VIEW_POSITION_STATE, - mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0]); - } - } - - @Override - public void onStop() { - super.onStop(); - saveCache(); - } - - private void saveCache() { - if (savePostFeedScrolledPosition && postType == PostDataSource.TYPE_FRONT_PAGE && sortType != null && sortType.getType() == SortType.Type.BEST && mAdapter != null) { - Post currentPost = mAdapter.getItemByPosition(maxPosition); - if (currentPost != null) { - String accountNameForCache = accountName == null ? SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_ANONYMOUS : accountName; - String key = accountNameForCache + SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_FRONT_PAGE_BASE; - String value = currentPost.getFullName(); - postFeedScrolledPositionSharedPreferences.edit().putString(key, value).apply(); - } - } - } - - @Override - public void refresh() { - mAdapter.removeFooter(); - mFetchPostInfoLinearLayout.setVisibility(View.GONE); - hasPost = false; - if (isInLazyMode) { - stopLazyMode(); - } - saveCache(); - mPostViewModel.refresh(); - } - - 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 void changeNSFW(boolean nsfw) { - mPostViewModel.changeNSFW(nsfw); - } - - @Override - public boolean startLazyMode() { - if (!hasPost) { - Toast.makeText(activity, R.string.no_posts_no_lazy_mode, Toast.LENGTH_SHORT).show(); - return false; - } - - 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() { - 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) { - switch (postType) { - case PostDataSource.TYPE_FRONT_PAGE: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, postLayout).apply(); - break; - case PostDataSource.TYPE_SUBREDDIT: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + subredditName, postLayout).apply(); - break; - case PostDataSource.TYPE_USER: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + username, postLayout).apply(); - break; - case PostDataSource.TYPE_SEARCH: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST, postLayout).apply(); - break; - case PostDataSource.TYPE_MULTI_REDDIT: - mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + multiRedditPath, postLayout).apply(); - break; - } - - if (mAdapter != null) { - mAdapter.setPostLayout(postLayout); - refreshAdapter(); - } - } - - @Override - public void applyTheme() { - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); - mFetchPostInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); - } - - @Subscribe - public void onPostUpdateEvent(PostUpdateEventToPostList event) { - PagedList posts = mAdapter.getCurrentList(); - if (posts != null && 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.setScore(event.post.getScore()); - post.setNSFW(event.post.isNSFW()); - post.setHidden(event.post.isHidden()); - post.setSpoiler(event.post.isSpoiler()); - post.setFlair(event.post.getFlair()); - post.setSaved(event.post.isSaved()); - 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.setBlurNSFW(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 PostDataSource.TYPE_SUBREDDIT: - if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + bundle.getString(EXTRA_NAME))) { - changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); - } - break; - case PostDataSource.TYPE_USER: - if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + bundle.getString(EXTRA_USER_NAME))) { - changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); - } - break; - case PostDataSource.TYPE_MULTI_REDDIT: - if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + bundle.getString(EXTRA_NAME))) { - changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); - } - break; - case PostDataSource.TYPE_SEARCH: - if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST)) { - changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); - } - break; - case PostDataSource.TYPE_FRONT_PAGE: - if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST)) { - changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); - } - break; - } - } - } - - @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 onChangeSavePostFeedScrolledPositionEvent(ChangeSavePostFeedScrolledPositionEvent changeSavePostFeedScrolledPositionEvent) { - savePostFeedScrolledPosition = changeSavePostFeedScrolledPositionEvent.savePostFeedScrolledPosition; - } - - @Subscribe - public void onChangeVibrateWhenActionTriggeredEvent(ChangeVibrateWhenActionTriggeredEvent changeVibrateWhenActionTriggeredEvent) { - vibrateWhenActionTriggered = changeVibrateWhenActionTriggeredEvent.vibrateWhenActionTriggered; - } - - @Subscribe - public void onChangeEnableSwipeActionSwitchEvent(ChangeEnableSwipeActionSwitchEvent changeEnableSwipeActionSwitchEvent) { - if (touchHelper != null) { - 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 onChangeSwipeActionEvent(ChangeSwipeActionEvent changeSwipeActionEvent) { - swipeRightAction = changeSwipeActionEvent.swipeRightAction == -1 ? swipeRightAction : changeSwipeActionEvent.swipeRightAction; - swipeLeftAction = changeSwipeActionEvent.swipeLeftAction == -1 ? swipeLeftAction : changeSwipeActionEvent.swipeLeftAction; - initializeSwipeActionDrawable(); - } - - private void refreshAdapter() { - int previousPosition = -1; - if (mLinearLayoutManager != null) { - previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); - } else if (mStaggeredGridLayoutManager != null) { - int[] into = new int[2]; - 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(); - } - } - } - - public SortType getSortType() { - return sortType; - } - - public int getPostType() { - return postType; - } - - @Override - public void onPause() { - super.onPause(); - if (isInLazyMode) { - pauseLazyMode(false); - } - if (mAdapter != null && mPostRecyclerView != null) { - mPostRecyclerView.onWindowVisibilityChanged(View.GONE); - } - } - - @Override - public void onDestroy() { - EventBus.getDefault().unregister(this); - super.onDestroy(); - } - - 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; - - StaggeredGridLayoutManagerItemOffsetDecoration(int itemOffset) { - mItemOffset = itemOffset; - } - - StaggeredGridLayoutManagerItemOffsetDecoration(@NonNull Context context, @DimenRes int itemOffsetId) { - this(context.getResources().getDimensionPixelSize(itemOffsetId)); - } - - @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 (spanIndex == 0) { - outRect.set(0, 0, halfOffset, 0); - } else { - outRect.set(halfOffset, 0, 0, 0); - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SidebarFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SidebarFragment.java deleted file mode 100644 index bc45fa84..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SidebarFragment.java +++ /dev/null @@ -1,201 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.text.Spanned; -import android.text.style.SuperscriptSpan; -import android.text.util.Linkify; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import org.commonmark.ext.gfm.tables.TableBlock; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import io.noties.markwon.AbstractMarkwonPlugin; -import io.noties.markwon.Markwon; -import io.noties.markwon.MarkwonConfiguration; -import io.noties.markwon.core.MarkwonTheme; -import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; -import io.noties.markwon.linkify.LinkifyPlugin; -import io.noties.markwon.recycler.MarkwonAdapter; -import io.noties.markwon.recycler.table.TableEntry; -import io.noties.markwon.recycler.table.TableEntryPlugin; -import io.noties.markwon.simple.ext.SimpleExtPlugin; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertSubredditDataAsyncTask; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Subreddit.FetchSubredditData; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditViewModel; -import retrofit2.Retrofit; - -public class SidebarFragment extends Fragment { - - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - @BindView(R.id.swipe_refresh_layout_sidebar_fragment) - SwipeRefreshLayout swipeRefreshLayout; - @BindView(R.id.markdown_recycler_view_sidebar_fragment) - RecyclerView recyclerView; - private Activity activity; - private String subredditName; - public SubredditViewModel mSubredditViewModel; - private LinearLayoutManager linearLayoutManager; - private int markdownColor; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - - public SidebarFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_sidebar, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); - if (subredditName == null) { - Toast.makeText(activity, R.string.error_getting_subreddit_name, Toast.LENGTH_SHORT).show(); - return rootView; - } - - swipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); - swipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); - markdownColor = mCustomThemeWrapper.getSecondaryTextColor(); - - Markwon markwon = Markwon.builder(activity) - .usePlugin(new AbstractMarkwonPlugin() { - @Override - public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { - textView.setTextColor(markdownColor); - } - - @Override - public void configureTheme(@NonNull MarkwonTheme.Builder builder) { - builder.linkColor(mCustomThemeWrapper.getLinkColor()); - } - - @Override - public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { - builder.linkResolver((view, link) -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - Uri uri = Uri.parse(link); - if (uri.getScheme() == null && uri.getHost() == null) { - intent.setData(LinkResolverActivity.getRedditUriByPath(link)); - } else { - intent.setData(uri); - } - startActivity(intent); - }); - } - }) - .usePlugin(StrikethroughPlugin.create()) - .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) - .usePlugin(SimpleExtPlugin.create(plugin -> - plugin.addExtension(1, '^', (configuration, props) -> { - return new SuperscriptSpan(); - }) - ) - ) - .usePlugin(TableEntryPlugin.create(activity)) - .build(); - MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) - .include(TableBlock.class, TableEntry.create(builder -> builder - .tableLayout(R.layout.adapter_table_block, R.id.table_layout) - .textLayoutIsRoot(R.layout.view_table_entry_cell))) - .build(); - - linearLayoutManager = new LinearLayoutManager(activity); - recyclerView.setLayoutManager(linearLayoutManager); - recyclerView.setAdapter(markwonAdapter); - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (dy > 0) { - ((ViewSubredditDetailActivity) activity).contentScrollDown(); - } else if (dy < 0) { - ((ViewSubredditDetailActivity) activity).contentScrollUp(); - } - - } - }); - - mSubredditViewModel = new ViewModelProvider(this, - new SubredditViewModel.Factory(activity.getApplication(), mRedditDataRoomDatabase, subredditName)) - .get(SubredditViewModel.class); - mSubredditViewModel.getSubredditLiveData().observe(getViewLifecycleOwner(), subredditData -> { - if (subredditData != null) { - if (subredditData.getSidebarDescription() != null && !subredditData.getSidebarDescription().equals("")) { - markwonAdapter.setMarkdown(markwon, subredditData.getSidebarDescription()); - markwonAdapter.notifyDataSetChanged(); - } - } else { - fetchSubredditData(); - } - }); - - swipeRefreshLayout.setOnRefreshListener(this::fetchSubredditData); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } - - public void fetchSubredditData() { - swipeRefreshLayout.setRefreshing(true); - FetchSubredditData.fetchSubredditData(mRetrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { - @Override - public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { - swipeRefreshLayout.setRefreshing(false); - new InsertSubredditDataAsyncTask(mRedditDataRoomDatabase, subredditData, () -> swipeRefreshLayout.setRefreshing(false)).execute(); - } - - @Override - public void onFetchSubredditDataFail() { - swipeRefreshLayout.setRefreshing(false); - Toast.makeText(activity, R.string.cannot_fetch_sidebar, Toast.LENGTH_SHORT).show(); - } - }); - } - - public void goBackToTop() { - if (linearLayoutManager != null) { - linearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubredditListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubredditListingFragment.java deleted file mode 100644 index 61bff945..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubredditListingFragment.java +++ /dev/null @@ -1,239 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.os.Build; -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.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Activity.SearchSubredditsResultActivity; -import ml.docilealligator.infinityforreddit.Activity.ViewSubredditDetailActivity; -import ml.docilealligator.infinityforreddit.Adapter.SubredditListingRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditListingViewModel; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - - -/** - * A simple {@link Fragment} subclass. - */ -public class SubredditListingFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_QUERY = "EQ"; - public static final String EXTRA_IS_POSTING = "EIP"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - - @BindView(R.id.coordinator_layout_subreddit_listing_fragment) - CoordinatorLayout mCoordinatorLayout; - @BindView(R.id.recycler_view_subreddit_listing_fragment) - RecyclerView mSubredditListingRecyclerView; - @BindView(R.id.swipe_refresh_layout_subreddit_listing_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.fetch_subreddit_listing_info_linear_layout_subreddit_listing_fragment) - LinearLayout mFetchSubredditListingInfoLinearLayout; - @BindView(R.id.fetch_subreddit_listing_info_image_view_subreddit_listing_fragment) - ImageView mFetchSubredditListingInfoImageView; - @BindView(R.id.fetch_subreddit_listing_info_text_view_subreddit_listing_fragment) - TextView mFetchSubredditListingInfoTextView; - SubredditListingViewModel mSubredditListingViewModel; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences mNsfwAndSpoilerSharedPreferences; - @Inject - CustomThemeWrapper customThemeWrapper; - private LinearLayoutManager mLinearLayoutManager; - private SubredditListingRecyclerViewAdapter mAdapter; - private Activity mActivity; - private SortType sortType; - - public SubredditListingFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_subreddit_listing, container, false); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - applyTheme(); - - Resources resources = getResources(); - - if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { - mSubredditListingRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { - mSubredditListingRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); - } - } - - mLinearLayoutManager = new LinearLayoutManager(getActivity()); - mSubredditListingRecyclerView.setLayoutManager(mLinearLayoutManager); - - String query = getArguments().getString(EXTRA_QUERY); - boolean isPosting = getArguments().getBoolean(EXTRA_IS_POSTING); - String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); - String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - - String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SEARCH_SUBREDDIT, SortType.Type.RELEVANCE.value); - sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase())); - boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); - - mAdapter = new SubredditListingRecyclerViewAdapter(mActivity, mOauthRetrofit, mRetrofit, - customThemeWrapper, accessToken, accountName, mRedditDataRoomDatabase, - new SubredditListingRecyclerViewAdapter.Callback() { - @Override - public void retryLoadingMore() { - mSubredditListingViewModel.retryLoadingMore(); - } - - @Override - public void subredditSelected(String subredditName, String iconUrl) { - if (isPosting) { - ((SearchSubredditsResultActivity) mActivity).getSelectedSubreddit(subredditName, iconUrl); - } else { - Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); - intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); - mActivity.startActivity(intent); - } - } - }); - - mSubredditListingRecyclerView.setAdapter(mAdapter); - - SubredditListingViewModel.Factory factory = new SubredditListingViewModel.Factory( - accessToken == null ? mRetrofit : mOauthRetrofit, query, sortType, accessToken, nsfw); - mSubredditListingViewModel = new ViewModelProvider(this, factory).get(SubredditListingViewModel.class); - mSubredditListingViewModel.getSubreddits().observe(getViewLifecycleOwner(), subredditData -> mAdapter.submitList(subredditData)); - - mSubredditListingViewModel.hasSubredditLiveData().observe(getViewLifecycleOwner(), hasSubreddit -> { - mSwipeRefreshLayout.setRefreshing(false); - if (hasSubreddit) { - mFetchSubredditListingInfoLinearLayout.setVisibility(View.GONE); - } else { - mFetchSubredditListingInfoLinearLayout.setOnClickListener(null); - showErrorView(R.string.no_subreddits); - } - }); - - mSubredditListingViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { - if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { - mSwipeRefreshLayout.setRefreshing(false); - } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchSubredditListingInfoLinearLayout.setOnClickListener(view -> refresh()); - showErrorView(R.string.search_subreddits_error); - } else { - mSwipeRefreshLayout.setRefreshing(true); - } - }); - - mSubredditListingViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> { - mAdapter.setNetworkState(networkState); - }); - - mSwipeRefreshLayout.setOnRefreshListener(() -> mSubredditListingViewModel.refresh()); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mActivity = (Activity) context; - } - - private void showErrorView(int stringResId) { - if (getActivity() != null && isAdded()) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchSubredditListingInfoLinearLayout.setVisibility(View.VISIBLE); - mFetchSubredditListingInfoTextView.setText(stringResId); - Glide.with(this).load(R.drawable.error_image).into(mFetchSubredditListingInfoImageView); - } - } - - public void changeSortType(SortType sortType) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SEARCH_SUBREDDIT, sortType.getType().name()).apply(); - mSubredditListingViewModel.changeSortType(sortType); - this.sortType = sortType; - } - - @Override - public void refresh() { - mFetchSubredditListingInfoLinearLayout.setVisibility(View.GONE); - mSubredditListingViewModel.refresh(); - mAdapter.setNetworkState(null); - } - - @Override - public void applyTheme() { - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); - mFetchSubredditListingInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); - } - - public void goBackToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } - - public SortType getSortType() { - return sortType; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubscribedSubredditsListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubscribedSubredditsListingFragment.java deleted file mode 100644 index 63d6aade..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/SubscribedSubredditsListingFragment.java +++ /dev/null @@ -1,191 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.os.Build; -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 androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import me.zhanghai.android.fastscroll.FastScrollerBuilder; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Activity.SubredditSelectionActivity; -import ml.docilealligator.infinityforreddit.Activity.SubscribedThingListingActivity; -import ml.docilealligator.infinityforreddit.Adapter.SubscribedSubredditsRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditViewModel; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - - -/** - * A simple {@link Fragment} subclass. - */ -public class SubscribedSubredditsListingFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_ACCOUNT_PROFILE_IMAGE_URL = "EAPIU"; - public static final String EXTRA_IS_SUBREDDIT_SELECTION = "EISS"; - public static final String EXTRA_EXTRA_CLEAR_SELECTION = "EECS"; - - @BindView(R.id.swipe_refresh_layout_subscribed_subreddits_listing_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.recycler_view_subscribed_subreddits_listing_fragment) - RecyclerView mRecyclerView; - @BindView(R.id.no_subscriptions_linear_layout_subreddits_listing_fragment) - LinearLayout mLinearLayout; - @BindView(R.id.no_subscriptions_image_view_subreddits_listing_fragment) - ImageView mImageView; - @BindView(R.id.error_text_view_subscribed_subreddits_listing_fragment) - TextView mErrorTextView; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - CustomThemeWrapper customThemeWrapper; - public SubscribedSubredditViewModel mSubscribedSubredditViewModel; - private Activity mActivity; - private RequestManager mGlide; - private LinearLayoutManager mLinearLayoutManager; - - public SubscribedSubredditsListingFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_subscribed_subreddits_listing, container, false); - - ButterKnife.bind(this, rootView); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - applyTheme(); - - if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { - mRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).getNavBarHeight()); - } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O - && mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true)) { - Resources resources = getResources(); - int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); - if (navBarResourceId > 0) { - mRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); - } - } - - String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); - - mGlide = Glide.with(this); - - mLinearLayoutManager = new LinearLayoutManager(mActivity); - mRecyclerView.setLayoutManager(mLinearLayoutManager); - - SubscribedSubredditsRecyclerViewAdapter adapter; - if (getArguments().getBoolean(EXTRA_IS_SUBREDDIT_SELECTION)) { - adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity, mOauthRetrofit, mRedditDataRoomDatabase, - customThemeWrapper, accessToken, getArguments().getBoolean(EXTRA_EXTRA_CLEAR_SELECTION), - (name, iconUrl, subredditIsUser) -> ((SubredditSelectionActivity) mActivity).getSelectedSubreddit(name, iconUrl, subredditIsUser)); - } else { - adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity, mOauthRetrofit, mRedditDataRoomDatabase, - customThemeWrapper, accessToken); - } - - mRecyclerView.setAdapter(adapter); - new FastScrollerBuilder(mRecyclerView).build(); - - mSubscribedSubredditViewModel = new ViewModelProvider(this, - new SubscribedSubredditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName)) - .get(SubscribedSubredditViewModel.class); - mSubscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, subscribedSubredditData -> { - mSwipeRefreshLayout.setRefreshing(false); - if (subscribedSubredditData == null || subscribedSubredditData.size() == 0) { - mRecyclerView.setVisibility(View.GONE); - mLinearLayout.setVisibility(View.VISIBLE); - mGlide.load(R.drawable.error_image).into(mImageView); - } else { - mLinearLayout.setVisibility(View.GONE); - mRecyclerView.setVisibility(View.VISIBLE); - mGlide.clear(mImageView); - } - - adapter.addUser(accountName, getArguments().getString(EXTRA_ACCOUNT_PROFILE_IMAGE_URL)); - adapter.setSubscribedSubreddits(subscribedSubredditData); - }); - - mSubscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, favoriteSubscribedSubredditData -> { - mSwipeRefreshLayout.setRefreshing(false); - if (favoriteSubscribedSubredditData != null && favoriteSubscribedSubredditData.size() > 0) { - mLinearLayout.setVisibility(View.GONE); - mRecyclerView.setVisibility(View.VISIBLE); - mGlide.clear(mImageView); - } - - adapter.setFavoriteSubscribedSubreddits(favoriteSubscribedSubredditData); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mActivity = (Activity) context; - } - - @Override - public void stopRefreshProgressbar() { - mSwipeRefreshLayout.setRefreshing(false); - } - - @Override - public void applyTheme() { - if (mActivity instanceof SubscribedThingListingActivity) { - mSwipeRefreshLayout.setOnRefreshListener(() -> ((SubscribedThingListingActivity) mActivity).loadSubscriptions(true)); - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); - } else { - mSwipeRefreshLayout.setEnabled(false); - } - mErrorTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); - } - - public void goBackToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewCommentsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewCommentsFragment.java deleted file mode 100644 index 64903859..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewCommentsFragment.java +++ /dev/null @@ -1,154 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.content.Context; -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 ml.docilealligator.infinityforreddit.Activity.CustomThemePreviewActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.R; - -/** - * 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 CustomThemePreviewActivity activity; - - public ThemePreviewCommentsFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_theme_preview_comments, container, false); - ButterKnife.bind(this, rootView); - - 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); - - linearLayoutFullyCollapsed.setBackgroundColor(customTheme.fullyCollapsedCommentBackgroundColor); - authorTextViewFullyCollapsed.setTextColor(customTheme.username); - scoreTextViewFullyCollapsed.setTextColor(customTheme.secondaryTextColor); - timeTextViewFullyCollapsed.setTextColor(customTheme.secondaryTextColor); - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (CustomThemePreviewActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewPostsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewPostsFragment.java deleted file mode 100644 index 9f041f27..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ThemePreviewPostsFragment.java +++ /dev/null @@ -1,153 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.content.Context; -import android.content.res.ColorStateList; -import android.graphics.PorterDuff; -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.ProgressBar; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.cardview.widget.CardView; -import androidx.core.graphics.drawable.DrawableCompat; -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 ml.docilealligator.infinityforreddit.Activity.CustomThemePreviewActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.CustomView.AspectRatioGifImageView; -import ml.docilealligator.infinityforreddit.R; - -/** - * 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 CustomThemePreviewActivity activity; - - public ThemePreviewPostsFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_theme_preview_posts, container, false); - ButterKnife.bind(this, rootView); - - CustomTheme customTheme = activity.getCustomTheme(); - - cardView.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); - Drawable commentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); - if (commentIcon != null) { - DrawableCompat.setTint(commentIcon, 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); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (CustomThemePreviewActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/UserListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/UserListingFragment.java deleted file mode 100644 index d39f0d0e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/UserListingFragment.java +++ /dev/null @@ -1,220 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.os.Build; -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.coordinatorlayout.widget.CoordinatorLayout; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; - -import com.bumptech.glide.Glide; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.BaseActivity; -import ml.docilealligator.infinityforreddit.Adapter.UserListingRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.FragmentCommunicator; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.User.UserListingViewModel; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Retrofit; - - -/** - * A simple {@link Fragment} subclass. - */ -public class UserListingFragment extends Fragment implements FragmentCommunicator { - - public static final String EXTRA_QUERY = "EQ"; - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - - @BindView(R.id.coordinator_layout_user_listing_fragment) - CoordinatorLayout mCoordinatorLayout; - @BindView(R.id.recycler_view_user_listing_fragment) - RecyclerView mUserListingRecyclerView; - @BindView(R.id.swipe_refresh_layout_user_listing_fragment) - SwipeRefreshLayout mSwipeRefreshLayout; - @BindView(R.id.fetch_user_listing_info_linear_layout_user_listing_fragment) - LinearLayout mFetchUserListingInfoLinearLayout; - @BindView(R.id.fetch_user_listing_info_image_view_user_listing_fragment) - ImageView mFetchUserListingInfoImageView; - @BindView(R.id.fetch_user_listing_info_text_view_user_listing_fragment) - TextView mFetchUserListingInfoTextView; - UserListingViewModel mUserListingViewModel; - @Inject - @Named("no_oauth") - Retrofit mRetrofit; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences mNsfwAndSpoilerSharedPreferences; - @Inject - CustomThemeWrapper customThemeWrapper; - private LinearLayoutManager mLinearLayoutManager; - private String mQuery; - private UserListingRecyclerViewAdapter mAdapter; - private Activity mActivity; - private SortType sortType; - - public UserListingFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_user_listing, container, false); - - ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - applyTheme(); - - Resources resources = getResources(); - - if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { - mUserListingRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { - mUserListingRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); - } - } - - mLinearLayoutManager = new LinearLayoutManager(getActivity()); - mUserListingRecyclerView.setLayoutManager(mLinearLayoutManager); - - mQuery = getArguments().getString(EXTRA_QUERY); - String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); - String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SEARCH_USER, SortType.Type.RELEVANCE.value); - sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase())); - boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); - - mAdapter = new UserListingRecyclerViewAdapter(getActivity(), mOauthRetrofit, mRetrofit, - customThemeWrapper, accessToken, accountName, mRedditDataRoomDatabase.subscribedUserDao(), - () -> mUserListingViewModel.retryLoadingMore()); - - mUserListingRecyclerView.setAdapter(mAdapter); - - UserListingViewModel.Factory factory = new UserListingViewModel.Factory(mRetrofit, mQuery, - sortType, nsfw); - mUserListingViewModel = new ViewModelProvider(this, factory).get(UserListingViewModel.class); - mUserListingViewModel.getUsers().observe(getViewLifecycleOwner(), UserData -> mAdapter.submitList(UserData)); - - mUserListingViewModel.hasUser().observe(getViewLifecycleOwner(), hasUser -> { - mSwipeRefreshLayout.setRefreshing(false); - if (hasUser) { - mFetchUserListingInfoLinearLayout.setVisibility(View.GONE); - } else { - mFetchUserListingInfoLinearLayout.setOnClickListener(view -> { - //Do nothing - }); - showErrorView(R.string.no_users); - } - }); - - mUserListingViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { - if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { - mSwipeRefreshLayout.setRefreshing(false); - } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchUserListingInfoLinearLayout.setOnClickListener(view -> refresh()); - showErrorView(R.string.search_users_error); - } else { - mSwipeRefreshLayout.setRefreshing(true); - } - }); - - mUserListingViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> { - mAdapter.setNetworkState(networkState); - }); - - mSwipeRefreshLayout.setOnRefreshListener(() -> mUserListingViewModel.refresh()); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - mActivity = (Activity) context; - } - - private void showErrorView(int stringResId) { - if (getActivity() != null && isAdded()) { - mSwipeRefreshLayout.setRefreshing(false); - mFetchUserListingInfoLinearLayout.setVisibility(View.VISIBLE); - mFetchUserListingInfoTextView.setText(stringResId); - Glide.with(this).load(R.drawable.error_image).into(mFetchUserListingInfoImageView); - } - } - - public void changeSortType(SortType sortType) { - mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SEARCH_USER, sortType.getType().name()).apply(); - mUserListingViewModel.changeSortType(sortType); - this.sortType = sortType; - } - - @Override - public void refresh() { - mFetchUserListingInfoLinearLayout.setVisibility(View.GONE); - mUserListingViewModel.refresh(); - mAdapter.setNetworkState(null); - } - - @Override - public void applyTheme() { - mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); - mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); - mFetchUserListingInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); - } - - public void goBackToTop() { - if (mLinearLayoutManager != null) { - mLinearLayoutManager.scrollToPositionWithOffset(0, 0); - } - } - - public SortType getSortType() { - return sortType; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java deleted file mode 100644 index 29101dd6..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurImageFragment.java +++ /dev/null @@ -1,264 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.Manifest; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.core.content.FileProvider; -import androidx.fragment.app.Fragment; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.CustomTarget; -import com.bumptech.glide.request.target.Target; -import com.bumptech.glide.request.transition.Transition; -import com.davemorrissey.labs.subscaleview.ImageSource; -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; - -import java.io.File; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.ViewImgurMediaActivity; -import ml.docilealligator.infinityforreddit.AsyncTask.SaveBitmapImageToFileAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SetAsWallpaperBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BuildConfig; -import ml.docilealligator.infinityforreddit.ImgurMedia; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Service.DownloadMediaService; -import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; - -public class ViewImgurImageFragment extends Fragment { - - public static final String EXTRA_IMGUR_IMAGES = "EII"; - private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; - - @BindView(R.id.progress_bar_view_imgur_image_fragment) - ProgressBar progressBar; - @BindView(R.id.image_view_view_imgur_image_fragment) - SubsamplingScaleImageView imageView; - @BindView(R.id.load_image_error_linear_layout_view_imgur_image_fragment) - LinearLayout errorLinearLayout; - - private ViewImgurMediaActivity activity; - private RequestManager glide; - private ImgurMedia imgurMedia; - private boolean isDownloading = false; - private boolean isActionBarHidden = false; - - public ViewImgurImageFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_view_imgur_images, container, false); - - ButterKnife.bind(this, rootView); - - setHasOptionsMenu(true); - - imgurMedia = getArguments().getParcelable(EXTRA_IMGUR_IMAGES); - glide = Glide.with(activity); - loadImage(); - - imageView.setOnClickListener(view -> { - if (isActionBarHidden) { - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - isActionBarHidden = false; - } else { - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE); - isActionBarHidden = true; - } - }); - - errorLinearLayout.setOnClickListener(view -> { - progressBar.setVisibility(View.VISIBLE); - errorLinearLayout.setVisibility(View.GONE); - loadImage(); - }); - - return rootView; - } - - private void loadImage() { - glide.asBitmap().load(imgurMedia.getLink()).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - return false; - } - - @Override - public boolean onResourceReady(Bitmap resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - progressBar.setVisibility(View.GONE); - return false; - } - }).into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - imageView.setImage(ImageSource.bitmap(resource)); - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - inflater.inflate(R.menu.view_imgur_image_fragment, menu); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_download_view_imgur_image_fragment: - if (isDownloading) { - return false; - } - - isDownloading = true; - - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - - return true; - case R.id.action_share_view_imgur_image_fragment: - glide.asBitmap().load(imgurMedia.getLink()).into(new CustomTarget() { - - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - if (activity.getExternalCacheDir() != null) { - Toast.makeText(activity, R.string.save_image_first, Toast.LENGTH_SHORT).show(); - new SaveBitmapImageToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), - imgurMedia.getFileName(), - new SaveBitmapImageToFileAsyncTask.SaveBitmapImageToFileAsyncTaskListener() { - @Override - public void saveSuccess(File imageFile) { - Uri uri = FileProvider.getUriForFile(activity, - BuildConfig.APPLICATION_ID + ".provider", imageFile); - Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, uri); - shareIntent.setType("image/*"); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } - - @Override - public void saveFailed() { - Toast.makeText(activity, - R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); - } - }).execute(); - } else { - Toast.makeText(activity, - R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - return true; - case R.id.action_set_wallpaper_view_imgur_image_fragment: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); - setAsWallpaperBottomSheetFragment.setArguments(bundle); - setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); - } else { - ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); - } - return true; - } - - return false; - } - - private void download() { - isDownloading = false; - - Intent intent = new Intent(activity, DownloadMediaService.class); - intent.putExtra(DownloadMediaService.EXTRA_URL, imgurMedia.getLink()); - intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_IMAGE); - intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, imgurMedia.getFileName()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - activity.startForegroundService(intent); - } else { - activity.startService(intent); - } - Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); - isDownloading = false; - } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { - download(); - } - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (ViewImgurMediaActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java deleted file mode 100644 index 154901bb..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewImgurVideoFragment.java +++ /dev/null @@ -1,289 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.Manifest; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; - -import com.google.android.exoplayer2.ExoPlayerFactory; -import com.google.android.exoplayer2.Player; -import com.google.android.exoplayer2.SimpleExoPlayer; -import com.google.android.exoplayer2.source.ProgressiveMediaSource; -import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; -import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; -import com.google.android.exoplayer2.trackselection.TrackSelection; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; -import com.google.android.exoplayer2.trackselection.TrackSelector; -import com.google.android.exoplayer2.ui.PlayerView; -import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; -import com.google.android.exoplayer2.util.Util; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.ImgurMedia; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Service.DownloadMediaService; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class ViewImgurVideoFragment extends Fragment { - - public static final String EXTRA_IMGUR_VIDEO = "EIV"; - private static final String IS_MUTE_STATE = "IMS"; - private static final String POSITION_STATE = "PS"; - private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; - @BindView(R.id.player_view_view_imgur_video_fragment) - PlayerView videoPlayerView; - @BindView(R.id.mute_exo_playback_control_view) - ImageButton muteButton; - private Activity activity; - private ImgurMedia imgurMedia; - private SimpleExoPlayer player; - private DataSource.Factory dataSourceFactory; - private boolean wasPlaying = false; - private boolean isMute = false; - private boolean isDownloading = false; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - - public ViewImgurVideoFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_view_imgur_video, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - setHasOptionsMenu(true); - - activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); - - imgurMedia = getArguments().getParcelable(EXTRA_IMGUR_VIDEO); - - if (!mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_IGNORE_NAV_BAR, false)) { - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { - //Set player controller bottom margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); - LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.bottomMargin = getResources().getDimensionPixelSize(resourceId); - } else { - //Set player controller right margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); - LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.rightMargin = getResources().getDimensionPixelSize(resourceId); - } - } - - videoPlayerView.setControllerVisibilityListener(visibility -> { - switch (visibility) { - case View.GONE: - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE); - break; - case View.VISIBLE: - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - } - }); - - TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); - TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); - player = ExoPlayerFactory.newSimpleInstance(activity, trackSelector); - videoPlayerView.setPlayer(player); - dataSourceFactory = new DefaultDataSourceFactory(activity, - Util.getUserAgent(activity, "Infinity")); - player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(imgurMedia.getLink()))); - preparePlayer(savedInstanceState); - - return rootView; - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - inflater.inflate(R.menu.view_imgur_video_fragment, menu); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_download_view_imgur_video_fragment) { - isDownloading = true; - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - return true; - } - return false; - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); - isDownloading = false; - } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { - download(); - } - } - } - - private void download() { - isDownloading = false; - - Intent intent = new Intent(activity, DownloadMediaService.class); - intent.putExtra(DownloadMediaService.EXTRA_URL, imgurMedia.getLink()); - intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_VIDEO); - intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, imgurMedia.getFileName()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - activity.startForegroundService(intent); - } else { - activity.startService(intent); - } - Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); - } - - private void preparePlayer(Bundle savedInstanceState) { - player.setRepeatMode(Player.REPEAT_MODE_ALL); - wasPlaying = true; - - boolean muteVideo = mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_VIDEO, false); - - if (savedInstanceState != null) { - long position = savedInstanceState.getLong(POSITION_STATE); - if (position > 0) { - player.seekTo(position); - } - isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); - if (isMute) { - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } else { - player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } - } else if (muteVideo) { - isMute = true; - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } else { - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } - - player.addListener(new Player.EventListener() { - @Override - public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - if (!trackGroups.isEmpty()) { - for (int i = 0; i < trackGroups.length; i++) { - String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; - if (mimeType != null && mimeType.contains("audio")) { - muteButton.setVisibility(View.VISIBLE); - muteButton.setOnClickListener(view -> { - if (isMute) { - isMute = false; - player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } else { - isMute = true; - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } - }); - break; - } - } - } else { - muteButton.setVisibility(View.GONE); - } - } - }); - } - - @Override - public void onResume() { - super.onResume(); - if (wasPlaying) { - player.setPlayWhenReady(true); - } - } - - @Override - public void onPause() { - super.onPause(); - wasPlaying = player.getPlayWhenReady(); - player.setPlayWhenReady(false); - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(IS_MUTE_STATE, isMute); - outState.putLong(POSITION_STATE, player.getCurrentPosition()); - } - - @Override - public void onDestroy() { - super.onDestroy(); - player.release(); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryImageOrGifFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryImageOrGifFragment.java deleted file mode 100644 index 288f0d69..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryImageOrGifFragment.java +++ /dev/null @@ -1,381 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.Manifest; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.ProgressBar; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.content.ContextCompat; -import androidx.core.content.FileProvider; -import androidx.fragment.app.Fragment; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.RequestManager; -import com.bumptech.glide.load.DataSource; -import com.bumptech.glide.load.engine.GlideException; -import com.bumptech.glide.load.resource.gif.GifDrawable; -import com.bumptech.glide.request.RequestListener; -import com.bumptech.glide.request.target.CustomTarget; -import com.bumptech.glide.request.target.Target; -import com.bumptech.glide.request.transition.Transition; -import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; -import com.github.piasy.biv.BigImageViewer; -import com.github.piasy.biv.loader.ImageLoader; -import com.github.piasy.biv.loader.glide.GlideImageLoader; -import com.github.piasy.biv.view.BigImageView; -import com.github.piasy.biv.view.GlideImageViewFactory; - -import java.io.File; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Activity.ViewRedditGalleryActivity; -import ml.docilealligator.infinityforreddit.AsyncTask.SaveBitmapImageToFileAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.SaveGIFToFileAsyncTask; -import ml.docilealligator.infinityforreddit.BottomSheetFragment.SetAsWallpaperBottomSheetFragment; -import ml.docilealligator.infinityforreddit.BuildConfig; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Service.DownloadMediaService; -import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; - -public class ViewRedditGalleryImageOrGifFragment extends Fragment { - - public static final String EXTRA_REDDIT_GALLERY_MEDIA = "ERGM"; - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; - - @BindView(R.id.progress_bar_view_reddit_gallery_image_or_gif_fragment) - ProgressBar progressBar; - @BindView(R.id.image_view_view_reddit_gallery_image_or_gif_fragment) - BigImageView imageView; - @BindView(R.id.load_image_error_linear_layout_view_reddit_gallery_image_or_gif_fragment) - LinearLayout errorLinearLayout; - - private ViewRedditGalleryActivity activity; - private RequestManager glide; - private Post.Gallery media; - private String subredditName; - private boolean isDownloading = false; - private boolean isActionBarHidden = false; - - public ViewRedditGalleryImageOrGifFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - BigImageViewer.initialize(GlideImageLoader.with(activity)); - - View rootView = inflater.inflate(R.layout.fragment_view_reddit_gallery_image_or_gif, container, false); - - ButterKnife.bind(this, rootView); - - setHasOptionsMenu(true); - - media = getArguments().getParcelable(EXTRA_REDDIT_GALLERY_MEDIA); - subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); - glide = Glide.with(activity); - - imageView.setImageViewFactory(new GlideImageViewFactory()); - - imageView.setImageLoaderCallback(new ImageLoader.Callback() { - @Override - public void onCacheHit(int imageType, File image) { - - } - - @Override - public void onCacheMiss(int imageType, File image) { - - } - - @Override - public void onStart() { - - } - - @Override - public void onProgress(int progress) { - - } - - @Override - public void onFinish() { - - } - - @Override - public void onSuccess(File image) { - progressBar.setVisibility(View.GONE); - - final SubsamplingScaleImageView view = imageView.getSSIV(); - - if (view != null) { - view.setMinimumDpi(80); - - view.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() { - @Override - public void onReady() { - - } - - @Override - public void onImageLoaded() { - view.setDoubleTapZoomDpi(70); - view.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); - view.setQuickScaleEnabled(true); - } - - @Override - public void onPreviewLoadError(Exception e) { - - } - - @Override - public void onImageLoadError(Exception e) { - - } - - @Override - public void onTileLoadError(Exception e) { - - } - - @Override - public void onPreviewReleased() { - - } - }); - } - } - - @Override - public void onFail(Exception error) { - progressBar.setVisibility(View.GONE); - errorLinearLayout.setVisibility(View.VISIBLE); - } - }); - - loadImage(); - - imageView.setOnClickListener(view -> { - if (isActionBarHidden) { - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - isActionBarHidden = false; - } else { - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE); - isActionBarHidden = true; - } - }); - - errorLinearLayout.setOnClickListener(view -> { - progressBar.setVisibility(View.VISIBLE); - errorLinearLayout.setVisibility(View.GONE); - loadImage(); - }); - - return rootView; - } - - private void loadImage() { - imageView.showImage(Uri.parse(media.url)); - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - inflater.inflate(R.menu.view_reddit_gallery_image_or_gif_fragment, menu); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - switch (item.getItemId()) { - case R.id.action_download_view_reddit_gallery_image_or_gif_fragment: - if (isDownloading) { - return false; - } - - isDownloading = true; - - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - - return true; - case R.id.action_share_view_reddit_gallery_image_or_gif_fragment: - if (media.mediaType == Post.Gallery.TYPE_GIF) { - shareGif(); - } else { - shareImage(); - } - return true; - case R.id.action_set_wallpaper_view_reddit_gallery_image_or_gif_fragment: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { - SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); - Bundle bundle = new Bundle(); - bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); - setAsWallpaperBottomSheetFragment.setArguments(bundle); - setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); - } else { - ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); - } - return true; - } - - return false; - } - - private void download() { - isDownloading = false; - - Intent intent = new Intent(activity, DownloadMediaService.class); - intent.putExtra(DownloadMediaService.EXTRA_URL, media.url); - intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, media.mediaType == Post.Gallery.TYPE_GIF ? DownloadMediaService.EXTRA_MEDIA_TYPE_GIF: DownloadMediaService.EXTRA_MEDIA_TYPE_IMAGE); - intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, media.fileName); - intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, subredditName); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - activity.startForegroundService(intent); - } else { - activity.startService(intent); - } - Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); - } - - private void shareImage() { - glide.asBitmap().load(media.url).into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - if (activity.getExternalCacheDir() != null) { - Toast.makeText(activity, R.string.save_image_first, Toast.LENGTH_SHORT).show(); - new SaveBitmapImageToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), - media.fileName, - new SaveBitmapImageToFileAsyncTask.SaveBitmapImageToFileAsyncTaskListener() { - @Override - public void saveSuccess(File imageFile) { - Uri uri = FileProvider.getUriForFile(activity, - BuildConfig.APPLICATION_ID + ".provider", imageFile); - Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, uri); - shareIntent.setType("image/*"); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } - - @Override - public void saveFailed() { - Toast.makeText(activity, - R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); - } - }).execute(); - } else { - Toast.makeText(activity, - R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); - } - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - } - - private void shareGif() { - Toast.makeText(activity, R.string.save_gif_first, Toast.LENGTH_SHORT).show(); - glide.asGif().load(media.url).listener(new RequestListener() { - @Override - public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { - return false; - } - - @Override - public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { - if (activity.getExternalCacheDir() != null) { - new SaveGIFToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), media.fileName, - new SaveGIFToFileAsyncTask.SaveGIFToFileAsyncTaskListener() { - @Override - public void saveSuccess(File imageFile) { - Uri uri = FileProvider.getUriForFile(activity, - BuildConfig.APPLICATION_ID + ".provider", imageFile); - Intent shareIntent = new Intent(); - shareIntent.setAction(Intent.ACTION_SEND); - shareIntent.putExtra(Intent.EXTRA_STREAM, uri); - shareIntent.setType("image/*"); - shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); - } - - @Override - public void saveFailed() { - Toast.makeText(activity, - R.string.cannot_save_gif, Toast.LENGTH_SHORT).show(); - } - }).execute(); - } else { - Toast.makeText(activity, - R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); - } - return false; - } - }).submit(); - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); - isDownloading = false; - } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { - download(); - } - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (ViewRedditGalleryActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryVideoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryVideoFragment.java deleted file mode 100644 index 3ec55cb7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Fragment/ViewRedditGalleryVideoFragment.java +++ /dev/null @@ -1,293 +0,0 @@ -package ml.docilealligator.infinityforreddit.Fragment; - -import android.Manifest; -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.content.res.Configuration; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Build; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageButton; -import android.widget.LinearLayout; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.core.content.ContextCompat; -import androidx.fragment.app.Fragment; - -import com.google.android.exoplayer2.ExoPlayerFactory; -import com.google.android.exoplayer2.Player; -import com.google.android.exoplayer2.SimpleExoPlayer; -import com.google.android.exoplayer2.source.ProgressiveMediaSource; -import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; -import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; -import com.google.android.exoplayer2.trackselection.TrackSelection; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; -import com.google.android.exoplayer2.trackselection.TrackSelector; -import com.google.android.exoplayer2.ui.PlayerView; -import com.google.android.exoplayer2.upstream.DataSource; -import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; -import com.google.android.exoplayer2.util.Util; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Service.DownloadMediaService; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class ViewRedditGalleryVideoFragment extends Fragment { - - public static final String EXTRA_REDDIT_GALLERY_VIDEO = "EIV"; - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - private static final String IS_MUTE_STATE = "IMS"; - private static final String POSITION_STATE = "PS"; - private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; - @BindView(R.id.player_view_view_reddit_gallery_video_fragment) - PlayerView videoPlayerView; - @BindView(R.id.mute_exo_playback_control_view) - ImageButton muteButton; - private Activity activity; - private Post.Gallery galleryVideo; - private String subredditName; - private SimpleExoPlayer player; - private DataSource.Factory dataSourceFactory; - private boolean wasPlaying = false; - private boolean isMute = false; - private boolean isDownloading = false; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - - public ViewRedditGalleryVideoFragment() { - // Required empty public constructor - } - - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_view_reddit_gallery_video, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - setHasOptionsMenu(true); - - activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); - - galleryVideo = getArguments().getParcelable(EXTRA_REDDIT_GALLERY_VIDEO); - subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); - - if (!mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_IGNORE_NAV_BAR, false)) { - if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { - //Set player controller bottom margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); - LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.bottomMargin = getResources().getDimensionPixelSize(resourceId); - } else { - //Set player controller right margin in order to display it above the navbar - int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); - LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); - ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); - params.rightMargin = getResources().getDimensionPixelSize(resourceId); - } - } - - videoPlayerView.setControllerVisibilityListener(visibility -> { - switch (visibility) { - case View.GONE: - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE); - break; - case View.VISIBLE: - activity.getWindow().getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); - } - }); - - TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); - TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); - player = ExoPlayerFactory.newSimpleInstance(activity, trackSelector); - videoPlayerView.setPlayer(player); - dataSourceFactory = new DefaultDataSourceFactory(activity, - Util.getUserAgent(activity, "Infinity")); - player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(galleryVideo.url))); - preparePlayer(savedInstanceState); - - return rootView; - } - - @Override - public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { - inflater.inflate(R.menu.view_reddit_gallery_video_fragment, menu); - super.onCreateOptionsMenu(menu, inflater); - } - - @Override - public boolean onOptionsItemSelected(@NonNull MenuItem item) { - if (item.getItemId() == R.id.action_download_view_reddit_gallery_video_fragment) { - isDownloading = true; - if (Build.VERSION.SDK_INT >= 23) { - if (ContextCompat.checkSelfPermission(activity, - Manifest.permission.WRITE_EXTERNAL_STORAGE) - != PackageManager.PERMISSION_GRANTED) { - - // Permission is not granted - // No explanation needed; request the permission - requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, - PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); - } else { - // Permission has already been granted - download(); - } - } else { - download(); - } - return true; - } - return false; - } - - @Override - public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { - if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { - if (grantResults[0] == PackageManager.PERMISSION_DENIED) { - Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); - isDownloading = false; - } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { - download(); - } - } - } - - private void download() { - isDownloading = false; - - Intent intent = new Intent(activity, DownloadMediaService.class); - intent.putExtra(DownloadMediaService.EXTRA_URL, galleryVideo.url); - intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_VIDEO); - intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, galleryVideo.fileName); - intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, subredditName); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - activity.startForegroundService(intent); - } else { - activity.startService(intent); - } - Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); - } - - private void preparePlayer(Bundle savedInstanceState) { - player.setRepeatMode(Player.REPEAT_MODE_ALL); - wasPlaying = true; - - boolean muteVideo = mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_VIDEO, false); - - if (savedInstanceState != null) { - long position = savedInstanceState.getLong(POSITION_STATE); - if (position > 0) { - player.seekTo(position); - } - isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); - if (isMute) { - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } else { - player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } - } else if (muteVideo) { - isMute = true; - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } else { - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } - - player.addListener(new Player.EventListener() { - @Override - public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - if (!trackGroups.isEmpty()) { - for (int i = 0; i < trackGroups.length; i++) { - String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; - if (mimeType != null && mimeType.contains("audio")) { - muteButton.setVisibility(View.VISIBLE); - muteButton.setOnClickListener(view -> { - if (isMute) { - isMute = false; - player.setVolume(1f); - muteButton.setImageResource(R.drawable.ic_unmute_24dp); - } else { - isMute = true; - player.setVolume(0f); - muteButton.setImageResource(R.drawable.ic_mute_24dp); - } - }); - break; - } - } - } else { - muteButton.setVisibility(View.GONE); - } - } - }); - } - - @Override - public void onResume() { - super.onResume(); - if (wasPlaying) { - player.setPlayWhenReady(true); - } - } - - @Override - public void onPause() { - super.onPause(); - wasPlaying = player.getPlayWhenReady(); - player.setPlayWhenReady(false); - } - - @Override - public void onSaveInstanceState(@NonNull Bundle outState) { - super.onSaveInstanceState(outState); - outState.putBoolean(IS_MUTE_STATE, isMute); - outState.putLong(POSITION_STATE, player.getCurrentPosition()); - } - - @Override - public void onDestroy() { - super.onDestroy(); - player.release(); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java index a93327bc..4d17d9d3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Infinity.java @@ -15,9 +15,9 @@ import com.melegy.redscreenofdeath.RedScreenOfDeath; import org.greenrobot.eventbus.EventBus; -import ml.docilealligator.infinityforreddit.BroadcastReceiver.NetworkWifiStatusReceiver; -import ml.docilealligator.infinityforreddit.Event.ChangeNetworkStatusEvent; -import ml.docilealligator.infinityforreddit.Utils.Utils; +import ml.docilealligator.infinityforreddit.broadcastreceivers.NetworkWifiStatusReceiver; +import ml.docilealligator.infinityforreddit.events.ChangeNetworkStatusEvent; +import ml.docilealligator.infinityforreddit.utils.Utils; import ml.docilealligator.inifinityforreddit.EventBusIndex; public class Infinity extends Application { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ComposeMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ComposeMessage.java deleted file mode 100644 index ff40ccc8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ComposeMessage.java +++ /dev/null @@ -1,58 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class ComposeMessage { - public static void composeMessage(Retrofit oauthRetrofit, String accessToken, Locale locale, String username, - String subject, String message, ComposeMessageListener composeMessageListener) { - Map headers = APIUtils.getOAuthHeader(accessToken); - Map params = new HashMap<>(); - params.put(APIUtils.API_TYPE_KEY, "json"); - params.put(APIUtils.RETURN_RTJSON_KEY, "true"); - params.put(APIUtils.SUBJECT_KEY, subject); - params.put(APIUtils.TEXT_KEY, message); - params.put(APIUtils.TO_KEY, username); - - oauthRetrofit.create(RedditAPI.class).composePrivateMessage(headers, params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseMessage.parseComposedMessageError(response.body(), new ParseMessage.ParseComposedMessageErrorListener() { - @Override - public void noError() { - composeMessageListener.composeMessageSuccess(); - } - - @Override - public void error(String errorMessage) { - composeMessageListener.composeMessageFailed(errorMessage); - } - }); - } else { - composeMessageListener.composeMessageFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - composeMessageListener.composeMessageFailed(t.getMessage()); - } - }); - } - - public interface ComposeMessageListener { - void composeMessageSuccess(); - void composeMessageFailed(String errorMessage); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/FetchMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/FetchMessage.java deleted file mode 100644 index 1322d7c0..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/FetchMessage.java +++ /dev/null @@ -1,53 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.ArrayList; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchMessage { - - public static final String WHERE_INBOX = "inbox"; - public static final String WHERE_UNREAD = "unread"; - public static final String WHERE_SENT = "sent"; - public static final String WHERE_COMMENTS = "comments"; - public static final String WHERE_MESSAGES = "messages"; - public static final String WHERE_MESSAGES_DETAIL = "messages_detail"; - public static final int MESSAGE_TYPE_INBOX = 0; - public static final int MESSAGE_TYPE_PRIVATE_MESSAGE = 1; - public static final int MESSAGE_TYPE_NOTIFICATION = 2; - - static void fetchInbox(Retrofit oauthRetrofit, Locale locale, String accessToken, String where, - String after, int messageType, FetchMessagesListener fetchMessagesListener) { - oauthRetrofit.create(RedditAPI.class).getMessages(APIUtils.getOAuthHeader(accessToken), where, after) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseMessage.parseMessage(response.body(), locale, messageType, fetchMessagesListener::fetchSuccess); - } else { - fetchMessagesListener.fetchFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchMessagesListener.fetchFailed(); - } - }); - } - - interface FetchMessagesListener { - void fetchSuccess(ArrayList messages, @Nullable String after); - - void fetchFailed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/Message.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/Message.java deleted file mode 100644 index 771d675e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/Message.java +++ /dev/null @@ -1,221 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.ArrayList; - -public class Message implements Parcelable { - public static final String TYPE_COMMENT = "t1"; - public static final String TYPE_ACCOUNT = "t2"; - public static final String TYPE_LINK = "t3"; - public static final String TYPE_MESSAGE = "t4"; - public static final String TYPE_SUBREDDIT = "t5"; - static final String TYPE_AWARD = "t6"; - - private String kind; - private String subredditName; - private String subredditNamePrefixed; - private String id; - private String fullname; - private String subject; - private String author; - private String destination; - private String parentFullName; - private String title; - private String body; - private String context; - private String distinguished; - private String formattedTime; - private boolean wasComment; - private boolean isNew; - private int score; - private int nComments; - private long timeUTC; - private ArrayList replies; - - Message(String kind, String subredditName, String subredditNamePrefixed, String id, String fullname, - String subject, String author, String destination, String parentFullName, String title, String body, - String context, String distinguished, String formattedTime, boolean wasComment, boolean isNew, - int score, int nComments, long timeUTC) { - this.kind = kind; - this.subredditName = subredditName; - this.subredditNamePrefixed = subredditNamePrefixed; - this.id = id; - this.fullname = fullname; - this.subject = subject; - this.author = author; - this.destination = destination; - this.parentFullName = parentFullName; - this.title = title; - this.body = body; - this.context = context; - this.distinguished = distinguished; - this.formattedTime = formattedTime; - this.wasComment = wasComment; - this.isNew = isNew; - this.score = score; - this.nComments = nComments; - this.timeUTC = timeUTC; - } - - - protected Message(Parcel in) { - kind = in.readString(); - subredditName = in.readString(); - subredditNamePrefixed = in.readString(); - id = in.readString(); - fullname = in.readString(); - subject = in.readString(); - author = in.readString(); - destination = in.readString(); - parentFullName = in.readString(); - title = in.readString(); - body = in.readString(); - context = in.readString(); - distinguished = in.readString(); - formattedTime = in.readString(); - wasComment = in.readByte() != 0; - isNew = in.readByte() != 0; - score = in.readInt(); - nComments = in.readInt(); - timeUTC = in.readLong(); - replies = in.createTypedArrayList(Message.CREATOR); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Message createFromParcel(Parcel in) { - return new Message(in); - } - - @Override - public Message[] newArray(int size) { - return new Message[size]; - } - }; - - public String getKind() { - return kind; - } - - public String getSubredditName() { - return subredditName; - } - - public String getSubredditNamePrefixed() { - return subredditNamePrefixed; - } - - public String getId() { - return id; - } - - public String getFullname() { - return fullname; - } - - public String getSubject() { - return subject; - } - - public String getAuthor() { - return author; - } - - public String getDestination() { - return destination; - } - - public String getParentFullName() { - return parentFullName; - } - - public String getTitle() { - return title; - } - - public String getBody() { - return body; - } - - public String getContext() { - return context; - } - - public String getDistinguished() { - return distinguished; - } - - public String getFormattedTime() { - return formattedTime; - } - - public boolean wasComment() { - return wasComment; - } - - public boolean isNew() { - return isNew; - } - - public void setNew(boolean isNew) { - this.isNew = isNew; - } - - public int getScore() { - return score; - } - - public int getnComments() { - return nComments; - } - - public long getTimeUTC() { - return timeUTC; - } - - public ArrayList getReplies() { - return replies; - } - - public void setReplies(ArrayList replies) { - this.replies = replies; - } - - public void addReply(Message reply) { - if (replies == null) { - replies = new ArrayList<>(); - } - replies.add(reply); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(kind); - parcel.writeString(subredditName); - parcel.writeString(subredditNamePrefixed); - parcel.writeString(id); - parcel.writeString(fullname); - parcel.writeString(subject); - parcel.writeString(author); - parcel.writeString(destination); - parcel.writeString(parentFullName); - parcel.writeString(title); - parcel.writeString(body); - parcel.writeString(context); - parcel.writeString(distinguished); - parcel.writeString(formattedTime); - parcel.writeByte((byte) (wasComment ? 1 : 0)); - parcel.writeByte((byte) (isNew ? 1 : 0)); - parcel.writeInt(score); - parcel.writeInt(nComments); - parcel.writeLong(timeUTC); - parcel.writeTypedList(replies); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSource.java deleted file mode 100644 index e3f8cc18..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSource.java +++ /dev/null @@ -1,119 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.PageKeyedDataSource; - -import java.util.ArrayList; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.NetworkState; -import retrofit2.Retrofit; - -class MessageDataSource extends PageKeyedDataSource { - private Retrofit oauthRetrofit; - private Locale locale; - private String accessToken; - private String where; - private int messageType; - - private MutableLiveData paginationNetworkStateLiveData; - private MutableLiveData initialLoadStateLiveData; - private MutableLiveData hasPostLiveData; - - private LoadParams params; - private LoadCallback callback; - - MessageDataSource(Retrofit oauthRetrofit, Locale locale, String accessToken, String where) { - this.oauthRetrofit = oauthRetrofit; - this.locale = locale; - this.accessToken = accessToken; - this.where = where; - if (where.equals(FetchMessage.WHERE_MESSAGES)) { - messageType = FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE; - } else { - messageType = FetchMessage.MESSAGE_TYPE_INBOX; - } - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasPostLiveData = new MutableLiveData<>(); - } - - MutableLiveData getPaginationNetworkStateLiveData() { - return paginationNetworkStateLiveData; - } - - MutableLiveData getInitialLoadStateLiveData() { - return initialLoadStateLiveData; - } - - MutableLiveData hasPostLiveData() { - return hasPostLiveData; - } - - void retryLoadingMore() { - loadAfter(params, callback); - } - - @Override - public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { - initialLoadStateLiveData.postValue(NetworkState.LOADING); - - FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, null, messageType, - new FetchMessage.FetchMessagesListener() { - @Override - public void fetchSuccess(ArrayList messages, @Nullable String after) { - if (messages.size() == 0) { - hasPostLiveData.postValue(false); - } else { - hasPostLiveData.postValue(true); - } - - if (after == null || after.equals("") || after.equals("null")) { - callback.onResult(messages, null, null); - } else { - callback.onResult(messages, null, after); - } - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void fetchFailed() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); - } - }); - } - - @Override - public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { - - } - - @Override - public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { - this.params = params; - this.callback = callback; - - paginationNetworkStateLiveData.postValue(NetworkState.LOADING); - - FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, params.key, messageType, - new FetchMessage.FetchMessagesListener() { - @Override - public void fetchSuccess(ArrayList messages, @Nullable String after) { - if (after == null || after.equals("") || after.equals("null")) { - callback.onResult(messages, null); - } else { - callback.onResult(messages, after); - } - - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void fetchFailed() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSourceFactory.java deleted file mode 100644 index db717ce5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageDataSourceFactory.java +++ /dev/null @@ -1,47 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.DataSource; - -import java.util.Locale; - -import retrofit2.Retrofit; - -class MessageDataSourceFactory extends DataSource.Factory { - private Retrofit oauthRetrofit; - private Locale locale; - private String accessToken; - private String where; - - private MessageDataSource messageDataSource; - private MutableLiveData messageDataSourceLiveData; - - MessageDataSourceFactory(Retrofit oauthRetrofit, Locale locale, String accessToken, String where) { - this.oauthRetrofit = oauthRetrofit; - this.locale = locale; - this.accessToken = accessToken; - this.where = where; - messageDataSourceLiveData = new MutableLiveData<>(); - } - - @NonNull - @Override - public DataSource create() { - messageDataSource = new MessageDataSource(oauthRetrofit, locale, accessToken, where); - messageDataSourceLiveData.postValue(messageDataSource); - return messageDataSource; - } - - public MutableLiveData getMessageDataSourceLiveData() { - return messageDataSourceLiveData; - } - - MessageDataSource getMessageDataSource() { - return messageDataSource; - } - - void changeWhere(String where) { - this.where = where; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageViewModel.java deleted file mode 100644 index 3af6b708..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/MessageViewModel.java +++ /dev/null @@ -1,97 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; -import androidx.paging.LivePagedListBuilder; -import androidx.paging.PagedList; - -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.NetworkState; -import retrofit2.Retrofit; - -public class MessageViewModel extends ViewModel { - private MessageDataSourceFactory messageDataSourceFactory; - private LiveData paginationNetworkState; - private LiveData initialLoadingState; - private LiveData hasMessageLiveData; - private LiveData> messages; - private MutableLiveData whereLiveData; - - public MessageViewModel(Retrofit retrofit, Locale locale, String accessToken, String where) { - messageDataSourceFactory = new MessageDataSourceFactory(retrofit, locale, accessToken, where); - - initialLoadingState = Transformations.switchMap(messageDataSourceFactory.getMessageDataSourceLiveData(), - MessageDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(messageDataSourceFactory.getMessageDataSourceLiveData(), - MessageDataSource::getPaginationNetworkStateLiveData); - hasMessageLiveData = Transformations.switchMap(messageDataSourceFactory.getMessageDataSourceLiveData(), - MessageDataSource::hasPostLiveData); - - whereLiveData = new MutableLiveData<>(); - whereLiveData.postValue(where); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - messages = Transformations.switchMap(whereLiveData, newWhere -> { - messageDataSourceFactory.changeWhere(whereLiveData.getValue()); - return (new LivePagedListBuilder(messageDataSourceFactory, pagedListConfig)).build(); - }); - } - - public LiveData> getMessages() { - return messages; - } - - public LiveData getPaginationNetworkState() { - return paginationNetworkState; - } - - public LiveData getInitialLoadingState() { - return initialLoadingState; - } - - public LiveData hasMessage() { - return hasMessageLiveData; - } - - public void refresh() { - messageDataSourceFactory.getMessageDataSource().invalidate(); - } - - public void retryLoadingMore() { - messageDataSourceFactory.getMessageDataSource().retryLoadingMore(); - } - - void changeWhere(String where) { - whereLiveData.postValue(where); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Retrofit retrofit; - private Locale locale; - private String accessToken; - private String where; - - public Factory(Retrofit retrofit, Locale locale, String accessToken, String where) { - this.retrofit = retrofit; - this.locale = locale; - this.accessToken = accessToken; - this.where = where; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new MessageViewModel(retrofit, locale, accessToken, where); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ParseMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ParseMessage.java deleted file mode 100644 index 410d1886..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ParseMessage.java +++ /dev/null @@ -1,242 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import android.os.AsyncTask; - -import androidx.annotation.Nullable; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Calendar; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -public class ParseMessage { - public static void parseMessage(String response, Locale locale, int messageType, - ParseMessageAsyncTaskListener parseMessageAsnycTaskListener) { - new ParseMessageAsnycTask(response, locale, messageType, parseMessageAsnycTaskListener).execute(); - } - - public static ArrayList parseMessages(JSONArray messageArray, Locale locale, int messageType) { - ArrayList messages = new ArrayList<>(); - for (int i = 0; i < messageArray.length(); i++) { - try { - Message message = parseSingleMessage(messageArray.getJSONObject(i), locale, messageType); - if (message != null) { - messages.add(message); - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - return messages; - } - - public static void parseRepliedMessage(String response, Locale locale, ParseSentMessageAsyncTaskListener parseSentMessageAsyncTaskListener) { - new ParseSentMessageAsnycTask(response, locale, parseSentMessageAsyncTaskListener).execute(); - } - - public static void parseComposedMessageError(String response, ParseComposedMessageErrorListener parseComposedMessageErrorListener) { - new ParseComposedMessageErrorAsncTask(response, parseComposedMessageErrorListener).execute(); - } - - @Nullable - private static Message parseSingleMessage(JSONObject messageJSON, Locale locale, int messageType) throws JSONException { - String kind = messageJSON.getString(JSONUtils.KIND_KEY); - if ((messageType == FetchMessage.MESSAGE_TYPE_INBOX && kind.equals("t4")) || - (messageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE && !kind.equals("t4"))) { - return null; - } - - JSONObject rawMessageJSON = messageJSON.getJSONObject(JSONUtils.DATA_KEY); - String subredditName = rawMessageJSON.getString(JSONUtils.SUBREDDIT_KEY); - String subredditNamePrefixed = rawMessageJSON.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); - String id = rawMessageJSON.getString(JSONUtils.ID_KEY); - String fullname = rawMessageJSON.getString(JSONUtils.NAME_KEY); - String subject = rawMessageJSON.getString(JSONUtils.SUBJECT_KEY); - String author = rawMessageJSON.getString(JSONUtils.AUTHOR_KEY); - String destination = rawMessageJSON.getString(JSONUtils.DEST_KEY); - String parentFullname = rawMessageJSON.getString(JSONUtils.PARENT_ID_KEY); - String title = rawMessageJSON.has(JSONUtils.LINK_TITLE_KEY) ? rawMessageJSON.getString(JSONUtils.LINK_TITLE_KEY) : null; - String body = Utils.modifyMarkdown(rawMessageJSON.getString(JSONUtils.BODY_KEY)); - String context = rawMessageJSON.getString(JSONUtils.CONTEXT_KEY); - String distinguished = rawMessageJSON.getString(JSONUtils.DISTINGUISHED_KEY); - boolean wasComment = rawMessageJSON.getBoolean(JSONUtils.WAS_COMMENT_KEY); - boolean isNew = rawMessageJSON.getBoolean(JSONUtils.NEW_KEY); - int score = rawMessageJSON.getInt(JSONUtils.SCORE_KEY); - int nComments = rawMessageJSON.isNull(JSONUtils.NUM_COMMENTS_KEY) ? -1 : rawMessageJSON.getInt(JSONUtils.NUM_COMMENTS_KEY); - long timeUTC = rawMessageJSON.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; - - Calendar submitTimeCalendar = Calendar.getInstance(); - submitTimeCalendar.setTimeInMillis(timeUTC); - String formattedTime = new SimpleDateFormat("MMM d, yyyy, HH:mm", - locale).format(submitTimeCalendar.getTime()); - - ArrayList replies = null; - if (!rawMessageJSON.isNull(JSONUtils.REPLIES_KEY) && rawMessageJSON.get(JSONUtils.REPLIES_KEY) instanceof JSONObject) { - JSONArray repliesArray = rawMessageJSON.getJSONObject(JSONUtils.REPLIES_KEY).getJSONObject(JSONUtils.DATA_KEY) - .getJSONArray(JSONUtils.CHILDREN_KEY); - replies = parseMessages(repliesArray, locale, messageType); - } - - Message message = new Message(kind, subredditName, subredditNamePrefixed, id, fullname, subject, - author, destination, parentFullname, title, body, context, distinguished, formattedTime, - wasComment, isNew, score, nComments, timeUTC); - if (replies != null) { - message.setReplies(replies); - } - - return message; - } - - private static class ParseMessageAsnycTask extends AsyncTask { - - private String response; - private Locale locale; - private ArrayList messages; - private String after; - private int messageType; - private ParseMessageAsyncTaskListener parseMessageAsyncTaskListener; - ParseMessageAsnycTask(String response, Locale locale, int messageType, - ParseMessageAsyncTaskListener parseMessageAsnycTaskListener) { - this.response = response; - this.locale = locale; - this.messageType = messageType; - messages = new ArrayList<>(); - this.parseMessageAsyncTaskListener = parseMessageAsnycTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONArray messageArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - messages = parseMessages(messageArray, locale, messageType); - after = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); - } catch (JSONException e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - parseMessageAsyncTaskListener.parseSuccess(messages, after); - } - } - - private static class ParseSentMessageAsnycTask extends AsyncTask { - - private String response; - private Locale locale; - private Message message; - private String errorMessage; - private boolean parseFailed = false; - private ParseSentMessageAsyncTaskListener parseSentMessageAsyncTaskListener; - - ParseSentMessageAsnycTask(String response, Locale locale, ParseSentMessageAsyncTaskListener parseSentMessageAsyncTaskListener) { - this.response = response; - this.locale = locale; - this.parseSentMessageAsyncTaskListener = parseSentMessageAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject messageJSON = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY) - .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.THINGS_KEY).getJSONObject(0); - message = parseSingleMessage(messageJSON, locale, FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE); - } catch (JSONException e) { - e.printStackTrace(); - errorMessage = parseRepliedMessageErrorMessage(response); - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - parseSentMessageAsyncTaskListener.parseFailed(errorMessage); - } else { - parseSentMessageAsyncTaskListener.parseSuccess(message); - } - } - } - - private static class ParseComposedMessageErrorAsncTask extends AsyncTask { - private String response; - private ParseComposedMessageErrorListener parseComposedMessageErrorListener; - private String errorMessage; - - ParseComposedMessageErrorAsncTask(String response, ParseComposedMessageErrorListener parseComposedMessageErrorListener) { - this.response = response; - this.parseComposedMessageErrorListener = parseComposedMessageErrorListener; - } - - @Override - protected Void doInBackground(Void... voids) { - errorMessage = parseRepliedMessageErrorMessage(response); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (errorMessage == null) { - parseComposedMessageErrorListener.noError(); - } else { - parseComposedMessageErrorListener.error(errorMessage); - } - } - } - - @Nullable - private static String parseRepliedMessageErrorMessage(String response) { - try { - JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); - - if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { - JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) - .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); - if (error.length() != 0) { - String errorString; - if (error.length() >= 2) { - errorString = error.getString(1); - } else { - errorString = error.getString(0); - } - return errorString.substring(0, 1).toUpperCase() + errorString.substring(1); - } else { - return null; - } - } else { - return null; - } - } catch (JSONException e) { - e.printStackTrace(); - } - - return null; - } - - public interface ParseMessageAsyncTaskListener { - void parseSuccess(ArrayList messages, @Nullable String after); - } - - public interface ParseSentMessageAsyncTaskListener { - void parseSuccess(Message message); - void parseFailed(String errorMessage); - } - - public interface ParseComposedMessageErrorListener { - void noError(); - void error(String errorMessage); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReadMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReadMessage.java deleted file mode 100644 index bb8b4030..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReadMessage.java +++ /dev/null @@ -1,43 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class ReadMessage { - public static void readMessage(Retrofit oauthRetrofit, String accessToken, String commaSeparatedFullnames, - ReadMessageListener readMessageListener) { - Map params = new HashMap<>(); - params.put(APIUtils.ID_KEY, commaSeparatedFullnames); - oauthRetrofit.create(RedditAPI.class).readMessage(APIUtils.getOAuthHeader(accessToken), params) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - readMessageListener.readSuccess(); - } else { - readMessageListener.readFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - readMessageListener.readFailed(); - } - }); - } - - public interface ReadMessageListener { - void readSuccess(); - - void readFailed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReplyMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReplyMessage.java deleted file mode 100644 index ca8edcd2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Message/ReplyMessage.java +++ /dev/null @@ -1,58 +0,0 @@ -package ml.docilealligator.infinityforreddit.Message; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class ReplyMessage { - public static void replyMessage(String messageMarkdown, String thingFullname, - Locale locale, Retrofit oauthRetrofit, String accessToken, - ReplyMessageListener replyMessageListener) { - Map headers = APIUtils.getOAuthHeader(accessToken); - Map params = new HashMap<>(); - params.put(APIUtils.API_TYPE_KEY, "json"); - params.put(APIUtils.RETURN_RTJSON_KEY, "true"); - params.put(APIUtils.TEXT_KEY, messageMarkdown); - params.put(APIUtils.THING_ID_KEY, thingFullname); - - oauthRetrofit.create(RedditAPI.class).sendCommentOrReplyToMessage(headers, params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseMessage.parseRepliedMessage(response.body(), locale, new ParseMessage.ParseSentMessageAsyncTaskListener() { - @Override - public void parseSuccess(Message message) { - replyMessageListener.replyMessageSuccess(message); - } - - @Override - public void parseFailed(String errorMessage) { - replyMessageListener.replyMessageFailed(errorMessage); - } - }); - } else { - replyMessageListener.replyMessageFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - replyMessageListener.replyMessageFailed(t.getMessage()); - } - }); - } - - public interface ReplyMessageListener { - void replyMessageSuccess(Message message); - void replyMessageFailed(String errorMessage); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/CreateMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/CreateMultiReddit.java deleted file mode 100644 index 67d11d57..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/CreateMultiReddit.java +++ /dev/null @@ -1,56 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class CreateMultiReddit { - public interface CreateMultiRedditListener { - void success(); - void failed(int errorType); - } - - public static void createMultiReddit(Retrofit oauthRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, - String accessToken, String multipath, String model, - CreateMultiRedditListener createMultiRedditListener) { - Map params = new HashMap<>(); - params.put(APIUtils.MULTIPATH_KEY, multipath); - params.put(APIUtils.MODEL_KEY, model); - oauthRetrofit.create(RedditAPI.class).createMultiReddit(APIUtils.getOAuthHeader(accessToken), - params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseMultiReddit.parseAndSaveMultiReddit(response.body(), redditDataRoomDatabase, - new ParseMultiReddit.ParseMultiRedditListener() { - @Override - public void success() { - createMultiRedditListener.success(); - } - - @Override - public void failed() { - createMultiRedditListener.failed(1); - } - }); - } else { - createMultiRedditListener.failed(response.code()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - createMultiRedditListener.failed(0); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/DeleteMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/DeleteMultiReddit.java deleted file mode 100644 index 39f9f253..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/DeleteMultiReddit.java +++ /dev/null @@ -1,41 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import androidx.annotation.NonNull; - -import ml.docilealligator.infinityforreddit.AsyncTask.DeleteMultiredditInDatabaseAsyncTask; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class DeleteMultiReddit { - public interface DeleteMultiRedditListener { - void success(); - void failed(); - } - - public static void deleteMultiReddit(Retrofit oauthRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, - String accessToken, String accountName, String multipath, - DeleteMultiRedditListener deleteMultiRedditListener) { - oauthRetrofit.create(RedditAPI.class).deleteMultiReddit(APIUtils.getOAuthHeader(accessToken), - multipath).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new DeleteMultiredditInDatabaseAsyncTask(redditDataRoomDatabase, accountName, multipath, - deleteMultiRedditListener::success).execute(); - } else { - deleteMultiRedditListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - deleteMultiRedditListener.failed(); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/EditMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/EditMultiReddit.java deleted file mode 100644 index 8f16398b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/EditMultiReddit.java +++ /dev/null @@ -1,43 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class EditMultiReddit { - public interface EditMultiRedditListener { - void success(); - void failed(); - } - - public static void editMultiReddit(Retrofit oauthRetrofit, String accessToken, String multipath, String model, - EditMultiRedditListener editMultiRedditListener) { - Map params = new HashMap<>(); - params.put(APIUtils.MULTIPATH_KEY, multipath); - params.put(APIUtils.MODEL_KEY, model); - oauthRetrofit.create(RedditAPI.class).updateMultiReddit(APIUtils.getOAuthHeader(accessToken), - params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - editMultiRedditListener.success(); - } else { - editMultiRedditListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - editMultiRedditListener.failed(); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FavoriteMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FavoriteMultiReddit.java deleted file mode 100644 index 8c976245..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FavoriteMultiReddit.java +++ /dev/null @@ -1,49 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.AsyncTask.InsertMultiRedditAsyncTask; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FavoriteMultiReddit { - public interface FavoriteMultiRedditListener { - void success(); - void failed(); - } - - public static void favoriteMultiReddit(Retrofit oauthRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, - String accessToken, boolean makeFavorite, - MultiReddit multiReddit, FavoriteMultiRedditListener favoriteMultiRedditListener) { - Map params = new HashMap<>(); - params.put(APIUtils.MULTIPATH_KEY, multiReddit.getPath()); - params.put(APIUtils.MAKE_FAVORITE_KEY, String.valueOf(makeFavorite)); - params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); - oauthRetrofit.create(RedditAPI.class).favoriteMultiReddit(APIUtils.getOAuthHeader(accessToken), - params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - multiReddit.setFavorite(makeFavorite); - new InsertMultiRedditAsyncTask(redditDataRoomDatabase, multiReddit, - favoriteMultiRedditListener::success).execute(); - } else { - favoriteMultiRedditListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - favoriteMultiRedditListener.failed(); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMultiRedditInfo.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMultiRedditInfo.java deleted file mode 100644 index 839f69f8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMultiRedditInfo.java +++ /dev/null @@ -1,101 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import android.os.AsyncTask; - -import androidx.annotation.NonNull; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchMultiRedditInfo { - - public interface FetchMultiRedditInfoListener { - void success(MultiReddit multiReddit); - void failed(); - } - - public static void fetchMultiRedditInfo(Retrofit retrofit, String accessToken, String multipath, - FetchMultiRedditInfoListener fetchMultiRedditInfoListener) { - retrofit.create(RedditAPI.class).getMultiRedditInfo(APIUtils.getOAuthHeader(accessToken), multipath).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseMultiRedditInfoAsyncTask(response.body(), fetchMultiRedditInfoListener).execute(); - } else { - fetchMultiRedditInfoListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchMultiRedditInfoListener.failed(); - } - }); - } - - private static class ParseMultiRedditInfoAsyncTask extends AsyncTask { - - private String response; - private FetchMultiRedditInfoListener fetchMultiRedditInfoListener; - private MultiReddit multiReddit; - private boolean parseFailed = false; - - public ParseMultiRedditInfoAsyncTask(String response, FetchMultiRedditInfoListener fetchMultiRedditInfoListener) { - this.response = response; - this.fetchMultiRedditInfoListener = fetchMultiRedditInfoListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject object = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY); - String path = object.getString(JSONUtils.PATH_KEY); - String displayName = object.getString(JSONUtils.DISPLAY_NAME_KEY); - String name = object.getString(JSONUtils.NAME_KEY); - String description = object.getString(JSONUtils.DESCRIPTION_MD_KEY); - String copiedFrom = object.getString(JSONUtils.COPIED_FROM_KEY); - String iconUrl = object.getString(JSONUtils.ICON_URL_KEY); - String visibility = object.getString(JSONUtils.VISIBILITY_KEY); - String owner = object.getString(JSONUtils.OWNER_KEY); - int nSubscribers = object.getInt(JSONUtils.NUM_SUBSCRIBERS_KEY); - long createdUTC = object.getLong(JSONUtils.CREATED_UTC_KEY); - boolean over18 = object.getBoolean(JSONUtils.OVER_18_KEY); - boolean isSubscriber = object.getBoolean(JSONUtils.IS_SUBSCRIBER_KEY); - boolean isFavorite = object.getBoolean(JSONUtils.IS_FAVORITED_KEY); - ArrayList subreddits = new ArrayList<>(); - JSONArray subredditsArray = object.getJSONArray(JSONUtils.SUBREDDITS_KEY); - for (int i = 0; i < subredditsArray.length(); i++) { - subreddits.add(subredditsArray.getJSONObject(i).getString(JSONUtils.NAME_KEY)); - } - - multiReddit = new MultiReddit(path, displayName, name, description, copiedFrom, iconUrl, - visibility, owner, nSubscribers, createdUTC, over18, isSubscriber, isFavorite, - subreddits); - } catch (JSONException e) { - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - fetchMultiRedditInfoListener.failed(); - } else { - fetchMultiRedditInfoListener.success(multiReddit); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMyMultiReddits.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMyMultiReddits.java deleted file mode 100644 index 383c8f23..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/FetchMyMultiReddits.java +++ /dev/null @@ -1,48 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import androidx.annotation.NonNull; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchMyMultiReddits { - public interface FetchMyMultiRedditsListener { - void success(ArrayList multiReddits); - void failed(); - } - - public static void fetchMyMultiReddits(Retrofit oauthRetrofit, String accessToken, FetchMyMultiRedditsListener fetchMyMultiRedditsListener) { - oauthRetrofit.create(RedditAPI.class) - .getMyMultiReddits(APIUtils.getOAuthHeader(accessToken)).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseMultiReddit.parseMultiRedditsList(response.body(), new ParseMultiReddit.ParseMultiRedditsListListener() { - @Override - public void success(ArrayList multiReddits) { - fetchMyMultiRedditsListener.success(multiReddits); - } - - @Override - public void failed() { - fetchMyMultiRedditsListener.failed(); - } - }); - } else { - fetchMyMultiRedditsListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchMyMultiRedditsListener.failed(); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiReddit.java deleted file mode 100644 index 71b14ad7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiReddit.java +++ /dev/null @@ -1,258 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.ForeignKey; -import androidx.room.Ignore; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.Account.Account; - -@Entity(tableName = "multi_reddits", primaryKeys = {"path", "username"}, - foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", - childColumns = "username", onDelete = ForeignKey.CASCADE)) -public class MultiReddit implements Parcelable { - @NonNull - @ColumnInfo(name = "path") - private String path; - @NonNull - @ColumnInfo(name = "display_name") - private String displayName; - @NonNull - @ColumnInfo(name = "name") - private String name; - @ColumnInfo(name = "description") - private String description; - @ColumnInfo(name = "copied_from") - private String copiedFrom; - @ColumnInfo(name = "icon_url") - private String iconUrl; - @ColumnInfo(name = "visibility") - private String visibility; - @NonNull - @ColumnInfo(name = "username") - private String owner; - @ColumnInfo(name = "n_subscribers") - private int nSubscribers; - @ColumnInfo(name = "created_UTC") - private long createdUTC; - @ColumnInfo(name = "over_18") - private boolean over18; - @ColumnInfo(name = "is_subscriber") - private boolean isSubscriber; - @ColumnInfo(name = "is_favorite") - private boolean isFavorite; - @Ignore - private ArrayList subreddits; - - public MultiReddit(@NonNull String path, @NonNull String displayName, @NonNull String name, - String description, String copiedFrom, String iconUrl, String visibility, - @NonNull String owner, int nSubscribers, long createdUTC, boolean over18, - boolean isSubscriber, boolean isFavorite) { - this.displayName = displayName; - this.name = name; - this.description = description; - this.copiedFrom = copiedFrom; - this.iconUrl = iconUrl; - this.visibility = visibility; - this.path = path; - this.owner = owner; - this.nSubscribers = nSubscribers; - this.createdUTC = createdUTC; - this.over18 = over18; - this.isSubscriber = isSubscriber; - this.isFavorite = isFavorite; - } - - public MultiReddit(@NonNull String path, @NonNull String displayName, @NonNull String name, - String description, String copiedFrom, String iconUrl, String visibility, - @NonNull String owner, int nSubscribers, long createdUTC, boolean over18, - boolean isSubscriber, boolean isFavorite, ArrayList subreddits) { - this.displayName = displayName; - this.name = name; - this.description = description; - this.copiedFrom = copiedFrom; - this.iconUrl = iconUrl; - this.visibility = visibility; - this.path = path; - this.owner = owner; - this.nSubscribers = nSubscribers; - this.createdUTC = createdUTC; - this.over18 = over18; - this.isSubscriber = isSubscriber; - this.isFavorite = isFavorite; - this.subreddits = subreddits; - } - - protected MultiReddit(Parcel in) { - path = in.readString(); - displayName = in.readString(); - name = in.readString(); - description = in.readString(); - copiedFrom = in.readString(); - iconUrl = in.readString(); - visibility = in.readString(); - owner = in.readString(); - nSubscribers = in.readInt(); - createdUTC = in.readLong(); - over18 = in.readByte() != 0; - isSubscriber = in.readByte() != 0; - isFavorite = in.readByte() != 0; - subreddits = in.readArrayList(MultiReddit.class.getClassLoader()); - } - - public static final Creator CREATOR = new Creator() { - @Override - public MultiReddit createFromParcel(Parcel in) { - return new MultiReddit(in); - } - - @Override - public MultiReddit[] newArray(int size) { - return new MultiReddit[size]; - } - }; - - @NonNull - public String getPath() { - return path; - } - - public void setPath(@NonNull String path) { - this.path = path; - } - - @NonNull - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(@NonNull String displayName) { - this.displayName = displayName; - } - - @NonNull - public String getName() { - return name; - } - - public void setName(@NonNull String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getCopiedFrom() { - return copiedFrom; - } - - public void setCopiedFrom(String copiedFrom) { - this.copiedFrom = copiedFrom; - } - - public String getIconUrl() { - return iconUrl; - } - - public void setIconUrl(String iconUrl) { - this.iconUrl = iconUrl; - } - - public String getVisibility() { - return visibility; - } - - public void setVisibility(String visibility) { - this.visibility = visibility; - } - - public String getOwner() { - return owner; - } - - public void setOwner(String owner) { - this.owner = owner; - } - - public int getNSubscribers() { - return nSubscribers; - } - - public void setNSubscribers(int nSubscribers) { - this.nSubscribers = nSubscribers; - } - - public long getCreatedUTC() { - return createdUTC; - } - - public void setCreatedUTC(long createdUTC) { - this.createdUTC = createdUTC; - } - - public boolean isOver18() { - return over18; - } - - public void setOver18(boolean over18) { - this.over18 = over18; - } - - public boolean isSubscriber() { - return isSubscriber; - } - - public void setSubscriber(boolean subscriber) { - isSubscriber = subscriber; - } - - public boolean isFavorite() { - return isFavorite; - } - - public void setFavorite(boolean favorite) { - isFavorite = favorite; - } - - public ArrayList getSubreddits() { - return subreddits; - } - - public void setSubreddits(ArrayList subreddits) { - this.subreddits = subreddits; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(path); - parcel.writeString(displayName); - parcel.writeString(name); - parcel.writeString(description); - parcel.writeString(copiedFrom); - parcel.writeString(iconUrl); - parcel.writeString(visibility); - parcel.writeString(owner); - parcel.writeInt(nSubscribers); - parcel.writeLong(createdUTC); - parcel.writeByte((byte) (over18 ? 1 : 0)); - parcel.writeByte((byte) (isSubscriber ? 1 : 0)); - parcel.writeByte((byte) (isFavorite ? 1 : 0)); - parcel.writeStringList(subreddits); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditDao.java deleted file mode 100644 index 7d3654c8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditDao.java +++ /dev/null @@ -1,33 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -import java.util.List; - -@Dao -public interface MultiRedditDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(MultiReddit MultiReddit); - - @Query("SELECT * FROM multi_reddits WHERE username = :username ORDER BY name COLLATE NOCASE ASC") - LiveData> getAllMultiReddits(String username); - - @Query("SELECT * FROM multi_reddits WHERE username = :username ORDER BY name COLLATE NOCASE ASC") - List getAllMultiRedditsList(String username); - - @Query("SELECT * FROM multi_reddits WHERE username = :username AND is_favorite ORDER BY name COLLATE NOCASE ASC") - LiveData> getAllFavoriteMultiReddits(String username); - - @Query("SELECT * FROM multi_reddits WHERE name = :name AND username = :username COLLATE NOCASE LIMIT 1") - MultiReddit getMultiReddit(String name, String username); - - @Query("DELETE FROM multi_reddits WHERE name = :name AND username = :username") - void deleteMultiReddit(String name, String username); - - @Query("DELETE FROM multi_reddits WHERE username = :username") - void deleteAllUserMultiReddits(String username); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditJSONModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditJSONModel.java deleted file mode 100644 index 665a9092..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditJSONModel.java +++ /dev/null @@ -1,38 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import com.google.gson.Gson; - -import java.util.ArrayList; - -public class MultiRedditJSONModel { - private String display_name; - private String description_md; - private String visibility; - private SubredditInMultiReddit[] subreddits; - - public MultiRedditJSONModel() {} - - public MultiRedditJSONModel(String display_name, String description_md, boolean isPrivate, - ArrayList subreddits) { - this.display_name = display_name; - this.description_md = description_md; - if (isPrivate) { - visibility = "private"; - } else { - visibility = "public"; - } - - if (subreddits != null) { - this.subreddits = new SubredditInMultiReddit[subreddits.size()]; - for (int i = 0; i < subreddits.size(); i++) { - SubredditInMultiReddit subredditInMultiReddit = new SubredditInMultiReddit(subreddits.get(i)); - this.subreddits[i] = subredditInMultiReddit; - } - } - } - - public String createJSONModel() { - Gson gson = new Gson(); - return gson.toJson(this); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditRepository.java deleted file mode 100644 index 860cdd43..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditRepository.java +++ /dev/null @@ -1,26 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import androidx.lifecycle.LiveData; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class MultiRedditRepository { - private LiveData> mAllMultiReddits; - private LiveData> mAllFavoriteMultiReddits; - - MultiRedditRepository(RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - MultiRedditDao multiRedditDao = redditDataRoomDatabase.multiRedditDao(); - mAllMultiReddits = multiRedditDao.getAllMultiReddits(accountName); - mAllFavoriteMultiReddits = multiRedditDao.getAllFavoriteMultiReddits(accountName); - } - - LiveData> getAllMultiReddits() { - return mAllMultiReddits; - } - - LiveData> getAllFavoriteMultiReddits() { - return mAllFavoriteMultiReddits; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditViewModel.java deleted file mode 100644 index 14f42bee..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/MultiRedditViewModel.java +++ /dev/null @@ -1,52 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class MultiRedditViewModel extends AndroidViewModel { - private MultiRedditRepository mMultiRedditRepository; - private LiveData> mAllMultiReddits; - private LiveData> mAllFavoriteMultiReddits; - - public MultiRedditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - super(application); - mMultiRedditRepository = new MultiRedditRepository(redditDataRoomDatabase, accountName); - mAllMultiReddits = mMultiRedditRepository.getAllMultiReddits(); - mAllFavoriteMultiReddits = mMultiRedditRepository.getAllFavoriteMultiReddits(); - } - - public LiveData> getAllMultiReddits() { - return mAllMultiReddits; - } - - public LiveData> getAllFavoriteMultiReddits() { - return mAllFavoriteMultiReddits; - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Application mApplication; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private String mAccountName; - - public Factory(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - mApplication = application; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mAccountName = accountName; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new MultiRedditViewModel(mApplication, mRedditDataRoomDatabase, mAccountName); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/ParseMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/ParseMultiReddit.java deleted file mode 100644 index 635a9646..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/ParseMultiReddit.java +++ /dev/null @@ -1,138 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -import android.os.AsyncTask; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; - -public class ParseMultiReddit { - interface ParseMultiRedditsListListener { - void success(ArrayList multiReddits); - void failed(); - } - - interface ParseMultiRedditListener { - void success(); - void failed(); - } - - public static void parseMultiRedditsList(String response, ParseMultiRedditsListListener parseMultiRedditsListListener) { - new ParseMultiRedditsListAsyncTask(response, parseMultiRedditsListListener).execute(); - } - - public static void parseAndSaveMultiReddit(String response, RedditDataRoomDatabase redditDataRoomDatabase, - ParseMultiRedditListener parseMultiRedditListener) { - new ParseAndSaveMultiRedditAsyncTask(response, redditDataRoomDatabase, parseMultiRedditListener).execute(); - } - - private static MultiReddit parseMultiReddit(JSONObject singleMultiRedditJSON) throws JSONException { - String displayName = singleMultiRedditJSON.getString(JSONUtils.DISPLAY_NAME_KEY); - String name = singleMultiRedditJSON.getString(JSONUtils.NAME_KEY); - String description = singleMultiRedditJSON.getString(JSONUtils.DESCRIPTION_MD_KEY); - int nSubscribers = singleMultiRedditJSON.getInt(JSONUtils.NUM_SUBSCRIBERS_KEY); - String copiedFrom = singleMultiRedditJSON.getString(JSONUtils.COPIED_FROM_KEY); - String iconUrl = singleMultiRedditJSON.getString(JSONUtils.ICON_URL_KEY); - long createdUTC = singleMultiRedditJSON.getLong(JSONUtils.CREATED_UTC_KEY); - String visibility = singleMultiRedditJSON.getString(JSONUtils.VISIBILITY_KEY); - boolean over18 = singleMultiRedditJSON.getBoolean(JSONUtils.OVER_18_KEY); - String path = singleMultiRedditJSON.getString(JSONUtils.PATH_KEY); - String owner = singleMultiRedditJSON.getString(JSONUtils.OWNER_KEY); - boolean isSubscriber = singleMultiRedditJSON.getBoolean(JSONUtils.IS_SUBSCRIBER_KEY); - boolean isFavorited = singleMultiRedditJSON.getBoolean(JSONUtils.IS_FAVORITED_KEY); - - JSONArray subredditsArray = singleMultiRedditJSON.getJSONArray(JSONUtils.SUBREDDITS_KEY); - ArrayList subreddits = new ArrayList<>(); - for (int j = 0; j < subredditsArray.length(); j++) { - subreddits.add(subredditsArray.getJSONObject(j).getString(JSONUtils.NAME_KEY)); - } - - return new MultiReddit(path, displayName, name, description, copiedFrom, - iconUrl, visibility, owner, nSubscribers, createdUTC, over18, isSubscriber, - isFavorited, subreddits); - } - - private static class ParseMultiRedditsListAsyncTask extends AsyncTask { - private JSONArray arrayResponse; - private boolean parseFailed; - private ArrayList multiReddits; - private ParseMultiRedditsListListener parseMultiRedditsListListener; - - ParseMultiRedditsListAsyncTask(String response, - ParseMultiRedditsListListener parseMultiRedditsListListener) { - this.parseMultiRedditsListListener = parseMultiRedditsListListener; - try { - arrayResponse = new JSONArray(response); - multiReddits = new ArrayList<>(); - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - @Override - protected Void doInBackground(Void... voids) { - if (!parseFailed) { - for (int i = 0; i < arrayResponse.length(); i++) { - try { - multiReddits.add(parseMultiReddit(arrayResponse.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY))); - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (!parseFailed) { - parseMultiRedditsListListener.success(multiReddits); - } else { - parseMultiRedditsListListener.failed(); - } - } - } - - private static class ParseAndSaveMultiRedditAsyncTask extends AsyncTask { - private String response; - private RedditDataRoomDatabase redditDataRoomDatabase; - private MultiReddit multiReddit; - private ParseMultiRedditListener parseMultiRedditListener; - - ParseAndSaveMultiRedditAsyncTask(String response, RedditDataRoomDatabase redditDataRoomDatabase, - ParseMultiRedditListener parseMultiRedditListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.parseMultiRedditListener = parseMultiRedditListener; - this.response = response; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - multiReddit = parseMultiReddit(new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY)); - redditDataRoomDatabase.multiRedditDao().insert(multiReddit); - } catch (JSONException e) { - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (multiReddit != null) { - parseMultiRedditListener.success(); - } else { - parseMultiRedditListener.failed(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/SubredditInMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/SubredditInMultiReddit.java deleted file mode 100644 index 34a1e638..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/MultiReddit/SubredditInMultiReddit.java +++ /dev/null @@ -1,11 +0,0 @@ -package ml.docilealligator.infinityforreddit.MultiReddit; - -public class SubredditInMultiReddit { - String name; - - SubredditInMultiReddit() {} - - SubredditInMultiReddit(String subredditName) { - name = subredditName; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java index 40f40146..68efd8c0 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ParseSubscribedThing.java @@ -8,10 +8,10 @@ import org.json.JSONObject; import java.util.ArrayList; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; class ParseSubscribedThing { static void parseSubscribedSubreddits(String response, String accountName, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java deleted file mode 100644 index 2d5ec30e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchPost.java +++ /dev/null @@ -1,95 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import androidx.annotation.NonNull; - -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchPost { - public static void fetchPost(Retrofit retrofit, String id, String accessToken, Locale locale, FetchPostListener fetchPostListener) { - Call postCall; - if (accessToken == null) { - postCall = retrofit.create(RedditAPI.class).getPost(id); - } else { - postCall = retrofit.create(RedditAPI.class).getPostOauth(id, APIUtils.getOAuthHeader(accessToken)); - } - postCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { - @Override - public void onParsePostSuccess(Post post) { - fetchPostListener.fetchPostSuccess(post); - } - - @Override - public void onParsePostFail() { - fetchPostListener.fetchPostFailed(); - } - }); - } else { - fetchPostListener.fetchPostFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchPostListener.fetchPostFailed(); - } - }); - } - - public static void fetchRandomPost(Retrofit retrofit, boolean isNSFW, FetchRandomPostListener fetchRandomPostListener) { - Call call; - if (isNSFW) { - call = retrofit.create(RedditAPI.class).getRandomNSFWPost(); - } else { - call = retrofit.create(RedditAPI.class).getRandomPost(); - } - - call.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParsePost.ParseRandomPostAsyncTask(response.body(), isNSFW, new ParsePost.ParseRandomPostListener() { - - @Override - public void onParseRandomPostSuccess(String postId, String subredditName) { - fetchRandomPostListener.fetchRandomPostSuccess(postId, subredditName); - } - - @Override - public void onParseRandomPostFailed() { - fetchRandomPostListener.fetchRandomPostFailed(); - } - }).execute(); - } else { - fetchRandomPostListener.fetchRandomPostFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchRandomPostListener.fetchRandomPostFailed(); - } - }); - } - - public interface FetchPostListener { - void fetchPostSuccess(Post post); - - void fetchPostFailed(); - } - - public interface FetchRandomPostListener { - void fetchRandomPostSuccess(String postId, String subredditName); - void fetchRandomPostFailed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchRemovedPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchRemovedPost.java deleted file mode 100644 index dd641e6e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/FetchRemovedPost.java +++ /dev/null @@ -1,159 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import android.net.Uri; -import android.os.AsyncTask; -import android.text.Html; - -import androidx.annotation.NonNull; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.API.PushshiftAPI; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchRemovedPost { - - public static void fetchRemovedPost(Retrofit retrofit, Post post, FetchRemovedPostListener listener) { - retrofit.create(PushshiftAPI.class).getRemovedPost(post.getId()) - .enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParsePostAsyncTask(response.body(), post, listener).execute(); - } else { - listener.fetchFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - t.printStackTrace(); - listener.fetchFailed(); - } - }); - } - - private static Post parseRemovedPost(JSONObject result, Post post) throws JSONException { - String id = result.getString(JSONUtils.ID_KEY); - String author = result.getString(JSONUtils.AUTHOR_KEY); - String title = result.getString(JSONUtils.TITLE_KEY); - String body = Utils.modifyMarkdown(result.getString(JSONUtils.SELFTEXT_KEY).trim()); - - if ( id.equals(post.getId()) && - (!author.equals(post.getAuthor()) || - foundSelfText(post.getSelfText(), body)) - ) { - post.setAuthor(author); - post.setTitle(title); - post.setSelfText(body); - post.setSelfTextPlain(""); - post.setSelfTextPlainTrimmed(""); - - String url = result.optString(JSONUtils.URL_KEY); - - if (url.endsWith("gif") || url.endsWith("mp4")) { - post.setVideoUrl(url); - post.setVideoDownloadUrl(url); - } else if (post.getPostType() == Post.VIDEO_TYPE || post.getPostType() == Post.GIF_TYPE) { - JSONObject redditVideoObject = result.getJSONObject("secure_media").getJSONObject(JSONUtils.REDDIT_VIDEO_KEY); - String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString(); - String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY); - - post.setVideoUrl(videoUrl); - post.setVideoDownloadUrl(videoDownloadUrl); - } else if (post.getPostType() == Post.LINK_TYPE) { - post.setUrl(url); - } - - if (post.getPostType() == Post.VIDEO_TYPE) { - try { - Uri uri = Uri.parse(url); - String authority = uri.getAuthority(); - if (authority != null && (authority.contains("gfycat.com") || authority.contains("redgifs.com"))) { - post.setPostType(Post.LINK_TYPE); - post.setUrl(url); - } - } catch (IllegalArgumentException ignore) { - } - } - - if (!result.isNull("thumbnail")) { - ArrayList previews = post.getPreviews(); - if (previews != null && !previews.isEmpty()) { - if (previews.size() >= 2) { - Post.Preview preview = previews.get(1); - preview.setPreviewUrl(result.getString("thumbnail")); - previews.set(1, preview); - } else { - Post.Preview preview = previews.get(0); - preview.setPreviewUrl(result.getString("thumbnail")); - previews.set(0, preview); - } - } else { - Post.Preview preview = new Post.Preview(result.getString("thumbnail"), 1, 1); - preview.setPreviewUrl(result.getString("thumbnail")); - ArrayList newPreviews = new ArrayList<>(); - newPreviews.add(preview); - post.setPreviews(newPreviews); - } - } - - return post; - } else { - return null; - } - } - - private static boolean foundSelfText(String oldText, String newText) { - return !(newText.equals("[deleted]") || newText.equals("[removed]")) && - !newText.equals(oldText); - } - - public interface FetchRemovedPostListener { - void fetchSuccess(Post post); - - void fetchFailed(); - } - - private static class ParsePostAsyncTask extends AsyncTask { - - private String responseBody; - private FetchRemovedPostListener listener; - Post post; - - public ParsePostAsyncTask(String responseBody, Post post, FetchRemovedPostListener listener) { - this.responseBody = responseBody; - this.post = post; - this.listener = listener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject postJson = new JSONObject(responseBody).getJSONArray(JSONUtils.DATA_KEY).getJSONObject(0); - post = parseRemovedPost(postJson, post); - } catch (JSONException e) { - e.printStackTrace(); - post = null; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (post != null) - listener.fetchSuccess(post); - else - listener.fetchFailed(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java deleted file mode 100644 index c71fd5a1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/HidePost.java +++ /dev/null @@ -1,63 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class HidePost { - public static void hidePost(Retrofit oauthRetrofit, String accessToken, String fullname, - HidePostListener hidePostListener) { - Map params = new HashMap<>(); - params.put(APIUtils.ID_KEY, fullname); - oauthRetrofit.create(RedditAPI.class).hide(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - hidePostListener.success(); - } else { - hidePostListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - hidePostListener.failed(); - } - }); - } - - public static void unhidePost(Retrofit oauthRetrofit, String accessToken, String fullname, - HidePostListener hidePostListener) { - Map params = new HashMap<>(); - params.put(APIUtils.ID_KEY, fullname); - oauthRetrofit.create(RedditAPI.class).unhide(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - hidePostListener.success(); - } else { - hidePostListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - hidePostListener.failed(); - } - }); - } - - public interface HidePostListener { - void success(); - - void failed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java deleted file mode 100644 index 64c1ad98..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/ParsePost.java +++ /dev/null @@ -1,666 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import android.net.Uri; -import android.os.AsyncTask; -import android.text.Html; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; - -import ml.docilealligator.infinityforreddit.Fragment.PostFragment; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -/** - * Created by alex on 3/21/18. - */ - -public class ParsePost { - public static void parsePosts(String response, int nPosts, int filter, boolean nsfw, - ParsePostsListingListener parsePostsListingListener) { - new ParsePostDataAsyncTask(response, nPosts, filter, nsfw, parsePostsListingListener).execute(); - } - - public static void parsePosts(String response, int nPosts, int filter, boolean nsfw, - List subredditFilterList, ParsePostsListingListener parsePostsListingListener) { - new ParsePostDataAsyncTask(response, nPosts, filter, nsfw, subredditFilterList, parsePostsListingListener).execute(); - } - - public static void parsePost(String response, ParsePostListener parsePostListener) { - new ParsePostDataAsyncTask(response, true, parsePostListener).execute(); - } - - private static Post parseBasicData(JSONObject data) throws JSONException { - String id = data.getString(JSONUtils.ID_KEY); - String fullName = data.getString(JSONUtils.NAME_KEY); - String subredditName = data.getString(JSONUtils.SUBREDDIT_KEY); - String subredditNamePrefixed = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); - String author = data.getString(JSONUtils.AUTHOR_KEY); - StringBuilder authorFlairHTMLBuilder = new StringBuilder(); - if (data.has(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY)) { - JSONArray flairArray = data.getJSONArray(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY); - for (int i = 0; i < flairArray.length(); i++) { - JSONObject flairObject = flairArray.getJSONObject(i); - String e = flairObject.getString(JSONUtils.E_KEY); - if (e.equals("text")) { - authorFlairHTMLBuilder.append(flairObject.getString(JSONUtils.T_KEY)); - } else if (e.equals("emoji")) { - authorFlairHTMLBuilder.append(""); - } - } - } - String authorFlair = data.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) ? "" : data.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY); - long postTime = data.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; - String title = data.getString(JSONUtils.TITLE_KEY); - int score = data.getInt(JSONUtils.SCORE_KEY); - int voteType; - int nComments = data.getInt(JSONUtils.NUM_COMMENTS_KEY); - boolean hidden = data.getBoolean(JSONUtils.HIDDEN_KEY); - boolean spoiler = data.getBoolean(JSONUtils.SPOILER_KEY); - boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); - boolean stickied = data.getBoolean(JSONUtils.STICKIED_KEY); - boolean archived = data.getBoolean(JSONUtils.ARCHIVED_KEY); - boolean locked = data.getBoolean(JSONUtils.LOCKEC_KEY); - boolean saved = data.getBoolean(JSONUtils.SAVED_KEY); - StringBuilder postFlairHTMLBuilder = new StringBuilder(); - String flair = ""; - if (data.has(JSONUtils.LINK_FLAIR_RICHTEXT_KEY)) { - JSONArray flairArray = data.getJSONArray(JSONUtils.LINK_FLAIR_RICHTEXT_KEY); - for (int i = 0; i < flairArray.length(); i++) { - JSONObject flairObject = flairArray.getJSONObject(i); - String e = flairObject.getString(JSONUtils.E_KEY); - if (e.equals("text")) { - postFlairHTMLBuilder.append(Html.escapeHtml(flairObject.getString(JSONUtils.T_KEY))); - } else if (e.equals("emoji")) { - postFlairHTMLBuilder.append(""); - } - } - flair = postFlairHTMLBuilder.toString(); - } - - if (flair.equals("") && data.has(JSONUtils.LINK_FLAIR_TEXT_KEY) && !data.isNull(JSONUtils.LINK_FLAIR_TEXT_KEY)) { - flair = data.getString(JSONUtils.LINK_FLAIR_TEXT_KEY); - } - - StringBuilder awardingsBuilder = new StringBuilder(); - JSONArray awardingsArray = data.getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); - int nAwards = 0; - for (int i = 0; i < awardingsArray.length(); i++) { - JSONObject award = awardingsArray.getJSONObject(i); - int count = award.getInt(JSONUtils.COUNT_KEY); - nAwards += count; - JSONArray icons = award.getJSONArray(JSONUtils.RESIZED_ICONS_KEY); - if (icons.length() > 4) { - String iconUrl = icons.getJSONObject(3).getString(JSONUtils.URL_KEY); - awardingsBuilder.append(" ").append("x").append(count).append(" "); - } else if (icons.length() > 0) { - String iconUrl = icons.getJSONObject(icons.length() - 1).getString(JSONUtils.URL_KEY); - awardingsBuilder.append(" ").append("x").append(count).append(" "); - } - } - - if (data.isNull(JSONUtils.LIKES_KEY)) { - voteType = 0; - } else { - voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; - score -= voteType; - } - - String permalink = Html.fromHtml(data.getString(JSONUtils.PERMALINK_KEY)).toString(); - - ArrayList previews = new ArrayList<>(); - if (data.has(JSONUtils.PREVIEW_KEY)) { - JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); - String previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); - int previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); - int previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); - previews.add(new Post.Preview(previewUrl, previewWidth, previewHeight)); - - JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY); - for (int i = 0; i < thumbnailPreviews.length(); i++) { - JSONObject thumbnailPreview = thumbnailPreviews.getJSONObject(i); - String thumbnailPreviewUrl = thumbnailPreview.getString(JSONUtils.URL_KEY); - int thumbnailPreviewWidth = thumbnailPreview.getInt(JSONUtils.WIDTH_KEY); - int thumbnailPreviewHeight = thumbnailPreview.getInt(JSONUtils.HEIGHT_KEY); - - previews.add(new Post.Preview(thumbnailPreviewUrl, thumbnailPreviewWidth, thumbnailPreviewHeight)); - } - } - if (data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { - //Cross post - data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); - Post crosspostParent = parseBasicData(data); - Post post = parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, - author, authorFlair, authorFlairHTMLBuilder.toString(), - postTime, title, previews, - score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, - spoiler, nsfw, stickied, archived, locked, saved, true); - post.setCrosspostParentId(crosspostParent.getId()); - return post; - } else { - return parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, - author, authorFlair, authorFlairHTMLBuilder.toString(), - postTime, title, previews, - score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, - spoiler, nsfw, stickied, archived, locked, saved, false); - } - } - - private static Post parseData(JSONObject data, String permalink, String id, String fullName, - String subredditName, String subredditNamePrefixed, String author, - String authorFlair, String authorFlairHTML, - long postTimeMillis, String title, ArrayList previews, - int score, int voteType, int nComments, String flair, - String awards, int nAwards, boolean hidden, boolean spoiler, - boolean nsfw, boolean stickied, boolean archived, boolean locked, - boolean saved, boolean isCrosspost) throws JSONException { - Post post; - - boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); - String url = Html.fromHtml(data.getString(JSONUtils.URL_KEY)).toString(); - - if (!data.has(JSONUtils.PREVIEW_KEY) && previews.isEmpty()) { - if (url.contains(permalink)) { - //Text post - int postType = Post.TEXT_TYPE; - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, - title, permalink, score, postType, voteType, nComments, flair, awards, nAwards, - hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost); - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - if (data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { - post.setSelfTextPlainTrimmed(""); - } else { - String selfTextPlain = Utils.trimTrailingWhitespace( - Html.fromHtml(data.getString(JSONUtils.SELFTEXT_HTML_KEY))).toString(); - post.setSelfTextPlain(selfTextPlain); - if (selfTextPlain.length() > 250) { - selfTextPlain = selfTextPlain.substring(0, 250); - } - post.setSelfTextPlainTrimmed(selfTextPlain); - } - } - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - int postType = Post.IMAGE_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, - locked, saved, isCrosspost); - - if (previews.isEmpty()) { - previews.add(new Post.Preview(url, 0, 0)); - } - post.setPreviews(previews); - } else { - //No preview link post - int postType = Post.NO_PREVIEW_LINK_TYPE; - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, - title, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, - archived, locked, saved, isCrosspost); - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - } - } - } - } else { - if (previews.isEmpty()) { - if (data.has(JSONUtils.PREVIEW_KEY)) { - JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); - String previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); - int previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); - int previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); - previews.add(new Post.Preview(previewUrl, previewWidth, previewHeight)); - - JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY); - for (int i = 0; i < thumbnailPreviews.length(); i++) { - JSONObject thumbnailPreview = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY).getJSONObject(2); - String thumbnailPreviewUrl = thumbnailPreview.getString(JSONUtils.URL_KEY); - int thumbnailPreviewWidth = thumbnailPreview.getInt(JSONUtils.WIDTH_KEY); - int thumbnailPreviewHeight = thumbnailPreview.getInt(JSONUtils.HEIGHT_KEY); - - previews.add(new Post.Preview(thumbnailPreviewUrl, thumbnailPreviewWidth, thumbnailPreviewHeight)); - } - } - } - - if (isVideo) { - //Video post - JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY); - int postType = Post.VIDEO_TYPE; - String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString(); - String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY); - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, - saved, isCrosspost); - - post.setPreviews(previews); - post.setVideoUrl(videoUrl); - post.setVideoDownloadUrl(videoDownloadUrl); - } else if (data.has(JSONUtils.PREVIEW_KEY)) { - if (data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) { - //Gif video post (HLS) - int postType = Post.VIDEO_TYPE; - String videoUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY) - .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.HLS_URL_KEY)).toString(); - String videoDownloadUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY) - .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.FALLBACK_URL_KEY); - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, - locked, saved, isCrosspost); - post.setPreviews(previews); - post.setVideoUrl(videoUrl); - post.setVideoDownloadUrl(videoDownloadUrl); - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - int postType = Post.IMAGE_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, - title, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, - stickied, archived, locked, saved, isCrosspost); - - if (previews.isEmpty()) { - previews.add(new Post.Preview(url, 0, 0)); - } - post.setPreviews(previews); - } else if (url.endsWith("gif")){ - //Gif post - int postType = Post.GIF_TYPE; - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, - title, url, permalink, score, - postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, - nsfw, stickied, archived, locked, saved, isCrosspost); - - post.setPreviews(previews); - post.setVideoUrl(url); - } else if (url.endsWith("mp4")) { - //Video post - int postType = Post.VIDEO_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, - archived, locked, saved, isCrosspost); - post.setPreviews(previews); - post.setVideoUrl(url); - post.setVideoDownloadUrl(url); - } else { - if (url.contains(permalink)) { - //Text post but with a preview - int postType = Post.TEXT_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, - title, permalink, score, postType, voteType, nComments, flair, - awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, - saved, isCrosspost); - - //Need attention - post.setPreviews(previews); - - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - if (data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { - post.setSelfTextPlainTrimmed(""); - } else { - String selfTextPlain = Utils.trimTrailingWhitespace( - Html.fromHtml(data.getString(JSONUtils.SELFTEXT_HTML_KEY))).toString(); - post.setSelfTextPlain(selfTextPlain); - if (selfTextPlain.length() > 250) { - selfTextPlain = selfTextPlain.substring(0, 250); - } - post.setSelfTextPlainTrimmed(selfTextPlain); - } - } - } else { - //Link post - int postType = Post.LINK_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, - title, url, permalink, score, - postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, - nsfw, stickied, archived, locked, saved, isCrosspost); - if (data.isNull(JSONUtils.SELFTEXT_KEY)) { - post.setSelfText(""); - } else { - post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); - } - - post.setPreviews(previews); - } - } - } - } else { - if (url.endsWith("jpg") || url.endsWith("png")) { - //Image post - int postType = Post.IMAGE_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, - archived, locked, saved, isCrosspost); - - if (previews.isEmpty()) { - previews.add(new Post.Preview(url, 0, 0)); - } - post.setPreviews(previews); - } else if (url.endsWith("mp4")) { - //Video post - int postType = Post.VIDEO_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, - voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, - archived, locked, saved, isCrosspost); - post.setPreviews(previews); - post.setVideoUrl(url); - post.setVideoDownloadUrl(url); - } else { - //CP No Preview Link post - int postType = Post.NO_PREVIEW_LINK_TYPE; - - post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, - authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, voteType, - nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, - locked, saved, isCrosspost); - //Need attention - } - } - } - - if (post.getPostType() == Post.VIDEO_TYPE) { - try { - Uri uri = Uri.parse(url); - String authority = uri.getAuthority(); - if (authority != null && (authority.contains("gfycat.com"))) { - post.setIsGfycat(true); - post.setVideoUrl(url); - String gfycatId = url.substring(url.lastIndexOf("/") + 1); - if (gfycatId.contains("-")) { - gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); - } - post.setGfycatId(gfycatId); - } else if (authority != null && authority.contains("redgifs.com")) { - String gfycatId = url.substring(url.lastIndexOf("/") + 1); - if (gfycatId.contains("-")) { - gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); - } - post.setIsRedgifs(true); - post.setVideoUrl(url); - post.setGfycatId(gfycatId); - } - } catch (IllegalArgumentException ignore) { } - } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { - if (data.has(JSONUtils.GALLERY_DATA_KEY)) { - JSONArray galleryIdsArray = data.getJSONObject(JSONUtils.GALLERY_DATA_KEY).getJSONArray(JSONUtils.ITEMS_KEY); - JSONObject galleryObject = data.getJSONObject(JSONUtils.MEDIA_METADATA_KEY); - ArrayList gallery = new ArrayList<>(); - for (int i = 0; i < galleryIdsArray.length(); i++) { - String galleryId = galleryIdsArray.getJSONObject(i).getString(JSONUtils.MEDIA_ID_KEY); - JSONObject singleGalleryObject = galleryObject.getJSONObject(galleryId); - String mimeType = singleGalleryObject.getString(JSONUtils.M_KEY); - String galleryItemUrl; - if (mimeType.contains("jpg") || mimeType.contains("png")) { - galleryItemUrl = singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getString(JSONUtils.U_KEY); - } else { - JSONObject sourceObject = singleGalleryObject.getJSONObject(JSONUtils.S_KEY); - if (mimeType.contains("gif")) { - galleryItemUrl = sourceObject.getString(JSONUtils.GIF_KEY); - } else { - galleryItemUrl = sourceObject.getString(JSONUtils.MP4_KEY); - } - } - if ((previews.isEmpty()) && mimeType.contains("jpg") || mimeType.contains("png")) { - previews.add(new Post.Preview(galleryItemUrl, singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getInt(JSONUtils.X_KEY), - singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getInt(JSONUtils.Y_KEY))); - } - gallery.add(new Post.Gallery(mimeType, galleryItemUrl, subredditName + "-" + galleryId + "." + mimeType.substring(mimeType.lastIndexOf("/") + 1))); - } - - if (!gallery.isEmpty()) { - post.setPostType(Post.GALLERY_TYPE); - post.setGallery(gallery); - post.setPreviews(previews); - } - } else if (post.getPostType() == Post.LINK_TYPE) { - Uri uri = Uri.parse(url); - String authority = uri.getAuthority(); - if (authority != null && (authority.contains("gfycat.com"))) { - post.setPostType(Post.VIDEO_TYPE); - post.setIsGfycat(true); - post.setVideoUrl(url); - post.setGfycatId(url.substring(url.lastIndexOf("/") + 1)); - } else if (authority != null && authority.contains("redgifs.com")) { - post.setPostType(Post.VIDEO_TYPE); - post.setIsRedgifs(true); - post.setVideoUrl(url); - post.setGfycatId(url.substring(url.lastIndexOf("/") + 1)); - } - } - } - - return post; - } - - public interface ParsePostsListingListener { - void onParsePostsListingSuccess(LinkedHashSet newPostData, String lastItem); - - void onParsePostsListingFail(); - } - - public interface ParsePostListener { - void onParsePostSuccess(Post post); - - void onParsePostFail(); - } - - public interface ParseRandomPostListener { - void onParseRandomPostSuccess(String postId, String subredditName); - void onParseRandomPostFailed(); - } - - private static class ParsePostDataAsyncTask extends AsyncTask { - private JSONArray allData; - private int nPosts; - private int filter; - private boolean nsfw; - private List subredditFilterList; - private ParsePostsListingListener parsePostsListingListener; - private ParsePostListener parsePostListener; - private LinkedHashSet newPosts; - private Post post; - private String lastItem; - private boolean parseFailed; - - ParsePostDataAsyncTask(String response, int nPosts, int filter, boolean nsfw, - ParsePostsListingListener parsePostsListingListener) { - this.parsePostsListingListener = parsePostsListingListener; - try { - JSONObject jsonResponse = new JSONObject(response); - allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); - this.nPosts = nPosts; - this.filter = filter; - this.nsfw = nsfw; - newPosts = new LinkedHashSet<>(); - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - ParsePostDataAsyncTask(String response, int nPosts, int filter, boolean nsfw, - List subredditFilterList, ParsePostsListingListener parsePostsListingListener) { - this(response, nPosts, filter, nsfw, parsePostsListingListener); - this.subredditFilterList = subredditFilterList; - } - - ParsePostDataAsyncTask(String response, boolean nsfw, - ParsePostListener parsePostListener) { - this.parsePostListener = parsePostListener; - try { - allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - this.nsfw = nsfw; - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - @Override - protected Void doInBackground(Void... voids) { - if (parseFailed) { - return null; - } - - if (newPosts == null) { - //Only one post - if (allData.length() == 0) { - parseFailed = true; - return null; - } - - try { - JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); - post = parseBasicData(data); - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } else { - //Posts listing - int size; - if (nPosts < 0 || nPosts > allData.length()) { - size = allData.length(); - } else { - size = nPosts; - } - - for (int i = 0; i < size; i++) { - try { - if (allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { - JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - Post post = parseBasicData(data); - boolean availablePost = true; - if (subredditFilterList != null) { - for (SubredditFilter subredditFilter : subredditFilterList) { - if (subredditFilter.getSubredditName().equals(post.getSubredditName())) { - availablePost = false; - break; - } - } - } - if (availablePost && !(!nsfw && post.isNSFW())) { - if (filter == PostFragment.EXTRA_NO_FILTER) { - newPosts.add(post); - } else if (filter == post.getPostType()) { - newPosts.add(post); - } else if (filter == Post.LINK_TYPE && post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { - newPosts.add(post); - } else if (filter == Post.NSFW_TYPE && post.isNSFW()) { - newPosts.add(post); - } - } - } - } catch (JSONException e) { - e.printStackTrace(); - } - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - if (newPosts != null) { - parsePostsListingListener.onParsePostsListingSuccess(newPosts, lastItem); - } else { - parsePostListener.onParsePostSuccess(post); - } - } else { - if (parsePostsListingListener != null) { - parsePostsListingListener.onParsePostsListingFail(); - } else { - parsePostListener.onParsePostFail(); - } - } - } - } - - public static class ParseRandomPostAsyncTask extends AsyncTask { - - private String response; - private boolean isNSFW; - private ParseRandomPostListener parseRandomPostListener; - private String subredditName; - private String postId; - private boolean parseFailed = false; - - ParseRandomPostAsyncTask(String response, boolean isNSFW, ParseRandomPostListener parseRandomPostListener) { - this.response = response; - this.isNSFW = isNSFW; - this.parseRandomPostListener = parseRandomPostListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONArray postsArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - if (postsArray.length() == 0) { - parseFailed = true; - } else { - JSONObject post = postsArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); - subredditName = post.getString(JSONUtils.SUBREDDIT_KEY); - if (isNSFW) { - postId = post.getString(JSONUtils.ID_KEY); - } else { - postId = post.getString(JSONUtils.LINK_ID_KEY).substring("t3_".length()); - } - } - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - parseRandomPostListener.onParseRandomPostFailed(); - } else { - parseRandomPostListener.onParseRandomPostSuccess(postId, subredditName); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java deleted file mode 100644 index 381f89c2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/Post.java +++ /dev/null @@ -1,652 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.Nullable; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.Utils.APIUtils; - -/** - * Created by alex on 3/1/18. - */ - -public class Post implements Parcelable { - public static final int NSFW_TYPE = -1; - public static final int TEXT_TYPE = 0; - public static final int IMAGE_TYPE = 1; - public static final int LINK_TYPE = 2; - public static final int VIDEO_TYPE = 3; - public static final int GIF_TYPE = 4; - public static final int NO_PREVIEW_LINK_TYPE = 5; - public static final int GALLERY_TYPE = 6; - public static final Creator CREATOR = new Creator() { - @Override - public Post createFromParcel(Parcel in) { - return new Post(in); - } - - @Override - public Post[] newArray(int size) { - return new Post[size]; - } - }; - private String id; - private String fullName; - private String subredditName; - private String subredditNamePrefixed; - private String subredditIconUrl; - private String author; - private String authorNamePrefixed; - private String authorIconUrl; - private String authorFlair; - private String authorFlairHTML; - private String title; - private String selfText; - private String selfTextPlain; - private String selfTextPlainTrimmed; - private String url; - private String videoUrl; - private String videoDownloadUrl; - private String gfycatId; - private boolean isGfycat; - private boolean isRedgifs; - private boolean loadGfyOrRedgifsVideoSuccess; - private String permalink; - private String flair; - private String awards; - private int nAwards; - private long postTimeMillis; - private int score; - private int postType; - private int voteType; - private int nComments; - private boolean hidden; - private boolean spoiler; - private boolean nsfw; - private boolean stickied; - private boolean archived; - private boolean locked; - private boolean saved; - private boolean isCrosspost; - private String crosspostParentId; - private ArrayList previews = new ArrayList<>(); - private ArrayList gallery = new ArrayList<>(); - - public Post(String id, String fullName, String subredditName, String subredditNamePrefixed, - String author, String authorFlair, String authorFlairHTML, - long postTimeMillis, String title, - String permalink, int score, int postType, int voteType, int nComments, String flair, - String awards, int nAwards, boolean hidden, boolean spoiler, boolean nsfw, boolean stickied, - boolean archived, boolean locked, boolean saved, boolean isCrosspost) { - this.id = id; - this.fullName = fullName; - this.subredditName = subredditName; - this.subredditNamePrefixed = subredditNamePrefixed; - this.author = author; - this.authorNamePrefixed = "u/" + author; - this.authorFlair = authorFlair; - this.authorFlairHTML = authorFlairHTML; - this.postTimeMillis = postTimeMillis; - this.title = title; - this.permalink = APIUtils.API_BASE_URI + permalink; - this.score = score; - this.postType = postType; - this.voteType = voteType; - this.nComments = nComments; - this.flair = flair; - this.awards = awards; - this.nAwards = nAwards; - this.hidden = hidden; - this.spoiler = spoiler; - this.nsfw = nsfw; - this.stickied = stickied; - this.archived = archived; - this.locked = locked; - this.saved = saved; - this.isCrosspost = isCrosspost; - } - - public Post(String id, String fullName, String subredditName, String subredditNamePrefixed, - String author, String authorFlair, String authorFlairHTML, - long postTimeMillis, String title, - String url, String permalink, int score, int postType, int voteType, int nComments, - String flair, String awards, int nAwards, boolean hidden, boolean spoiler, boolean nsfw, - boolean stickied, boolean archived, boolean locked, boolean saved, boolean isCrosspost) { - this.id = id; - this.fullName = fullName; - this.subredditName = subredditName; - this.subredditNamePrefixed = subredditNamePrefixed; - this.author = author; - this.authorNamePrefixed = "u/" + author; - this.authorFlair = authorFlair; - this.authorFlairHTML = authorFlairHTML; - this.postTimeMillis = postTimeMillis; - this.title = title; - this.url = url; - this.permalink = APIUtils.API_BASE_URI + permalink; - this.score = score; - this.postType = postType; - this.voteType = voteType; - this.nComments = nComments; - this.flair = flair; - this.awards = awards; - this.nAwards = nAwards; - this.hidden = hidden; - this.spoiler = spoiler; - this.nsfw = nsfw; - this.stickied = stickied; - this.archived = archived; - this.locked = locked; - this.saved = saved; - this.isCrosspost = isCrosspost; - } - - protected Post(Parcel in) { - id = in.readString(); - fullName = in.readString(); - subredditName = in.readString(); - subredditNamePrefixed = in.readString(); - subredditIconUrl = in.readString(); - author = in.readString(); - authorNamePrefixed = in.readString(); - authorFlair = in.readString(); - authorFlairHTML = in.readString(); - authorIconUrl = in.readString(); - postTimeMillis = in.readLong(); - title = in.readString(); - selfText = in.readString(); - selfTextPlain = in.readString(); - selfTextPlainTrimmed = in.readString(); - url = in.readString(); - videoUrl = in.readString(); - videoDownloadUrl = in.readString(); - gfycatId = in.readString(); - isGfycat = in.readByte() != 0; - isRedgifs = in.readByte() != 0; - loadGfyOrRedgifsVideoSuccess = in.readByte() != 0; - permalink = in.readString(); - flair = in.readString(); - awards = in.readString(); - nAwards = in.readInt(); - score = in.readInt(); - postType = in.readInt(); - voteType = in.readInt(); - nComments = in.readInt(); - hidden = in.readByte() != 0; - spoiler = in.readByte() != 0; - nsfw = in.readByte() != 0; - stickied = in.readByte() != 0; - archived = in.readByte() != 0; - locked = in.readByte() != 0; - saved = in.readByte() != 0; - isCrosspost = in.readByte() != 0; - crosspostParentId = in.readString(); - in.readTypedList(previews, Preview.CREATOR); - in.readTypedList(gallery, Gallery.CREATOR); - } - - public String getId() { - return id; - } - - public String getFullName() { - return fullName; - } - - public String getSubredditName() { - return subredditName; - } - - public String getSubredditNamePrefixed() { - return subredditNamePrefixed; - } - - public String getSubredditIconUrl() { - return subredditIconUrl; - } - - public void setSubredditIconUrl(String subredditIconUrl) { - this.subredditIconUrl = subredditIconUrl; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - this.authorNamePrefixed = "u/" + author; - } - - public String getAuthorNamePrefixed() { - return authorNamePrefixed; - } - - public String getAuthorFlair() { - return authorFlair; - } - - public String getAuthorFlairHTML() { - return authorFlairHTML; - } - - public String getAuthorIconUrl() { - return authorIconUrl; - } - - public void setAuthorIconUrl(String authorIconUrl) { - this.authorIconUrl = authorIconUrl; - } - - public long getPostTimeMillis() { - return postTimeMillis; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getSelfText() { - return selfText; - } - - public void setSelfText(String selfText) { - this.selfText = selfText; - } - - public String getSelfTextPlain() { - return selfTextPlain; - } - - public void setSelfTextPlain(String selfTextPlain) { - this.selfTextPlain = selfTextPlain; - } - - public String getSelfTextPlainTrimmed() { - return selfTextPlainTrimmed; - } - - public void setSelfTextPlainTrimmed(String selfTextPlainTrimmed) { - this.selfTextPlainTrimmed = selfTextPlainTrimmed; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getVideoUrl() { - return videoUrl; - } - - public void setVideoUrl(String videoUrl) { - this.videoUrl = videoUrl; - } - - public String getVideoDownloadUrl() { - return videoDownloadUrl; - } - - public void setVideoDownloadUrl(String videoDownloadUrl) { - this.videoDownloadUrl = videoDownloadUrl; - } - - public String getGfycatId() { - return gfycatId; - } - - public void setGfycatId(String gfycatId) { - this.gfycatId = gfycatId; - } - - public boolean isGfycat() { - return isGfycat; - } - - public void setIsGfycat(boolean isGfycat) { - this.isGfycat = isGfycat; - } - - public boolean isRedgifs() { - return isRedgifs; - } - - public void setIsRedgifs(boolean isRedgifs) { - this.isRedgifs = isRedgifs; - } - - public boolean isLoadGfyOrRedgifsVideoSuccess() { - return loadGfyOrRedgifsVideoSuccess; - } - - public void setLoadGfyOrRedgifsVideoSuccess(boolean loadGfyOrRedgifsVideoSuccess) { - this.loadGfyOrRedgifsVideoSuccess = loadGfyOrRedgifsVideoSuccess; - } - - public String getPermalink() { - return permalink; - } - - public String getFlair() { - return flair; - } - - public void setFlair(String flair) { - this.flair = flair; - } - - public String getAwards() { - return awards; - } - - public void addAwards(String newAwardsHTML) { - awards += newAwardsHTML; - } - - public int getnAwards() { - return nAwards; - } - - public void addAwards(int newNAwards) { - nAwards += newNAwards; - } - - public int getScore() { - return score; - } - - public void setScore(int score) { - this.score = score; - } - - public int getPostType() { - return postType; - } - - public void setPostType(int postType) { - this.postType = postType; - } - - public int getVoteType() { - return voteType; - } - - public void setVoteType(int voteType) { - this.voteType = voteType; - } - - public int getNComments() { - return nComments; - } - - public void setNComments(int nComments) { - this.nComments = nComments; - } - - public boolean isHidden() { - return hidden; - } - - public void setHidden(boolean hidden) { - this.hidden = hidden; - } - - public boolean isSpoiler() { - return spoiler; - } - - public void setSpoiler(boolean spoiler) { - this.spoiler = spoiler; - } - - public boolean isNSFW() { - return nsfw; - } - - public void setNSFW(boolean nsfw) { - this.nsfw = nsfw; - } - - @Override - public int describeContents() { - return 0; - } - - public boolean isStickied() { - return stickied; - } - - public boolean isArchived() { - return archived; - } - - public boolean isLocked() { - return locked; - } - - public boolean isSaved() { - return saved; - } - - public void setSaved(boolean saved) { - this.saved = saved; - } - - public boolean isCrosspost() { - return isCrosspost; - } - - public String getCrosspostParentId() { - return crosspostParentId; - } - - public void setCrosspostParentId(String crosspostParentId) { - this.crosspostParentId = crosspostParentId; - } - - public ArrayList getPreviews() { - return previews; - } - - public void setPreviews(ArrayList previews) { - this.previews = previews; - } - - public ArrayList getGallery() { - return gallery; - } - - public void setGallery(ArrayList gallery) { - this.gallery = gallery; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(id); - parcel.writeString(fullName); - parcel.writeString(subredditName); - parcel.writeString(subredditNamePrefixed); - parcel.writeString(subredditIconUrl); - parcel.writeString(author); - parcel.writeString(authorNamePrefixed); - parcel.writeString(authorFlair); - parcel.writeString(authorFlairHTML); - parcel.writeString(authorIconUrl); - parcel.writeLong(postTimeMillis); - parcel.writeString(title); - parcel.writeString(selfText); - parcel.writeString(selfTextPlain); - parcel.writeString(selfTextPlainTrimmed); - parcel.writeString(url); - parcel.writeString(videoUrl); - parcel.writeString(videoDownloadUrl); - parcel.writeString(gfycatId); - parcel.writeByte((byte) (isGfycat ? 1 : 0)); - parcel.writeByte((byte) (isRedgifs ? 1 : 0)); - parcel.writeByte((byte) (loadGfyOrRedgifsVideoSuccess ? 1 : 0)); - parcel.writeString(permalink); - parcel.writeString(flair); - parcel.writeString(awards); - parcel.writeInt(nAwards); - parcel.writeInt(score); - parcel.writeInt(postType); - parcel.writeInt(voteType); - parcel.writeInt(nComments); - parcel.writeByte((byte) (hidden ? 1 : 0)); - parcel.writeByte((byte) (spoiler ? 1 : 0)); - parcel.writeByte((byte) (nsfw ? 1 : 0)); - parcel.writeByte((byte) (stickied ? 1 : 0)); - parcel.writeByte((byte) (archived ? 1 : 0)); - parcel.writeByte((byte) (locked ? 1 : 0)); - parcel.writeByte((byte) (saved ? 1 : 0)); - parcel.writeByte((byte) (isCrosspost ? 1 : 0)); - parcel.writeString(crosspostParentId); - parcel.writeTypedList(previews); - parcel.writeTypedList(gallery); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (!(obj instanceof Post)) { - return false; - } - return ((Post) obj).id.equals(id); - } - - @Override - public int hashCode() { - return id.hashCode(); - } - - public static class Gallery implements Parcelable { - public static final int TYPE_IMAGE = 0; - public static final int TYPE_GIF = 1; - public static final int TYPE_VIDEO = 2; - - public String mimeType; - public String url; - public String fileName; - public int mediaType; - - public Gallery(String mimeType, String url, String fileName) { - this.mimeType = mimeType; - this.url = url; - this.fileName = fileName; - if (mimeType.contains("gif")) { - mediaType = TYPE_GIF; - } else if (mimeType.contains("jpg") || mimeType.contains("png")) { - mediaType = TYPE_IMAGE; - } else { - mediaType = TYPE_VIDEO; - } - } - - protected Gallery(Parcel in) { - mimeType = in.readString(); - url = in.readString(); - fileName = in.readString(); - mediaType = in.readInt(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Gallery createFromParcel(Parcel in) { - return new Gallery(in); - } - - @Override - public Gallery[] newArray(int size) { - return new Gallery[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(mimeType); - parcel.writeString(url); - parcel.writeString(fileName); - parcel.writeInt(mediaType); - } - } - - public static class Preview implements Parcelable { - private String previewUrl; - private int previewWidth; - private int previewHeight; - - public Preview(String previewUrl, int previewWidth, int previewHeight) { - this.previewUrl = previewUrl; - this.previewWidth = previewWidth; - this.previewHeight = previewHeight; - } - - protected Preview(Parcel in) { - previewUrl = in.readString(); - previewWidth = in.readInt(); - previewHeight = in.readInt(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Preview createFromParcel(Parcel in) { - return new Preview(in); - } - - @Override - public Preview[] newArray(int size) { - return new Preview[size]; - } - }; - - public String getPreviewUrl() { - return previewUrl; - } - - public void setPreviewUrl(String previewUrl) { - this.previewUrl = previewUrl; - } - - public int getPreviewWidth() { - return previewWidth; - } - - public void setPreviewWidth(int previewWidth) { - this.previewWidth = previewWidth; - } - - public int getPreviewHeight() { - return previewHeight; - } - - public void setPreviewHeight(int previewHeight) { - this.previewHeight = previewHeight; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(previewUrl); - parcel.writeInt(previewWidth); - parcel.writeInt(previewHeight); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java deleted file mode 100644 index 480e96b1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSource.java +++ /dev/null @@ -1,927 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.PageKeyedDataSource; - -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Retrofit; - -public class PostDataSource extends PageKeyedDataSource { - - public static final int TYPE_FRONT_PAGE = 0; - public static final int TYPE_SUBREDDIT = 1; - public static final int TYPE_USER = 2; - public static final int TYPE_SEARCH = 3; - public static final int TYPE_MULTI_REDDIT = 4; - - public static final String USER_WHERE_SUBMITTED = "submitted"; - public static final String USER_WHERE_UPVOTED = "upvoted"; - public static final String USER_WHERE_DOWNVOTED = "downvoted"; - public static final String USER_WHERE_HIDDEN = "hidden"; - public static final String USER_WHERE_SAVED = "saved"; - public static final String USER_WHERE_GILDED = "gilded"; - - private Retrofit retrofit; - private String accessToken; - private String accountName; - private Locale locale; - private SharedPreferences sharedPreferences; - private SharedPreferences postFeedScrolledPositionSharedPreferences; - private String subredditOrUserName; - private String query; - private int postType; - private SortType sortType; - private boolean nsfw; - private int filter; - private List subredditFilterList; - private String userWhere; - private String multiRedditPath; - private LinkedHashSet postLinkedHashSet; - - private MutableLiveData paginationNetworkStateLiveData; - private MutableLiveData initialLoadStateLiveData; - private MutableLiveData hasPostLiveData; - - private LoadParams params; - private LoadCallback callback; - - PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, int postType, - SortType sortType, int filter, boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasPostLiveData = new MutableLiveData<>(); - this.postType = postType; - this.sortType = sortType == null ? new SortType(SortType.Type.BEST) : sortType; - this.filter = filter; - this.nsfw = nsfw; - postLinkedHashSet = new LinkedHashSet<>(); - } - - PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - String path, int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - if (postType == TYPE_SUBREDDIT) { - this.subredditOrUserName = path; - } else { - if (sortType != null) { - if (path.endsWith("/")) { - multiRedditPath = path + sortType.getType().value; - } else { - multiRedditPath = path + "/" + sortType.getType().value; - } - } else { - multiRedditPath = path; - } - } - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasPostLiveData = new MutableLiveData<>(); - this.postType = postType; - if (sortType == null) { - if (path.equals("popular") || path.equals("all")) { - this.sortType = new SortType(SortType.Type.HOT); - } else { - this.sortType = new SortType(SortType.Type.BEST); - } - } else { - this.sortType = sortType; - } - this.filter = filter; - this.nsfw = nsfw; - this.subredditFilterList = subredditFilterList; - postLinkedHashSet = new LinkedHashSet<>(); - } - - PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, - int postType, SortType sortType, String where, int filter, boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditOrUserName = subredditOrUserName; - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasPostLiveData = new MutableLiveData<>(); - this.postType = postType; - this.sortType = sortType == null ? new SortType(SortType.Type.NEW) : sortType; - userWhere = where; - this.filter = filter; - this.nsfw = nsfw; - postLinkedHashSet = new LinkedHashSet<>(); - } - - PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, - String query, int postType, SortType sortType, int filter, boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditOrUserName = subredditOrUserName; - this.query = query; - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasPostLiveData = new MutableLiveData<>(); - this.postType = postType; - this.sortType = sortType == null ? new SortType(SortType.Type.RELEVANCE) : sortType; - this.filter = filter; - this.nsfw = nsfw; - postLinkedHashSet = new LinkedHashSet<>(); - } - - MutableLiveData getPaginationNetworkStateLiveData() { - return paginationNetworkStateLiveData; - } - - MutableLiveData getInitialLoadStateLiveData() { - return initialLoadStateLiveData; - } - - MutableLiveData hasPostLiveData() { - return hasPostLiveData; - } - - @Override - public void loadInitial(@NonNull LoadInitialParams params, @NonNull final LoadInitialCallback callback) { - initialLoadStateLiveData.postValue(NetworkState.LOADING); - switch (postType) { - case TYPE_FRONT_PAGE: - boolean savePostFeedScrolledPosition = sortType != null && sortType.getType() == SortType.Type.BEST && sharedPreferences.getBoolean(SharedPreferencesUtils.SAVE_FRONT_PAGE_SCROLLED_POSITION, false); - String accountNameForCache = accountName == null ? SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_ANONYMOUS : accountName; - if (savePostFeedScrolledPosition) { - loadBestPostsInitial(callback, postFeedScrolledPositionSharedPreferences.getString(accountNameForCache + SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_FRONT_PAGE_BASE, null)); - } else { - loadBestPostsInitial(callback, null); - } - break; - case TYPE_SUBREDDIT: - loadSubredditPostsInitial(callback, null); - break; - case TYPE_USER: - loadUserPostsInitial(callback, null); - break; - case TYPE_SEARCH: - loadSearchPostsInitial(callback, null); - break; - case TYPE_MULTI_REDDIT: - loadMultiRedditPostsInitial(callback, null); - break; - } - } - - @Override - public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { - - } - - @Override - public void loadAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback) { - this.params = params; - this.callback = callback; - - if (params == null || "".equals(params.key) || "null".equals(params.key)) { - return; - } - - paginationNetworkStateLiveData.postValue(NetworkState.LOADING); - - switch (postType) { - case TYPE_FRONT_PAGE: - loadBestPostsAfter(params, callback, null); - break; - case TYPE_SUBREDDIT: - loadSubredditPostsAfter(params, callback, null); - break; - case TYPE_USER: - loadUserPostsAfter(params, callback, null); - break; - case TYPE_SEARCH: - loadSearchPostsAfter(params, callback, null); - break; - case TYPE_MULTI_REDDIT: - loadMultiRedditPostsAfter(params, callback, null); - break; - } - } - - private void loadBestPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { - RedditAPI api = retrofit.create(RedditAPI.class); - Call bestPost; - if(sortType.getTime() != null) { - bestPost = api.getBestPosts(sortType.getType().value, sortType.getTime().value, lastItem, - APIUtils.getOAuthHeader(accessToken)); - } else { - bestPost = api.getBestPosts(sortType.getType().value, lastItem, APIUtils.getOAuthHeader(accessToken)); - } - bestPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - String nextPageKey; - if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - nextPageKey = null; - } else { - nextPageKey = lastItem; - } - - if (newPosts.size() != 0) { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(true); - } else if (nextPageKey != null) { - loadBestPostsInitial(callback, nextPageKey); - return; - } else { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(false); - } - - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onParsePostsListingFail() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing posts")); - } - }); - } else { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, - "code: " + response.code() + " message: " + response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, - errorMessage + " " + call.request().url().toString())); - } - }); - } - - private void loadBestPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { - String after = lastItem == null ? params.key : lastItem; - - RedditAPI api = retrofit.create(RedditAPI.class); - Call bestPost; - if(sortType.getTime() != null) { - bestPost = api.getBestPosts(sortType.getType().value, sortType.getTime().value, after, - APIUtils.getOAuthHeader(accessToken)); - } else { - bestPost = api.getBestPosts(sortType.getType().value, after, APIUtils.getOAuthHeader(accessToken)); - } - - bestPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { - loadBestPostsAfter(params, callback, lastItem); - } else { - int currentPostsSize = postLinkedHashSet.size(); - postLinkedHashSet.addAll(newPosts); - if (currentPostsSize == postLinkedHashSet.size()) { - callback.onResult(new ArrayList<>(), lastItem); - } else { - List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); - callback.onResult(newPostsList, lastItem); - } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - } - - @Override - public void onParsePostsListingFail() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing more posts")); - } - }); - } else { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - private void loadSubredditPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { - RedditAPI api = retrofit.create(RedditAPI.class); - - Call getPost; - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, sortType.getTime().value, lastItem); - } else { - getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, lastItem); - } - } else { - if (sortType.getTime() != null) { - getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, - sortType.getTime().value, lastItem, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, - lastItem, APIUtils.getOAuthHeader(accessToken)); - } - } - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, subredditFilterList, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - String nextPageKey; - if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - nextPageKey = null; - } else { - nextPageKey = lastItem; - } - - if (newPosts.size() != 0) { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(true); - } else if (nextPageKey != null) { - loadSubredditPostsInitial(callback, nextPageKey); - return; - } else { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(false); - } - - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onParsePostsListingFail() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing posts")); - } - }); - } else { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, - "code: " + response + " message: " + response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, - errorMessage + " " + call.request().url().toString())); - } - }); - } - - private void loadSubredditPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { - String after = lastItem == null ? params.key : lastItem; - - RedditAPI api = retrofit.create(RedditAPI.class); - - Call getPost; - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, - sortType.getTime().value, after); - } else { - getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, after); - } - } else { - if (sortType.getTime() != null) { - getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, - sortType.getTime().value, after, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, - after, APIUtils.getOAuthHeader(accessToken)); - } - } - - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, subredditFilterList, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { - loadSubredditPostsAfter(params, callback, lastItem); - } else { - int currentPostsSize = postLinkedHashSet.size(); - postLinkedHashSet.addAll(newPosts); - if (currentPostsSize == postLinkedHashSet.size()) { - callback.onResult(new ArrayList<>(), lastItem); - } else { - List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); - callback.onResult(newPostsList, lastItem); - } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - } - - @Override - public void onParsePostsListingFail() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - private void loadUserPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { - RedditAPI api = retrofit.create(RedditAPI.class); - - Call getPost; - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.getUserPosts(subredditOrUserName, lastItem, sortType.getType().value, - sortType.getTime().value); - } else { - getPost = api.getUserPosts(subredditOrUserName, lastItem, sortType.getType().value); - } - } else { - if (sortType.getTime() != null) { - getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, lastItem, sortType.getType().value, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, lastItem, sortType.getType().value, - APIUtils.getOAuthHeader(accessToken)); - } - } - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - String nextPageKey; - if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - nextPageKey = null; - } else { - nextPageKey = lastItem; - } - - if (newPosts.size() != 0) { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(true); - } else if (nextPageKey != null) { - loadUserPostsInitial(callback, nextPageKey); - return; - } else { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(false); - } - - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onParsePostsListingFail() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - private void loadUserPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { - String after = lastItem == null ? params.key : lastItem; - - RedditAPI api = retrofit.create(RedditAPI.class); - - Call getPost; - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.getUserPosts(subredditOrUserName, after, sortType.getType().value, - sortType.getTime().value); - } else { - getPost = api.getUserPosts(subredditOrUserName, after, sortType.getType().value); - } - } else { - if (sortType.getTime() != null) { - getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, after, sortType.getType().value, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, after, sortType.getType().value, - APIUtils.getOAuthHeader(accessToken)); - } - } - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { - loadUserPostsAfter(params, callback, lastItem); - } else { - int currentPostsSize = postLinkedHashSet.size(); - postLinkedHashSet.addAll(newPosts); - if (currentPostsSize == postLinkedHashSet.size()) { - callback.onResult(new ArrayList<>(), lastItem); - } else { - List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); - callback.onResult(newPostsList, lastItem); - } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - } - - @Override - public void onParsePostsListingFail() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - private void loadSearchPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { - RedditAPI api = retrofit.create(RedditAPI.class); - Call getPost; - - if (subredditOrUserName == null) { - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.searchPosts(query, lastItem, sortType.getType().value, sortType.getTime().value); - } else { - getPost = api.searchPosts(query, lastItem, sortType.getType().value); - } - } else { - if(sortType.getTime() != null) { - getPost = api.searchPostsOauth(query, lastItem, sortType.getType().value, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.searchPostsOauth(query, lastItem, sortType.getType().value, - APIUtils.getOAuthHeader(accessToken)); - } - } - } else { - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, - sortType.getType().value, sortType.getTime().value, lastItem); - } else { - getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, - sortType.getType().value, lastItem); - } - } else { - if (sortType.getTime() != null) { - getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, - sortType.getType().value, sortType.getTime().value, lastItem, - APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, - sortType.getType().value, lastItem, - APIUtils.getOAuthHeader(accessToken)); - } - } - } - - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - String nextPageKey; - if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - nextPageKey = null; - } else { - nextPageKey = lastItem; - } - - if (newPosts.size() != 0) { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(true); - } else if (nextPageKey != null) { - loadSearchPostsInitial(callback, nextPageKey); - return; - } else { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(false); - } - - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onParsePostsListingFail() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - private void loadSearchPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { - String after = lastItem == null ? params.key : lastItem; - - RedditAPI api = retrofit.create(RedditAPI.class); - Call getPost; - - if (subredditOrUserName == null) { - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.searchPosts(query, after, sortType.getType().value, sortType.getTime().value); - } else { - getPost = api.searchPosts(query, after, sortType.getType().value); - } - } else { - if (sortType.getTime() != null) { - getPost = api.searchPostsOauth(query, after, sortType.getType().value, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.searchPostsOauth(query, after, sortType.getType().value, APIUtils.getOAuthHeader(accessToken)); - } - } - } else { - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, - sortType.getType().value, sortType.getTime().value, after); - } else { - getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, - sortType.getType().value, after); - } - } else { - if (sortType.getTime() != null) { - getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, - sortType.getType().value, sortType.getTime().value, after, - APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, - sortType.getType().value, after, APIUtils.getOAuthHeader(accessToken)); - } - } - } - - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { - loadSearchPostsAfter(params, callback, lastItem); - } else { - int currentPostsSize = postLinkedHashSet.size(); - postLinkedHashSet.addAll(newPosts); - if (currentPostsSize == postLinkedHashSet.size()) { - callback.onResult(new ArrayList<>(), lastItem); - } else { - List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); - callback.onResult(newPostsList, lastItem); - } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - } - - @Override - public void onParsePostsListingFail() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - private void loadMultiRedditPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { - RedditAPI api = retrofit.create(RedditAPI.class); - Call getPost; - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.getMultiRedditPosts(multiRedditPath, lastItem, sortType.getTime().value); - } else { - getPost = api.getMultiRedditPosts(multiRedditPath, lastItem); - } - } else { - if (sortType.getTime() != null) { - getPost = api.getMultiRedditPostsOauth(multiRedditPath, lastItem, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.getMultiRedditPostsOauth(multiRedditPath, lastItem, - APIUtils.getOAuthHeader(accessToken)); - } - } - - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - String nextPageKey; - if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { - nextPageKey = null; - } else { - nextPageKey = lastItem; - } - - if (newPosts.size() != 0) { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(true); - } else if (nextPageKey != null) { - loadMultiRedditPostsInitial(callback, nextPageKey); - return; - } else { - postLinkedHashSet.addAll(newPosts); - callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); - hasPostLiveData.postValue(false); - } - - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onParsePostsListingFail() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - private void loadMultiRedditPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { - String after = lastItem == null ? params.key : lastItem; - - RedditAPI api = retrofit.create(RedditAPI.class); - - Call getPost; - if (accessToken == null) { - if (sortType.getTime() != null) { - getPost = api.getMultiRedditPosts(multiRedditPath, after, - sortType.getTime().value); - } else { - getPost = api.getMultiRedditPosts(multiRedditPath, after); - } - } else { - if (sortType.getTime() != null) { - getPost = api.getMultiRedditPostsOauth(multiRedditPath, after, - sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); - } else { - getPost = api.getMultiRedditPostsOauth(multiRedditPath, after, - APIUtils.getOAuthHeader(accessToken)); - } - } - getPost.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePosts(response.body(), -1, filter, nsfw, - new ParsePost.ParsePostsListingListener() { - @Override - public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { - if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { - loadMultiRedditPostsAfter(params, callback, lastItem); - } else { - int currentPostsSize = postLinkedHashSet.size(); - postLinkedHashSet.addAll(newPosts); - if (currentPostsSize == postLinkedHashSet.size()) { - callback.onResult(new ArrayList<>(), lastItem); - } else { - List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); - callback.onResult(newPostsList, lastItem); - } - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - } - - @Override - public void onParsePostsListingFail() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); - } - }); - } else { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String errorMessage = t.getMessage(); - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); - } - }); - } - - void retryLoadingMore() { - loadAfter(params, callback); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java deleted file mode 100644 index 02bc58c3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostDataSourceFactory.java +++ /dev/null @@ -1,141 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.DataSource; - -import java.util.List; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; -import retrofit2.Retrofit; - -class PostDataSourceFactory extends DataSource.Factory { - private Retrofit retrofit; - private String accessToken; - private String accountName; - private Locale locale; - private SharedPreferences sharedPreferences; - private SharedPreferences postFeedScrolledPositionSharedPreferences; - private String subredditName; - private String query; - private int postType; - private SortType sortType; - private String userWhere; - private int filter; - private boolean nsfw; - private List subredditFilterList; - - private PostDataSource postDataSource; - private MutableLiveData postDataSourceLiveData; - - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - int postType, SortType sortType, int filter, boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - postDataSourceLiveData = new MutableLiveData<>(); - this.postType = postType; - this.sortType = sortType; - this.filter = filter; - this.nsfw = nsfw; - } - - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - String subredditName, int postType, SortType sortType, int filter, boolean nsfw, - List subredditFilterList) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditName = subredditName; - postDataSourceLiveData = new MutableLiveData<>(); - this.postType = postType; - this.sortType = sortType; - this.filter = filter; - this.nsfw = nsfw; - this.subredditFilterList = subredditFilterList; - } - - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - String subredditName, int postType, SortType sortType, String where, int filter, - boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditName = subredditName; - postDataSourceLiveData = new MutableLiveData<>(); - this.postType = postType; - this.sortType = sortType; - userWhere = where; - this.filter = filter; - this.nsfw = nsfw; - } - - PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - String subredditName, String query, int postType, SortType sortType, int filter, - boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditName = subredditName; - this.query = query; - postDataSourceLiveData = new MutableLiveData<>(); - this.postType = postType; - this.sortType = sortType; - this.filter = filter; - this.nsfw = nsfw; - } - - @NonNull - @Override - public DataSource create() { - if (postType == PostDataSource.TYPE_FRONT_PAGE) { - postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, - sharedPreferences, postFeedScrolledPositionSharedPreferences, postType, sortType, filter, nsfw); - } else if (postType == PostDataSource.TYPE_SEARCH) { - postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, - sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw); - } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { - postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, - sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList); - } else { - postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, - sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, userWhere, filter, nsfw); - } - - postDataSourceLiveData.postValue(postDataSource); - return postDataSource; - } - - public MutableLiveData getPostDataSourceLiveData() { - return postDataSourceLiveData; - } - - PostDataSource getPostDataSource() { - return postDataSource; - } - - void changeNSFWAndSortType(boolean nsfw, SortType sortType) { - this.nsfw = nsfw; - this.sortType = sortType; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java deleted file mode 100644 index 44496d04..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/PostViewModel.java +++ /dev/null @@ -1,322 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import android.content.SharedPreferences; - -import androidx.annotation.NonNull; -import androidx.core.util.Pair; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MediatorLiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; -import androidx.paging.LivePagedListBuilder; -import androidx.paging.PagedList; - -import java.util.List; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.SortType; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; -import retrofit2.Retrofit; - -public class PostViewModel extends ViewModel { - private PostDataSourceFactory postDataSourceFactory; - private LiveData paginationNetworkState; - private LiveData initialLoadingState; - private LiveData hasPostLiveData; - private LiveData> posts; - private MutableLiveData nsfwLiveData; - private MutableLiveData sortTypeLiveData; - private NSFWAndSortTypeLiveData nsfwAndSortTypeLiveData; - - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences cache, int postType, - SortType sortType, int filter, boolean nsfw) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, - sharedPreferences, cache, postType, sortType, filter, nsfw); - - initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getPaginationNetworkStateLiveData); - hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::hasPostLiveData); - - nsfwLiveData = new MutableLiveData<>(); - nsfwLiveData.postValue(nsfw); - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - - nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { - postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); - return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); - }); - } - - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, - int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, - sharedPreferences, cache, subredditName, postType, sortType, filter, nsfw, subredditFilterList); - - initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getPaginationNetworkStateLiveData); - hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::hasPostLiveData); - - nsfwLiveData = new MutableLiveData<>(); - nsfwLiveData.postValue(nsfw); - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - - nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { - postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); - return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); - }); - } - - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, - int postType, SortType sortType, String where, int filter, - boolean nsfw) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, - sharedPreferences, cache, subredditName, postType, sortType, where, filter, nsfw); - - initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getPaginationNetworkStateLiveData); - hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::hasPostLiveData); - - nsfwLiveData = new MutableLiveData<>(); - nsfwLiveData.postValue(nsfw); - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - - nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { - postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); - return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); - }); - } - - public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, - String query, int postType, SortType sortType, int filter, - boolean nsfw) { - postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, - sharedPreferences, cache, subredditName, query, postType, sortType, filter, nsfw); - - initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::getPaginationNetworkStateLiveData); - hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), - PostDataSource::hasPostLiveData); - - nsfwLiveData = new MutableLiveData<>(); - nsfwLiveData.postValue(nsfw); - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - - nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { - postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); - return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); - }); - } - - public LiveData> getPosts() { - return posts; - } - - public LiveData getPaginationNetworkState() { - return paginationNetworkState; - } - - public LiveData getInitialLoadingState() { - return initialLoadingState; - } - - public LiveData hasPost() { - return hasPostLiveData; - } - - public void refresh() { - postDataSourceFactory.getPostDataSource().invalidate(); - } - - public void retryLoadingMore() { - postDataSourceFactory.getPostDataSource().retryLoadingMore(); - } - - public void changeSortType(SortType sortType) { - sortTypeLiveData.postValue(sortType); - } - - public void changeNSFW(boolean nsfw) { - nsfwLiveData.postValue(nsfw); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Retrofit retrofit; - private String accessToken; - private String accountName; - private Locale locale; - private SharedPreferences sharedPreferences; - private SharedPreferences postFeedScrolledPositionSharedPreferences; - private String subredditName; - private String query; - private int postType; - private SortType sortType; - private String userWhere; - private int filter; - private boolean nsfw; - private List subredditFilterList; - - public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, - int postType, SortType sortType, int filter, boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.postType = postType; - this.sortType = sortType; - this.filter = filter; - this.nsfw = nsfw; - } - - public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, - int postType, SortType sortType, int filter, boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditName = subredditName; - this.postType = postType; - this.sortType = sortType; - this.filter = filter; - this.nsfw = nsfw; - } - - //With subreddit filter - public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, - int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditName = subredditName; - this.postType = postType; - this.sortType = sortType; - this.filter = filter; - this.nsfw = nsfw; - this.subredditFilterList = subredditFilterList; - } - - //User posts - public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, - int postType, SortType sortType, String where, int filter, - boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditName = subredditName; - this.postType = postType; - this.sortType = sortType; - userWhere = where; - this.filter = filter; - this.nsfw = nsfw; - } - - public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, - SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, - String query, int postType, SortType sortType, int filter, boolean nsfw) { - this.retrofit = retrofit; - this.accessToken = accessToken; - this.accountName = accountName; - this.locale = locale; - this.sharedPreferences = sharedPreferences; - this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; - this.subredditName = subredditName; - this.query = query; - this.postType = postType; - this.sortType = sortType; - this.filter = filter; - this.nsfw = nsfw; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - if (postType == PostDataSource.TYPE_FRONT_PAGE) { - return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, - postFeedScrolledPositionSharedPreferences, postType, sortType, filter, nsfw); - } else if (postType == PostDataSource.TYPE_SEARCH) { - return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw); - } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { - return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList); - } else { - return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, - postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, userWhere, filter, nsfw); - } - } - } - - private static class NSFWAndSortTypeLiveData extends MediatorLiveData> { - public NSFWAndSortTypeLiveData(LiveData nsfw, LiveData sortType) { - addSource(nsfw, accessToken1 -> setValue(Pair.create(accessToken1, sortType.getValue()))); - addSource(sortType, sortType1 -> setValue(Pair.create(nsfw.getValue(), sortType1))); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java deleted file mode 100644 index 0abd88e9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Post/SubmitPost.java +++ /dev/null @@ -1,478 +0,0 @@ -package ml.docilealligator.infinityforreddit.Post; - -import android.graphics.Bitmap; -import android.os.AsyncTask; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlPullParserFactory; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.StringReader; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import okhttp3.MediaType; -import okhttp3.MultipartBody; -import okhttp3.RequestBody; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class SubmitPost { - public static void submitTextOrLinkPost(Retrofit oauthRetrofit, String accessToken, - Locale locale, String subredditName, String title, String content, - Flair flair, boolean isSpoiler, boolean isNSFW, String kind, - SubmitPostListener submitPostListener) { - submitPost(oauthRetrofit, accessToken, locale, subredditName, title, content, - flair, isSpoiler, isNSFW, kind, null, submitPostListener); - } - - public static void submitImagePost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, - String accessToken, Locale locale, - String subredditName, String title, Bitmap image, Flair flair, - boolean isSpoiler, boolean isNSFW, SubmitPostListener submitPostListener) { - uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, image, - new UploadImageListener() { - @Override - public void uploaded(String imageUrl) { - submitPost(oauthRetrofit, accessToken, locale, - subredditName, title, imageUrl, flair, isSpoiler, isNSFW, - APIUtils.KIND_IMAGE, null, submitPostListener); - } - - @Override - public void uploadFailed(@Nullable String errorMessage) { - submitPostListener.submitFailed(errorMessage); - } - }); - } - - public static void submitVideoPost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, - Retrofit uploadVideoRetrofit, String accessToken, - Locale locale, String subredditName, String title, File buffer, String mimeType, - Bitmap posterBitmap, Flair flair, boolean isSpoiler, boolean isNSFW, - SubmitPostListener submitPostListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - String fileType = mimeType.substring(mimeType.indexOf("/") + 1); - - Map uploadImageParams = new HashMap<>(); - uploadImageParams.put(APIUtils.FILEPATH_KEY, "post_video." + fileType); - uploadImageParams.put(APIUtils.MIMETYPE_KEY, mimeType); - - Call uploadImageCall = api.uploadImage(APIUtils.getOAuthHeader(accessToken), uploadImageParams); - uploadImageCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { - @Override - public void parseSuccessful(Map nameValuePairsMap) { - RequestBody fileBody = RequestBody.create(buffer, MediaType.parse("application/octet-stream")); - MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_video." + fileType, fileBody); - - RedditAPI uploadVideoToAWSApi; - if (fileType.equals("gif")) { - uploadVideoToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); - } else { - uploadVideoToAWSApi = uploadVideoRetrofit.create(RedditAPI.class); - } - Call uploadMediaToAWS = uploadVideoToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); - - uploadMediaToAWS.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { - @Override - public void parseSuccessful(String url) { - uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, - posterBitmap, new UploadImageListener() { - @Override - public void uploaded(String imageUrl) { - if (fileType.equals("gif")) { - submitPost(oauthRetrofit, accessToken, locale, - subredditName, title, url, flair, isSpoiler, isNSFW, - APIUtils.KIND_VIDEOGIF, imageUrl, submitPostListener); - } else { - submitPost(oauthRetrofit, accessToken, locale, - subredditName, title, url, flair, isSpoiler, isNSFW, - APIUtils.KIND_VIDEO, imageUrl, submitPostListener); - } - } - - @Override - public void uploadFailed(@Nullable String errorMessage) { - submitPostListener.submitFailed(errorMessage); - } - }); - } - - @Override - public void parseFailed() { - submitPostListener.submitFailed(null); - } - }).execute(); - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } - - @Override - public void parseFailed() { - submitPostListener.submitFailed(null); - } - }).execute(); - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } - - public static void submitCrosspost(Retrofit oauthRetrofit, String accessToken, - Locale locale, String subredditName, String title, String crosspostFullname, - Flair flair, boolean isSpoiler, boolean isNSFW, String kind, - SubmitPostListener submitPostListener) { - submitPost(oauthRetrofit, accessToken, locale, subredditName, title, crosspostFullname, - flair, isSpoiler, isNSFW, kind, null, submitPostListener); - } - - private static void submitPost(Retrofit oauthRetrofit, String accessToken, - Locale locale, String subredditName, String title, String content, - Flair flair, boolean isSpoiler, boolean isNSFW, String kind, - @Nullable String posterUrl, SubmitPostListener submitPostListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Map params = new HashMap<>(); - params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); - params.put(APIUtils.SR_KEY, subredditName); - params.put(APIUtils.TITLE_KEY, title); - params.put(APIUtils.KIND_KEY, kind); - switch (kind) { - case APIUtils.KIND_SELF: - params.put(APIUtils.TEXT_KEY, content); - break; - case APIUtils.KIND_LINK: - case APIUtils.KIND_IMAGE: - params.put(APIUtils.URL_KEY, content); - break; - case APIUtils.KIND_VIDEOGIF: - params.put(APIUtils.KIND_KEY, APIUtils.KIND_IMAGE); - params.put(APIUtils.URL_KEY, content); - params.put(APIUtils.VIDEO_POSTER_URL_KEY, posterUrl); - break; - case APIUtils.KIND_VIDEO: - params.put(APIUtils.URL_KEY, content); - params.put(APIUtils.VIDEO_POSTER_URL_KEY, posterUrl); - break; - case APIUtils.KIND_CROSSPOST: - params.put(APIUtils.CROSSPOST_FULLNAME_KEY, content); - break; - } - - if (flair != null) { - params.put(APIUtils.FLAIR_TEXT_KEY, flair.getText()); - params.put(APIUtils.FLAIR_ID_KEY, flair.getId()); - } - params.put(APIUtils.SPOILER_KEY, Boolean.toString(isSpoiler)); - params.put(APIUtils.NSFW_KEY, Boolean.toString(isNSFW)); - - Call submitPostCall = api.submit(APIUtils.getOAuthHeader(accessToken), params); - submitPostCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - try { - getSubmittedPost(response.body(), kind, oauthRetrofit, accessToken, - locale, submitPostListener); - } catch (JSONException e) { - e.printStackTrace(); - submitPostListener.submitFailed(null); - } - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } - - private static void uploadImage(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, - String accessToken, Bitmap image, - UploadImageListener uploadImageListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Map uploadImageParams = new HashMap<>(); - uploadImageParams.put(APIUtils.FILEPATH_KEY, "post_image.jpg"); - uploadImageParams.put(APIUtils.MIMETYPE_KEY, "image/jpeg"); - - Call uploadImageCall = api.uploadImage(APIUtils.getOAuthHeader(accessToken), uploadImageParams); - uploadImageCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { - @Override - public void parseSuccessful(Map nameValuePairsMap) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - image.compress(Bitmap.CompressFormat.JPEG, 100, stream); - byte[] byteArray = stream.toByteArray(); - - RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), byteArray); - MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_image.jpg", fileBody); - - RedditAPI uploadMediaToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); - Call uploadMediaToAWS = uploadMediaToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); - - uploadMediaToAWS.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { - @Override - public void parseSuccessful(String url) { - uploadImageListener.uploaded(url); - } - - @Override - public void parseFailed() { - uploadImageListener.uploadFailed(null); - } - }).execute(); - } else { - uploadImageListener.uploadFailed("Error: " + response.code()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - uploadImageListener.uploadFailed(t.getMessage()); - } - }); - } - - @Override - public void parseFailed() { - uploadImageListener.uploadFailed(null); - } - }).execute(); - } else { - uploadImageListener.uploadFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - uploadImageListener.uploadFailed(t.getMessage()); - } - }); - } - - private static void getSubmittedPost(String response, String kind, Retrofit oauthRetrofit, - String accessToken, Locale locale, - SubmitPostListener submitPostListener) throws JSONException { - JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); - if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { - JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) - .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); - if (error.length() != 0) { - String errorString; - if (error.length() >= 2) { - errorString = error.getString(1); - } else { - errorString = error.getString(0); - } - submitPostListener.submitFailed(errorString); - } else { - submitPostListener.submitFailed(null); - } - - return; - } - - if (!kind.equals(APIUtils.KIND_IMAGE) && !kind.equals(APIUtils.KIND_VIDEO) && !kind.equals(APIUtils.KIND_VIDEOGIF)) { - String postId = responseObject.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ID_KEY); - - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Call getPostCall = api.getPostOauth(postId, APIUtils.getOAuthHeader(accessToken)); - getPostCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { - @Override - public void onParsePostSuccess(Post post) { - submitPostListener.submitSuccessful(post); - } - - @Override - public void onParsePostFail() { - submitPostListener.submitFailed(null); - } - }); - } else { - submitPostListener.submitFailed(response.message()); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - submitPostListener.submitFailed(t.getMessage()); - } - }); - } else { - submitPostListener.submitSuccessful(null); - } - } - - public interface SubmitPostListener { - void submitSuccessful(Post post); - - void submitFailed(@Nullable String errorMessage); - } - - private interface UploadImageListener { - void uploaded(String imageUrl); - - void uploadFailed(@Nullable String errorMessage); - } - - private static class ParseJSONResponseFromAWSAsyncTask extends AsyncTask { - private String response; - private ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener; - private Map nameValuePairsMap; - private boolean successful; - ParseJSONResponseFromAWSAsyncTask(String response, ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener) { - this.response = response; - this.parseJSONResponseFromAWSListener = parseJSONResponseFromAWSListener; - nameValuePairsMap = new HashMap<>(); - successful = false; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject responseObject = new JSONObject(response); - JSONArray nameValuePairs = responseObject.getJSONObject(JSONUtils.ARGS_KEY).getJSONArray(JSONUtils.FIELDS_KEY); - - nameValuePairsMap = new HashMap<>(); - for (int i = 0; i < nameValuePairs.length(); i++) { - nameValuePairsMap.put(nameValuePairs.getJSONObject(i).getString(JSONUtils.NAME_KEY), - APIUtils.getRequestBody(nameValuePairs.getJSONObject(i).getString(JSONUtils.VALUE_KEY))); - } - - successful = true; - } catch (JSONException e) { - e.printStackTrace(); - successful = false; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (successful) { - parseJSONResponseFromAWSListener.parseSuccessful(nameValuePairsMap); - } else { - parseJSONResponseFromAWSListener.parseFailed(); - } - } - - interface ParseJSONResponseFromAWSListener { - void parseSuccessful(Map nameValuePairsMap); - - void parseFailed(); - } - } - - private static class ParseXMLReponseFromAWSAsyncTask extends AsyncTask { - private String response; - private ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener; - private String imageUrl; - private boolean successful; - ParseXMLReponseFromAWSAsyncTask(String response, ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener) { - this.response = response; - this.parseXMLResponseFromAWSListener = parseXMLResponseFromAWSListener; - successful = false; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); - xmlPullParser.setInput(new StringReader(response)); - - boolean isLocationTag = false; - int eventType = xmlPullParser.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - if (xmlPullParser.getName().equals("Location")) { - isLocationTag = true; - } - } else if (eventType == XmlPullParser.TEXT) { - if (isLocationTag) { - imageUrl = xmlPullParser.getText(); - successful = true; - return null; - } - } - eventType = xmlPullParser.next(); - } - } catch (XmlPullParserException | IOException e) { - e.printStackTrace(); - successful = false; - } - - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (successful) { - parseXMLResponseFromAWSListener.parseSuccessful(imageUrl); - } else { - parseXMLResponseFromAWSListener.parseFailed(); - } - } - - interface ParseXMLResponseFromAWSListener { - void parseSuccessful(String url); - - void parseFailed(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java index 1b1134b9..82260f00 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PullNotificationWorker.java @@ -26,18 +26,18 @@ import java.util.Map; import javax.inject.Inject; import javax.inject.Named; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Account.Account; -import ml.docilealligator.infinityforreddit.Activity.InboxActivity; -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Message.FetchMessage; -import ml.docilealligator.infinityforreddit.Message.Message; -import ml.docilealligator.infinityforreddit.Message.ParseMessage; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.NotificationUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.activities.InboxActivity; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.message.FetchMessage; +import ml.docilealligator.infinityforreddit.message.Message; +import ml.docilealligator.infinityforreddit.message.ParseMessage; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.NotificationUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Call; import retrofit2.Response; import retrofit2.Retrofit; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/DeleteRecentSearchQuery.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/DeleteRecentSearchQuery.java deleted file mode 100644 index f4ada66c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/DeleteRecentSearchQuery.java +++ /dev/null @@ -1,44 +0,0 @@ -package ml.docilealligator.infinityforreddit.RecentSearchQuery; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.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/ml/docilealligator/infinityforreddit/RecentSearchQuery/InsertRecentSearchQuery.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/InsertRecentSearchQuery.java deleted file mode 100644 index 19278a70..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/InsertRecentSearchQuery.java +++ /dev/null @@ -1,53 +0,0 @@ -package ml.docilealligator.infinityforreddit.RecentSearchQuery; - -import android.os.AsyncTask; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class InsertRecentSearchQuery { - public interface InsertRecentSearchQueryListener { - 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) { - List recentSearchQueries = recentSearchQueryDao.getAllRecentSearchQueries(username); - if (recentSearchQueries.size() >= 5) { - for (int i = 4; i < recentSearchQueries.size(); i++) { - recentSearchQueryDao.deleteRecentSearchQueries(recentSearchQueries.get(i)); - } - } - - recentSearchQueryDao.insert(new RecentSearchQuery(username, recentSearchQuery)); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - insertRecentSearchQueryListener.success(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQuery.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQuery.java deleted file mode 100644 index 70c9ed5a..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQuery.java +++ /dev/null @@ -1,43 +0,0 @@ -package ml.docilealligator.infinityforreddit.RecentSearchQuery; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.ForeignKey; - -import ml.docilealligator.infinityforreddit.Account.Account; - -@Entity(tableName = "recent_search_queries", primaryKeys = {"username", "search_query"}, - foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", - childColumns = "username", onDelete = ForeignKey.CASCADE)) -public class RecentSearchQuery { - @NonNull - @ColumnInfo(name = "username") - private String username; - @NonNull - @ColumnInfo(name = "search_query") - private String searchQuery; - - public RecentSearchQuery(@NonNull String username, @NonNull String searchQuery) { - this.username = username; - this.searchQuery = searchQuery; - } - - @NonNull - public String getUsername() { - return username; - } - - public void setUsername(@NonNull String username) { - this.username = username; - } - - @NonNull - public String getSearchQuery() { - return searchQuery; - } - - public void setSearchQuery(@NonNull String searchQuery) { - this.searchQuery = searchQuery; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryDao.java deleted file mode 100644 index 5db9718e..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryDao.java +++ /dev/null @@ -1,25 +0,0 @@ -package ml.docilealligator.infinityforreddit.RecentSearchQuery; - -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 RecentSearchQueryDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(RecentSearchQuery recentSearchQuery); - - @Query("SELECT * FROM recent_search_queries WHERE username = :username") - LiveData> getAllRecentSearchQueriesLiveData(String username); - - @Query("SELECT * FROM recent_search_queries WHERE username = :username") - List getAllRecentSearchQueries(String username); - - @Delete - void deleteRecentSearchQueries(RecentSearchQuery recentSearchQuery); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryRepository.java deleted file mode 100644 index 259ba28d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryRepository.java +++ /dev/null @@ -1,19 +0,0 @@ -package ml.docilealligator.infinityforreddit.RecentSearchQuery; - -import androidx.lifecycle.LiveData; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class RecentSearchQueryRepository { - private LiveData> mAllRecentSearchQueries; - - RecentSearchQueryRepository(RedditDataRoomDatabase redditDataRoomDatabase, String username) { - mAllRecentSearchQueries = redditDataRoomDatabase.recentSearchQueryDao().getAllRecentSearchQueriesLiveData(username); - } - - LiveData> getAllRecentSearchQueries() { - return mAllRecentSearchQueries; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryViewModel.java deleted file mode 100644 index 9b792117..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RecentSearchQuery/RecentSearchQueryViewModel.java +++ /dev/null @@ -1,38 +0,0 @@ -package ml.docilealligator.infinityforreddit.RecentSearchQuery; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class RecentSearchQueryViewModel extends ViewModel { - private LiveData> mAllRecentSearchQueries; - - public RecentSearchQueryViewModel(RedditDataRoomDatabase redditDataRoomDatabase, String username) { - mAllRecentSearchQueries = new RecentSearchQueryRepository(redditDataRoomDatabase, username).getAllRecentSearchQueries(); - } - - public LiveData> getAllRecentSearchQueries() { - return mAllRecentSearchQueries; - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private String mUsername; - - public Factory(RedditDataRoomDatabase redditDataRoomDatabase, String username) { - mRedditDataRoomDatabase = redditDataRoomDatabase; - mUsername = username; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new RecentSearchQueryViewModel(mRedditDataRoomDatabase, mUsername); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java index 2d4c1301..6c376569 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditDataRoomDatabase.java @@ -10,24 +10,24 @@ import androidx.room.RoomDatabase; import androidx.room.migration.Migration; import androidx.sqlite.db.SupportSQLiteDatabase; -import ml.docilealligator.infinityforreddit.Account.Account; -import ml.docilealligator.infinityforreddit.Account.AccountDao; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeDao; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiReddit; -import ml.docilealligator.infinityforreddit.MultiReddit.MultiRedditDao; -import ml.docilealligator.infinityforreddit.RecentSearchQuery.RecentSearchQuery; -import ml.docilealligator.infinityforreddit.RecentSearchQuery.RecentSearchQueryDao; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditDao; -import ml.docilealligator.infinityforreddit.Subreddit.SubredditData; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilter; -import ml.docilealligator.infinityforreddit.SubredditFilter.SubredditFilterDao; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditDao; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserDao; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.User.UserDao; -import ml.docilealligator.infinityforreddit.User.UserData; +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.account.AccountDao; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeDao; +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.MultiRedditDao; +import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQuery; +import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQueryDao; +import ml.docilealligator.infinityforreddit.subreddit.SubredditDao; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilterDao; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditDao; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserDao; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.user.UserDao; +import ml.docilealligator.infinityforreddit.user.UserData; @Database(entities = {Account.class, SubredditData.class, SubscribedSubredditData.class, UserData.class, SubscribedUserData.class, MultiReddit.class, CustomTheme.class, RecentSearchQuery.class, SubredditFilter.class}, version = 13) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java index 305da882..dc69a541 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ReportThing.java @@ -5,8 +5,8 @@ import androidx.annotation.NonNull; import java.util.HashMap; import java.util.Map; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SaveThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SaveThing.java index 4b510d8c..262a22d4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SaveThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SaveThing.java @@ -5,8 +5,8 @@ import androidx.annotation.NonNull; import java.util.HashMap; import java.util.Map; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java index 92761426..e2607976 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java @@ -12,9 +12,9 @@ import org.json.JSONObject; import java.util.HashMap; import java.util.Map; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadMediaService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadMediaService.java deleted file mode 100644 index 49182903..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadMediaService.java +++ /dev/null @@ -1,470 +0,0 @@ -package ml.docilealligator.infinityforreddit.Service; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Intent; -import android.content.SharedPreferences; -import android.media.MediaScannerConnection; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Environment; -import android.os.IBinder; -import android.provider.MediaStore; - -import androidx.annotation.NonNull; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; -import androidx.documentfile.provider.DocumentFile; - -import org.greenrobot.eventbus.EventBus; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.API.DownloadFile; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.DownloadProgressResponseBody; -import ml.docilealligator.infinityforreddit.Event.DownloadMediaEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.NotificationUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import okhttp3.OkHttpClient; -import okhttp3.ResponseBody; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -import static android.os.Environment.getExternalStoragePublicDirectory; - -public class DownloadMediaService extends Service { - public static final String EXTRA_URL = "EU"; - public static final String EXTRA_FILE_NAME = "EFN"; - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - public static final String EXTRA_MEDIA_TYPE = "EIG"; - public static final int EXTRA_MEDIA_TYPE_IMAGE = 0; - public static final int EXTRA_MEDIA_TYPE_GIF = 1; - public static final int EXTRA_MEDIA_TYPE_VIDEO = 2; - - private static final int NO_ERROR = -1; - private static final int ERROR_CANNOT_GET_DESTINATION_DIRECTORY = 0; - private static final int ERROR_FILE_CANNOT_DOWNLOAD = 1; - private static final int ERROR_FILE_CANNOT_SAVE = 2; - @Inject - @Named("download_media") - Retrofit retrofit; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private int mediaType; - private String mimeType; - private NotificationManagerCompat notificationManager; - private NotificationCompat.Builder builder; - private boolean downloadFinished; - - public DownloadMediaService() { - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - private String getNotificationChannelId() { - switch (mediaType) { - case EXTRA_MEDIA_TYPE_GIF: - return NotificationUtils.CHANNEL_ID_DOWNLOAD_GIF; - case EXTRA_MEDIA_TYPE_VIDEO: - return NotificationUtils.CHANNEL_ID_DOWNLOAD_VIDEO; - default: - return NotificationUtils.CHANNEL_ID_DOWNLOAD_IMAGE; - } - } - - private String getNotificationChannel() { - switch (mediaType) { - case EXTRA_MEDIA_TYPE_GIF: - return NotificationUtils.CHANNEL_DOWNLOAD_GIF; - case EXTRA_MEDIA_TYPE_VIDEO: - return NotificationUtils.CHANNEL_DOWNLOAD_VIDEO; - default: - return NotificationUtils.CHANNEL_DOWNLOAD_IMAGE; - } - } - - private int getNotificationId() { - switch (mediaType) { - case EXTRA_MEDIA_TYPE_GIF: - return NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID; - case EXTRA_MEDIA_TYPE_VIDEO: - return NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID; - default: - return NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID; - } - } - - private String getDownloadLocation() { - switch (mediaType) { - case EXTRA_MEDIA_TYPE_GIF: - return mSharedPreferences.getString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, ""); - case EXTRA_MEDIA_TYPE_VIDEO: - return mSharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, ""); - default: - return mSharedPreferences.getString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, ""); - } - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - notificationManager = NotificationManagerCompat.from(this); - builder = new NotificationCompat.Builder(this, getNotificationChannelId()); - - downloadFinished = false; - String fileUrl = intent.getStringExtra(EXTRA_URL); - final String[] fileName = {intent.getStringExtra(EXTRA_FILE_NAME)}; - String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); - mediaType = intent.getIntExtra(EXTRA_MEDIA_TYPE, EXTRA_MEDIA_TYPE_IMAGE); - mimeType = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? "video/*" : "image/*"; - - final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() { - long time = 0; - - @Override public void update(long bytesRead, long contentLength, boolean done) { - if (!done) { - if (contentLength != -1) { - long currentTime = System.currentTimeMillis(); - if (currentTime - time > 1000) { - time = currentTime; - updateNotification(0, (int) ((100 * bytesRead) / contentLength), null); - } - } - } - } - }; - - OkHttpClient client = new OkHttpClient.Builder() - .addNetworkInterceptor(chain -> { - okhttp3.Response originalResponse = chain.proceed(chain.request()); - return originalResponse.newBuilder() - .body(new DownloadProgressResponseBody(originalResponse.body(), progressListener)) - .build(); - }) - .build(); - - retrofit = retrofit.newBuilder().client(client).build(); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel serviceChannel; - serviceChannel = new NotificationChannel( - getNotificationChannelId(), - getNotificationChannel(), - NotificationManager.IMPORTANCE_LOW - ); - - NotificationManagerCompat manager = NotificationManagerCompat.from(this); - manager.createNotificationChannel(serviceChannel); - } - - switch (mediaType) { - case EXTRA_MEDIA_TYPE_GIF: - startForeground( - NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID, - createNotification(fileName[0]) - ); - break; - case EXTRA_MEDIA_TYPE_VIDEO: - startForeground( - NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID, - createNotification(fileName[0]) - ); - break; - default: - startForeground( - NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID, - createNotification(fileName[0]) - ); - } - - boolean separateDownloadFolder = mSharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false); - - retrofit.create(DownloadFile.class).downloadFile(fileUrl).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful() && response.body() != null) { - String destinationFileDirectory = getDownloadLocation(); - String destinationFileUriString; - boolean isDefaultDestination; - if (destinationFileDirectory.equals("")) { - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - File directory = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); - if (directory != null) { - String directoryPath = separateDownloadFolder && subredditName != null && !subredditName.equals("") ? directory.getAbsolutePath() + "/Infinity/" + subredditName + "/" : directory.getAbsolutePath() + "/Infinity/"; - File infinityDir = new File(directoryPath); - if (!infinityDir.exists() && !infinityDir.mkdirs()) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - destinationFileUriString = directoryPath + fileName[0]; - } else { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - } else { - String dir = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? Environment.DIRECTORY_MOVIES : Environment.DIRECTORY_PICTURES; - destinationFileUriString = separateDownloadFolder && subredditName != null && !subredditName.equals("") ? dir + "/Infinity/" + subredditName + "/" : dir + "/Infinity/"; - } - isDefaultDestination = true; - } else { - isDefaultDestination = false; - DocumentFile picFile; - DocumentFile dir; - if (separateDownloadFolder && subredditName != null && !subredditName.equals("")) { - dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory)); - if (dir == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - dir = dir.findFile(subredditName); - if (dir == null) { - dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory)).createDirectory(subredditName); - if (dir == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - } - } else { - dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory)); - if (dir == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - } - DocumentFile checkForDuplicates = dir.findFile(fileName[0]); - int extensionPosition = fileName[0].lastIndexOf('.'); - String extension = fileName[0].substring(extensionPosition); - int num = 1; - while (checkForDuplicates != null) { - fileName[0] = fileName[0].substring(0, extensionPosition) + " (" + num + ")" + extension; - checkForDuplicates = dir.findFile(fileName[0]); - num++; - } - picFile = dir.createFile(mimeType, fileName[0]); - if (picFile == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - destinationFileUriString = picFile.getUri().toString(); - } - - new SaveImageOrGifAndCopyToExternalStorageAsyncTask(response.body(), mediaType, - isDefaultDestination, fileName[0], destinationFileUriString, getContentResolver(), - (destinationFileUri, errorCode) -> downloadFinished(destinationFileUri, errorCode)).execute(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - downloadFinished(null, ERROR_FILE_CANNOT_DOWNLOAD); - } - }); - - return START_NOT_STICKY; - } - - private Notification createNotification(String fileName) { - builder.setContentTitle(fileName).setContentText(getString(R.string.downloading)) - .setProgress(100, 0, false); - return builder.setSmallIcon(R.drawable.ic_notification) - .setColor(mCustomThemeWrapper.getColorPrimaryLightTheme()) - .build(); - } - - private void updateNotification(int contentStringResId, int progress, PendingIntent pendingIntent) { - if (notificationManager != null) { - if (progress < 0) { - builder.setProgress(0, 0, false); - } else { - builder.setProgress(100, progress, false); - } - if (contentStringResId != 0) { - builder.setContentText(getString(contentStringResId)); - } - if (pendingIntent != null) { - builder.setContentIntent(pendingIntent); - } - notificationManager.notify(getNotificationId(), builder.build()); - } - } - - private void downloadFinished(Uri destinationFileUri, int errorCode) { - if (downloadFinished) { - return; - } - - downloadFinished = true; - if (errorCode != NO_ERROR) { - switch (errorCode) { - case ERROR_CANNOT_GET_DESTINATION_DIRECTORY: - updateNotification(R.string.downloading_image_or_gif_failed_cannot_get_destination_directory, -1, null); - break; - case ERROR_FILE_CANNOT_DOWNLOAD: - updateNotification(R.string.downloading_media_failed_cannot_download_media, -1, null); - break; - case ERROR_FILE_CANNOT_SAVE: - updateNotification(R.string.downloading_media_failed_cannot_save_to_destination_directory, -1, null); - break; - } - EventBus.getDefault().post(new DownloadMediaEvent(false)); - } else { - MediaScannerConnection.scanFile( - this, new String[]{destinationFileUri.toString()}, null, - (path, uri) -> { - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(destinationFileUri, mimeType); - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); - updateNotification(R.string.downloading_media_finished, -1, pendingIntent); - EventBus.getDefault().post(new DownloadMediaEvent(true)); - } - ); - } - stopForeground(false); - } - - private static class SaveImageOrGifAndCopyToExternalStorageAsyncTask extends AsyncTask { - - private ResponseBody response; - private int mediaType; - private boolean isDefaultDestination; - private String destinationFileName; - @NonNull - private String destinationFileUriString; - private ContentResolver contentResolver; - private SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener saveImageOrGifAndCopyToExternalStorageAsyncTaskListener; - private int errorCode = NO_ERROR; - - interface SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener { - void finished(Uri destinationFileUri, int errorCode); - } - - public SaveImageOrGifAndCopyToExternalStorageAsyncTask(ResponseBody response, int mediaType, - boolean isDefaultDestination, - String destinationFileName, - @NonNull String destinationFileUriString, - ContentResolver contentResolver, - SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener saveImageOrGifAndCopyToExternalStorageAsyncTaskListener) { - this.response = response; - this.mediaType = mediaType; - this.isDefaultDestination = isDefaultDestination; - this.destinationFileName = destinationFileName; - this.destinationFileUriString = destinationFileUriString; - this.contentResolver = contentResolver; - this.saveImageOrGifAndCopyToExternalStorageAsyncTaskListener = saveImageOrGifAndCopyToExternalStorageAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try { - writeResponseBodyToDisk(response); - } catch (IOException e) { - errorCode = ERROR_FILE_CANNOT_SAVE; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - saveImageOrGifAndCopyToExternalStorageAsyncTaskListener.finished(Uri.parse(destinationFileUriString), errorCode); - } - - private void writeResponseBodyToDisk(ResponseBody body) throws IOException { - if (isDefaultDestination) { - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - InputStream inputStream = body.byteStream(); - OutputStream outputStream = new FileOutputStream(destinationFileUriString); - byte[] fileReader = new byte[4096]; - - long fileSize = body.contentLength(); - long fileSizeDownloaded = 0; - - while (true) { - int read = inputStream.read(fileReader); - - if (read == -1) { - break; - } - - outputStream.write(fileReader, 0, read); - - fileSizeDownloaded += read; - } - - outputStream.flush(); - } else { - ContentValues contentValues = new ContentValues(); - contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, destinationFileName); - contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mediaType == EXTRA_MEDIA_TYPE_VIDEO ? "video/*" : "image/*"); - contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFileUriString); - contentValues.put(MediaStore.Images.Media.IS_PENDING, 1); - - final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; - Uri uri = contentResolver.insert(contentUri, contentValues); - - if (uri == null) { - throw new IOException("Failed to create new MediaStore record."); - } - - OutputStream stream = contentResolver.openOutputStream(uri); - - if (stream == null) { - throw new IOException("Failed to get output stream."); - } - - InputStream in = body.byteStream(); - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - stream.write(buf, 0, len); - } - contentValues.clear(); - contentValues.put(MediaStore.Images.Media.IS_PENDING, 0); - contentResolver.update(uri, contentValues, null, null); - destinationFileUriString = uri.toString(); - } - } else { - try (OutputStream stream = contentResolver.openOutputStream(Uri.parse(destinationFileUriString))) { - if (stream == null) { - throw new IOException("Failed to get output stream."); - } - - InputStream in = body.byteStream(); - - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - stream.write(buf, 0, len); - } - } - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadRedditVideoService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadRedditVideoService.java deleted file mode 100644 index 28133592..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/DownloadRedditVideoService.java +++ /dev/null @@ -1,662 +0,0 @@ -package ml.docilealligator.infinityforreddit.Service; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.app.Service; -import android.content.ContentResolver; -import android.content.ContentValues; -import android.content.Intent; -import android.content.SharedPreferences; -import android.media.MediaCodec; -import android.media.MediaExtractor; -import android.media.MediaFormat; -import android.media.MediaMuxer; -import android.media.MediaScannerConnection; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.Environment; -import android.os.IBinder; -import android.provider.MediaStore; - -import androidx.annotation.NonNull; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; -import androidx.documentfile.provider.DocumentFile; - -import org.greenrobot.eventbus.EventBus; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.API.DownloadFile; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.DownloadProgressResponseBody; -import ml.docilealligator.infinityforreddit.Event.DownloadRedditVideoEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.NotificationUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; -import okhttp3.OkHttpClient; -import okhttp3.ResponseBody; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -import static android.os.Environment.getExternalStoragePublicDirectory; - -public class DownloadRedditVideoService extends Service { - - public static final String EXTRA_VIDEO_URL = "EVU"; - public static final String EXTRA_SUBREDDIT = "ES"; - public static final String EXTRA_POST_ID = "EPI"; - - private static final int NO_ERROR = -1; - private static final int ERROR_CANNOT_GET_CACHE_DIRECTORY = 0; - private static final int ERROR_VIDEO_FILE_CANNOT_DOWNLOAD = 1; - private static final int ERROR_VIDEO_FILE_CANNOT_SAVE = 2; - private static final int ERROR_AUDIO_FILE_CANNOT_SAVE = 3; - private static final int ERROR_MUX_FAILED = 4; - private static final int ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE = 5; - private static final int ERROR_CANNOT_GET_DESTINATION_DIRECTORY = 6; - - @Inject - @Named("download_media") - Retrofit retrofit; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - @Inject - CustomThemeWrapper customThemeWrapper; - String resultFile; - private NotificationManagerCompat notificationManager; - private NotificationCompat.Builder builder; - - public DownloadRedditVideoService() { - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - notificationManager = NotificationManagerCompat.from(this); - builder = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO); - - final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() { - long time = 0; - - @Override public void update(long bytesRead, long contentLength, boolean done) { - if (!done) { - if (contentLength != -1) { - long currentTime = System.currentTimeMillis(); - if (currentTime - time > 1000) { - time = currentTime; - updateNotification(0, (int) ((100 * bytesRead) / contentLength), null); - } - } - } - } - }; - - OkHttpClient client = new OkHttpClient.Builder() - .addNetworkInterceptor(chain -> { - okhttp3.Response originalResponse = chain.proceed(chain.request()); - return originalResponse.newBuilder() - .body(new DownloadProgressResponseBody(originalResponse.body(), progressListener)) - .build(); - }) - .build(); - - retrofit = retrofit.newBuilder().client(client).build(); - - String videoUrl = intent.getStringExtra(EXTRA_VIDEO_URL); - String audioUrl = videoUrl.substring(0, videoUrl.lastIndexOf('/')) + "/DASH_audio.mp4"; - String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT); - final String[] fileNameWithoutExtension = {subredditName + "-" + intent.getStringExtra(EXTRA_POST_ID)}; - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel serviceChannel; - serviceChannel = new NotificationChannel( - NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO, - NotificationUtils.CHANNEL_DOWNLOAD_REDDIT_VIDEO, - NotificationManager.IMPORTANCE_LOW - ); - - NotificationManagerCompat manager = NotificationManagerCompat.from(this); - manager.createNotificationChannel(serviceChannel); - } - - startForeground( - NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID, - createNotification(fileNameWithoutExtension[0] + ".mp4") - ); - - DownloadFile downloadFile = retrofit.create(DownloadFile.class); - - boolean separateDownloadFolder = sharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false); - - File directory = getExternalCacheDir(); - String destinationFileName = fileNameWithoutExtension[0] + ".mp4"; - if (directory != null) { - String directoryPath = directory.getAbsolutePath() + "/"; - downloadFile.downloadFile(videoUrl).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response videoResponse) { - if (videoResponse.isSuccessful() && videoResponse.body() != null) { - String destinationFileDirectory = sharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, ""); - String destinationFileUriString; - boolean isDefaultDestination; - if (destinationFileDirectory.equals("")) { - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - File directory = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); - if (directory != null) { - String directoryPath = separateDownloadFolder ? directory.getAbsolutePath() + "/Infinity/" + subredditName + "/" : directory.getAbsolutePath() + "/Infinity/"; - File infinityDir = new File(directoryPath); - if (!infinityDir.exists() && !infinityDir.mkdir()) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - destinationFileUriString = directoryPath + destinationFileName; - } else { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - } else { - destinationFileUriString = separateDownloadFolder ? Environment.DIRECTORY_MOVIES + "/Infinity/" + subredditName + "/" : Environment.DIRECTORY_MOVIES + "/Infinity/"; - } - isDefaultDestination = true; - } else { - isDefaultDestination = false; - DocumentFile picFile; - DocumentFile dir; - if (separateDownloadFolder) { - dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory)); - if (dir == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - dir = dir.findFile(subredditName); - if (dir == null) { - dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory)).createDirectory(subredditName); - if (dir == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - } - } else { - dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory)); - if (dir == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - } - DocumentFile checkForDuplicates = dir.findFile(destinationFileName); - int num = 1; - while (checkForDuplicates != null) { - fileNameWithoutExtension[0] = fileNameWithoutExtension[0] + " (" + num + ")"; - checkForDuplicates = dir.findFile(fileNameWithoutExtension[0] + ".mp4"); - num++; - } - picFile = dir.createFile("video/*", fileNameWithoutExtension[0] + ".mp4"); - if (picFile == null) { - downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); - return; - } - destinationFileUriString = picFile.getUri().toString(); - } - - updateNotification(R.string.downloading_reddit_video_audio_track, 0, null); - downloadFile.downloadFile(audioUrl).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response audioResponse) { - if (audioResponse.isSuccessful() && audioResponse.body() != null) { - String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4"; - String audioFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp3"; - String outputFilePath = directoryPath + fileNameWithoutExtension[0] + ".mp4"; - new SaveTempMuxAndCopyAsyncTask(videoResponse.body(), - audioResponse.body(), videoFilePath, audioFilePath, outputFilePath, - destinationFileName, destinationFileUriString, isDefaultDestination, - getContentResolver(), - new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() { - @Override - public void finished(Uri destinationFileUri, int errorCode) { - new File(videoFilePath).delete(); - new File(audioFilePath).delete(); - new File(outputFilePath).delete(); - downloadFinished(destinationFileUri, errorCode); - } - - @Override - public void updateProgressNotification(int stringResId) { - updateNotification(stringResId, -1, null); - } - }).execute(); - } else { - String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4"; - new SaveTempMuxAndCopyAsyncTask(videoResponse.body(), - null, videoFilePath, null, null, - destinationFileName, destinationFileUriString, isDefaultDestination, - getContentResolver(), - new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() { - @Override - public void finished(Uri destinationFileUri, int errorCode) { - new File(videoFilePath).delete(); - downloadFinished(destinationFileUri, errorCode); - } - - @Override - public void updateProgressNotification(int stringResId) { - updateNotification(stringResId, -1, null); - } - }).execute(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4"; - new SaveTempMuxAndCopyAsyncTask(videoResponse.body(), - null, videoFilePath, null, null, - destinationFileName, destinationFileUriString, isDefaultDestination, - getContentResolver(), - new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() { - @Override - public void finished(Uri destinationFileUri, int errorCode) { - new File(videoFilePath).delete(); - downloadFinished(destinationFileUri, errorCode); - } - - @Override - public void updateProgressNotification(int stringResId) { - updateNotification(stringResId, -1, null); - } - }).execute(); - } - }); - } else { - downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD); - } - }); - } else { - downloadFinished(null, ERROR_CANNOT_GET_CACHE_DIRECTORY); - } - - return START_NOT_STICKY; - } - - private void downloadFinished(Uri destinationFileUri, int errorCode) { - if (errorCode != NO_ERROR) { - switch (errorCode) { - case ERROR_CANNOT_GET_CACHE_DIRECTORY: - updateNotification(R.string.downloading_reddit_video_failed_cannot_get_cache_directory, -1, null); - break; - case ERROR_VIDEO_FILE_CANNOT_DOWNLOAD: - updateNotification(R.string.downloading_reddit_video_failed_cannot_download_video, -1, null); - break; - case ERROR_VIDEO_FILE_CANNOT_SAVE: - updateNotification(R.string.downloading_reddit_video_failed_cannot_save_video, -1, null); - break; - case ERROR_AUDIO_FILE_CANNOT_SAVE: - updateNotification(R.string.downloading_reddit_video_failed_cannot_save_audio, -1, null); - break; - case ERROR_MUX_FAILED: - updateNotification(R.string.downloading_reddit_video_failed_cannot_mux, -1, null); - break; - case ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE: - updateNotification(R.string.downloading_reddit_video_failed_cannot_save_mux_video, -1, null); - break; - case ERROR_CANNOT_GET_DESTINATION_DIRECTORY: - updateNotification(R.string.downloading_media_failed_cannot_save_to_destination_directory, -1, null); - break; - } - EventBus.getDefault().post(new DownloadRedditVideoEvent(false)); - } else { - MediaScannerConnection.scanFile( - this, new String[]{destinationFileUri.toString()}, null, - (path, uri) -> { - Intent intent = new Intent(); - intent.setAction(android.content.Intent.ACTION_VIEW); - intent.setDataAndType(destinationFileUri, "video/*"); - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); - updateNotification(R.string.downloading_reddit_video_finished, -1, pendingIntent); - EventBus.getDefault().post(new DownloadRedditVideoEvent(true)); - } - ); - } - stopForeground(false); - } - - private Notification createNotification(String fileName) { - builder.setContentTitle(fileName).setContentText(getString(R.string.downloading_reddit_video)).setProgress(100, 0, false); - return builder.setSmallIcon(R.drawable.ic_notification) - .setColor(customThemeWrapper.getColorPrimaryLightTheme()) - .build(); - } - - private void updateNotification(int contentStringResId, int progress, PendingIntent pendingIntent) { - if (notificationManager != null) { - if (progress < 0) { - builder.setProgress(0, 0, false); - } else { - builder.setProgress(100, progress, false); - } - if (contentStringResId != 0) { - builder.setContentText(getString(contentStringResId)); - } - if (pendingIntent != null) { - builder.setContentIntent(pendingIntent); - } - notificationManager.notify(NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID, builder.build()); - } - } - - private static class SaveTempMuxAndCopyAsyncTask extends AsyncTask { - - private ResponseBody videoResponse; - private ResponseBody audioResponse; - private String videoFilePath; - private String audioFilePath; - private String outputFilePath; - private String destinationFileName; - @NonNull - private String destinationFileUriString; - private boolean isDefaultDestination; - private ContentResolver contentResolver; - private SaveTempMuxAndCopyAsyncTaskListener saveTempMuxAndCopyAsyncTaskListener; - private int errorCode = NO_ERROR; - - public SaveTempMuxAndCopyAsyncTask(ResponseBody videoResponse, ResponseBody audioResponse, - String videoFilePath, String audioFilePath, String outputFilePath, - String destinationFileName, @NonNull String destinationFileUriString, - boolean isDefaultDestination, ContentResolver contentResolver, - SaveTempMuxAndCopyAsyncTaskListener saveTempMuxAndCopyAsyncTaskListener) { - this.videoResponse = videoResponse; - this.audioResponse = audioResponse; - this.videoFilePath = videoFilePath; - this.audioFilePath = audioFilePath; - this.outputFilePath = outputFilePath; - this.destinationFileName = destinationFileName; - this.destinationFileUriString = destinationFileUriString; - this.isDefaultDestination = isDefaultDestination; - this.contentResolver = contentResolver; - this.saveTempMuxAndCopyAsyncTaskListener = saveTempMuxAndCopyAsyncTaskListener; - } - - @Override - protected void onProgressUpdate(Integer... values) { - super.onProgressUpdate(values); - saveTempMuxAndCopyAsyncTaskListener.updateProgressNotification(values[0]); - } - - @Override - protected Void doInBackground(Void... voids) { - String savedVideoFilePath = writeResponseBodyToDisk(videoResponse, videoFilePath); - if (savedVideoFilePath == null) { - errorCode = ERROR_VIDEO_FILE_CANNOT_SAVE; - return null; - } - if (audioResponse != null) { - String savedAudioFilePath = writeResponseBodyToDisk(audioResponse, audioFilePath); - if (savedAudioFilePath == null) { - errorCode = ERROR_AUDIO_FILE_CANNOT_SAVE; - return null; - } - - publishProgress(R.string.downloading_reddit_video_muxing); - if (!muxVideoAndAudio(videoFilePath, audioFilePath, outputFilePath)) { - errorCode = ERROR_MUX_FAILED; - return null; - } - - publishProgress(R.string.downloading_reddit_video_save_file_to_public_dir); - try { - copyToDestination(outputFilePath); - } catch (IOException e) { - e.printStackTrace(); - errorCode = ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE; - } - } else { - publishProgress(R.string.downloading_reddit_video_save_file_to_public_dir); - try { - copyToDestination(videoFilePath); - } catch (IOException e) { - e.printStackTrace(); - errorCode = ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE; - } - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - saveTempMuxAndCopyAsyncTaskListener.finished(Uri.parse(destinationFileUriString), errorCode); - } - - private String writeResponseBodyToDisk(ResponseBody body, String filePath) { - try { - File file = new File(filePath); - - InputStream inputStream = null; - OutputStream outputStream = null; - - try { - byte[] fileReader = new byte[4096]; - - long fileSize = body.contentLength(); - long fileSizeDownloaded = 0; - - inputStream = body.byteStream(); - outputStream = new FileOutputStream(file); - - while (true) { - int read = inputStream.read(fileReader); - - if (read == -1) { - break; - } - - outputStream.write(fileReader, 0, read); - - fileSizeDownloaded += read; - } - - outputStream.flush(); - - return file.getPath(); - } catch (IOException e) { - return null; - } finally { - if (inputStream != null) { - inputStream.close(); - } - - if (outputStream != null) { - outputStream.close(); - } - } - } catch (IOException e) { - return null; - } - } - - private boolean muxVideoAndAudio(String videoFilePath, String audioFilePath, String outputFilePath) { - try { - File file = new File(outputFilePath); - file.createNewFile(); - MediaExtractor videoExtractor = new MediaExtractor(); - videoExtractor.setDataSource(videoFilePath); - MediaExtractor audioExtractor = new MediaExtractor(); - audioExtractor.setDataSource(audioFilePath); - MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); - - videoExtractor.selectTrack(0); - MediaFormat videoFormat = videoExtractor.getTrackFormat(0); - int videoTrack = muxer.addTrack(videoFormat); - - audioExtractor.selectTrack(0); - MediaFormat audioFormat = audioExtractor.getTrackFormat(0); - int audioTrack = muxer.addTrack(audioFormat); - boolean sawEOS = false; - int offset = 100; - int sampleSize = 4096 * 1024; - ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize); - ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize); - MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo(); - MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo(); - - videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); - audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); - - muxer.start(); - - int muxedSize = 0; - while (!sawEOS) { - videoBufferInfo.offset = offset; - videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset); - - if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { - sawEOS = true; - videoBufferInfo.size = 0; - } else { - videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime(); - videoBufferInfo.flags = videoExtractor.getSampleFlags(); - muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo); - muxedSize += videoTrack; - videoExtractor.advance(); - } - } - - boolean sawEOS2 = false; - while (!sawEOS2) { - audioBufferInfo.offset = offset; - audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset); - - if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { - sawEOS2 = true; - audioBufferInfo.size = 0; - } else { - audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime(); - audioBufferInfo.flags = audioExtractor.getSampleFlags(); - muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo); - audioExtractor.advance(); - } - } - - muxer.stop(); - muxer.release(); - } catch (IllegalArgumentException ignore) { - } catch (IOException e) { - e.printStackTrace(); - return false; - } - - return true; - } - - private void copyToDestination(String srcPath) throws IOException { - if (isDefaultDestination) { - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { - InputStream in = new FileInputStream(srcPath); - OutputStream out = new FileOutputStream(destinationFileUriString); - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); - } - - new File(srcPath).delete(); - } else { - ContentValues contentValues = new ContentValues(); - contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, destinationFileName); - contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/*"); - contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFileUriString); - contentValues.put(MediaStore.Video.Media.IS_PENDING, 1); - - OutputStream stream = null; - Uri uri = null; - - try { - final Uri contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; - uri = contentResolver.insert(contentUri, contentValues); - - if (uri == null) { - throw new IOException("Failed to create new MediaStore record."); - } - - stream = contentResolver.openOutputStream(uri); - - if (stream == null) { - throw new IOException("Failed to get output stream."); - } - - InputStream in = new FileInputStream(srcPath); - - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - stream.write(buf, 0, len); - } - - contentValues.clear(); - contentValues.put(MediaStore.Video.Media.IS_PENDING, 0); - contentResolver.update(uri, contentValues, null, null); - destinationFileUriString = uri.toString(); - } catch (IOException e) { - if (uri != null) { - // Don't leave an orphan entry in the MediaStore - contentResolver.delete(uri, null, null); - } - - throw e; - } finally { - if (stream != null) { - stream.close(); - } - } - } - } else { - OutputStream stream = contentResolver.openOutputStream(Uri.parse(destinationFileUriString)); - if (stream == null) { - throw new IOException("Failed to get output stream."); - } - - InputStream in = new FileInputStream(srcPath); - - byte[] buf = new byte[1024]; - int len; - while ((len = in.read(buf)) > 0) { - stream.write(buf, 0, len); - } - } - } - - interface SaveTempMuxAndCopyAsyncTaskListener { - void finished(Uri destinationFileUri, int errorCode); - void updateProgressNotification(int stringResId); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java deleted file mode 100644 index 9f539d65..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Service/SubmitPostService.java +++ /dev/null @@ -1,354 +0,0 @@ -package ml.docilealligator.infinityforreddit.Service; - -import android.app.Notification; -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.app.Service; -import android.content.Intent; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.net.Uri; -import android.os.AsyncTask; -import android.os.Build; -import android.os.IBinder; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.request.target.CustomTarget; -import com.bumptech.glide.request.transition.Transition; - -import org.greenrobot.eventbus.EventBus; - -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.SubmitCrosspostEvent; -import ml.docilealligator.infinityforreddit.Event.SubmitImagePostEvent; -import ml.docilealligator.infinityforreddit.Event.SubmitTextOrLinkPostEvent; -import ml.docilealligator.infinityforreddit.Event.SubmitVideoOrGifPostEvent; -import ml.docilealligator.infinityforreddit.Flair; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.Utils.NotificationUtils; -import ml.docilealligator.infinityforreddit.Post.Post; -import ml.docilealligator.infinityforreddit.Post.SubmitPost; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Retrofit; - -public class SubmitPostService extends Service { - public static final String EXTRA_ACCESS_TOKEN = "EAT"; - public static final String EXTRA_SUBREDDIT_NAME = "ESN"; - public static final String EXTRA_TITLE = "ET"; - public static final String EXTRA_CONTENT = "EC"; - public static final String EXTRA_KIND = "EK"; - public static final String EXTRA_FLAIR = "EF"; - public static final String EXTRA_IS_SPOILER = "EIS"; - public static final String EXTRA_IS_NSFW = "EIN"; - public static final String EXTRA_POST_TYPE = "EPT"; - public static final int EXTRA_POST_TEXT_OR_LINK = 0; - public static final int EXTRA_POST_TYPE_IMAGE = 1; - public static final int EXTRA_POST_TYPE_VIDEO = 2; - public static final int EXTRA_POST_TYPE_CROSSPOST = 3; - @Inject - @Named("oauth") - Retrofit mOauthRetrofit; - @Inject - @Named("upload_media") - Retrofit mUploadMediaRetrofit; - @Inject - @Named("upload_video") - Retrofit mUploadVideoRetrofit; - @Inject - CustomThemeWrapper mCustomThemeWrapper; - private String mAccessToken; - private String subredditName; - private String title; - private Flair flair; - private boolean isSpoiler; - private boolean isNSFW; - private String content; - private String kind; - private Uri mediaUri; - - public SubmitPostService() { - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - ((Infinity) getApplication()).getAppComponent().inject(this); - - mAccessToken = intent.getStringExtra(EXTRA_ACCESS_TOKEN); - subredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); - title = intent.getStringExtra(EXTRA_TITLE); - flair = intent.getParcelableExtra(EXTRA_FLAIR); - isSpoiler = intent.getBooleanExtra(EXTRA_IS_SPOILER, false); - isNSFW = intent.getBooleanExtra(EXTRA_IS_NSFW, false); - int postType = intent.getIntExtra(EXTRA_POST_TYPE, EXTRA_POST_TEXT_OR_LINK); - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - NotificationChannel serviceChannel = new NotificationChannel( - NotificationUtils.CHANNEL_SUBMIT_POST, - NotificationUtils.CHANNEL_SUBMIT_POST, - NotificationManager.IMPORTANCE_LOW - ); - - NotificationManagerCompat manager = NotificationManagerCompat.from(this); - manager.createNotificationChannel(serviceChannel); - } - - if (postType == EXTRA_POST_TEXT_OR_LINK) { - content = intent.getStringExtra(EXTRA_CONTENT); - kind = intent.getStringExtra(EXTRA_KIND); - startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting)); - submitTextOrLinkPost(); - } else if (postType == EXTRA_POST_TYPE_CROSSPOST) { - content = intent.getStringExtra(EXTRA_CONTENT); - startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting)); - submitCrosspost(); - } else if (postType == EXTRA_POST_TYPE_IMAGE) { - mediaUri = intent.getData(); - startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting_image)); - submitImagePost(); - } else { - mediaUri = intent.getData(); - startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting_video)); - submitVideoPost(); - } - - return START_NOT_STICKY; - } - - private Notification createNotification(int stringResId) { - return new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_SUBMIT_POST) - .setContentTitle(getString(stringResId)) - .setContentText(getString(R.string.please_wait)) - .setSmallIcon(R.drawable.ic_notification) - .setColor(mCustomThemeWrapper.getColorPrimaryLightTheme()) - .build(); - } - - private void submitTextOrLinkPost() { - SubmitPost.submitTextOrLinkPost(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale, - subredditName, title, content, flair, isSpoiler, isNSFW, kind, new SubmitPost.SubmitPostListener() { - @Override - public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(true, post, null)); - - stopService(); - } - - @Override - public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(false, null, errorMessage)); - - stopService(); - } - }); - } - - private void submitCrosspost() { - SubmitPost.submitCrosspost(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale, - subredditName, title, content, flair, isSpoiler, isNSFW, APIUtils.KIND_CROSSPOST, new SubmitPost.SubmitPostListener() { - @Override - public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitCrosspostEvent(true, post, null)); - - stopService(); - } - - @Override - public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitCrosspostEvent(false, null, errorMessage)); - - stopService(); - } - }); - } - - private void submitImagePost() { - Glide.with(this) - .asBitmap() - .load(mediaUri) - .into(new CustomTarget() { - - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - SubmitPost.submitImagePost(mOauthRetrofit, mUploadMediaRetrofit, mAccessToken, - getResources().getConfiguration().locale, subredditName, title, resource, - flair, isSpoiler, isNSFW, new SubmitPost.SubmitPostListener() { - @Override - public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitImagePostEvent(true, null)); - Toast.makeText(SubmitPostService.this, R.string.image_is_processing, Toast.LENGTH_SHORT).show(); - - stopService(); - } - - @Override - public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitImagePostEvent(false, errorMessage)); - - stopService(); - } - }); - } - - @Override - public void onLoadFailed(@Nullable Drawable errorDrawable) { - EventBus.getDefault().post(new SubmitImagePostEvent(false, getString(R.string.error_processing_image))); - - stopService(); - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - } - - private void submitVideoPost() { - try { - InputStream in = getContentResolver().openInputStream(mediaUri); - String type = getContentResolver().getType(mediaUri); - String cacheFilePath; - if (type != null && type.contains("gif")) { - cacheFilePath = getExternalCacheDir() + "/" + mediaUri.getLastPathSegment() + ".gif"; - } else { - cacheFilePath = getExternalCacheDir() + "/" + mediaUri.getLastPathSegment() + ".mp4"; - } - - new CopyFileToCacheAsyncTask(in, cacheFilePath, - new CopyFileToCacheAsyncTask.CopyFileToCacheAsyncTaskListener() { - @Override - public void success() { - Glide.with(SubmitPostService.this) - .asBitmap() - .load(mediaUri) - .into(new CustomTarget() { - @Override - public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { - if (type != null) { - SubmitPost.submitVideoPost(mOauthRetrofit, mUploadMediaRetrofit, mUploadVideoRetrofit, - mAccessToken, getResources().getConfiguration().locale, subredditName, title, - new File(cacheFilePath), type, resource, flair, isSpoiler, isNSFW, - new SubmitPost.SubmitPostListener() { - @Override - public void submitSuccessful(Post post) { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(true, false, null)); - if (type.contains("gif")) { - Toast.makeText(SubmitPostService.this, R.string.gif_is_processing, Toast.LENGTH_SHORT).show(); - } else { - Toast.makeText(SubmitPostService.this, R.string.video_is_processing, Toast.LENGTH_SHORT).show(); - } - - stopService(); - } - - @Override - public void submitFailed(@Nullable String errorMessage) { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, false, errorMessage)); - - stopService(); - } - }); - } else { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); - } - } - - @Override - public void onLoadFailed(@Nullable Drawable errorDrawable) { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); - - stopService(); - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholder) { - - } - }); - } - - @Override - public void failed() { - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); - - stopService(); - } - }).execute(); - } catch (IOException e) { - e.printStackTrace(); - EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); - - stopService(); - } - } - - private static class CopyFileToCacheAsyncTask extends AsyncTask { - - private InputStream fileInputStream; - private String destinationFilePath; - private CopyFileToCacheAsyncTaskListener copyFileToCacheAsyncTaskListener; - private boolean parseFailed = false; - - interface CopyFileToCacheAsyncTaskListener { - void success(); - void failed(); - } - - public CopyFileToCacheAsyncTask(InputStream fileInputStream, String destinationFilePath, CopyFileToCacheAsyncTaskListener copyFileToCacheAsyncTaskListener) { - this.fileInputStream = fileInputStream; - this.destinationFilePath = destinationFilePath; - this.copyFileToCacheAsyncTaskListener = copyFileToCacheAsyncTaskListener; - } - - @Override - protected Void doInBackground(Void... voids) { - try (OutputStream out = new FileOutputStream(destinationFilePath)) { - byte[] buf = new byte[2048]; - int len; - while ((len = fileInputStream.read(buf)) > 0) { - out.write(buf, 0, len); - } - } catch (IOException e) { - e.printStackTrace(); - parseFailed = true; - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - if (parseFailed) { - copyFileToCacheAsyncTaskListener.failed(); - } else { - copyFileToCacheAsyncTaskListener.success(); - } - } - } - - private void stopService() { - stopForeground(true); - stopSelf(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AboutPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AboutPreferenceFragment.java deleted file mode 100644 index 640c8398..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AboutPreferenceFragment.java +++ /dev/null @@ -1,143 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - - -import android.app.Activity; -import android.content.ActivityNotFoundException; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.BuildConfig; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -/** - * A simple {@link PreferenceFragmentCompat} subclass. - */ -public class AboutPreferenceFragment extends PreferenceFragmentCompat { - - private Activity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.about_preferences, rootKey); - - Preference openSourcePreference = findPreference(SharedPreferencesUtils.OPEN_SOURCE_KEY); - Preference ratePreference = findPreference(SharedPreferencesUtils.RATE_KEY); - Preference fDroidPreference = findPreference(SharedPreferencesUtils.F_DROID_KEY); - Preference emailPreference = findPreference(SharedPreferencesUtils.EMAIL_KEY); - Preference redditAccountPreference = findPreference(SharedPreferencesUtils.REDDIT_ACCOUNT_KEY); - Preference subredditPreference = findPreference(SharedPreferencesUtils.SUBREDDIT_KEY); - Preference sharePreference = findPreference(SharedPreferencesUtils.SHARE_KEY); - Preference versionPreference = findPreference(SharedPreferencesUtils.VERSION_KEY); - - if (openSourcePreference != null) { - openSourcePreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://github.com/Docile-Alligator/Infinity-For-Reddit")); - startActivity(intent); - return true; - }); - } - - if (ratePreference != null) { - ratePreference.setOnPreferenceClickListener(preference -> { - Intent playStoreIntent = new Intent(Intent.ACTION_VIEW); - playStoreIntent.setData(Uri.parse("market://details?id=ml.docilealligator.infinityforreddit")); - if (playStoreIntent.resolveActivity(activity.getPackageManager()) != null) { - activity.startActivity(playStoreIntent); - } else { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit")); - startActivity(intent); - } - return true; - }); - } - - if (fDroidPreference != null) { - fDroidPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.reddit.com/r/Infinity_For_Reddit/comments/f23o0y/for_anyone_who_wants_to_use_fdroid/")); - startActivity(intent); - return true; - }); - } - - if (emailPreference != null) { - emailPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(Intent.ACTION_SENDTO); - intent.setData(Uri.parse("mailto:docilealligator.app@gmail.com")); - try { - startActivity(intent); - } catch (ActivityNotFoundException e) { - Toast.makeText(activity, R.string.no_email_client, Toast.LENGTH_SHORT).show(); - } - return true; - }); - } - - if (redditAccountPreference != null) { - redditAccountPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.reddit.com/user/Hostilenemy")); - startActivity(intent); - return true; - }); - } - - if (subredditPreference != null) { - subredditPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.reddit.com/r/Infinity_For_Reddit")); - startActivity(intent); - return true; - }); - } - - if (sharePreference != null) { - sharePreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(Intent.ACTION_SEND); - intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_this_app)); - if (intent.resolveActivity(activity.getPackageManager()) != null) { - startActivity(intent); - } else { - Toast.makeText(activity, R.string.no_app, Toast.LENGTH_SHORT).show(); - } - return true; - }); - } - - if (versionPreference != null) { - versionPreference.setSummary(getString(R.string.settings_version_summary, BuildConfig.VERSION_NAME)); - - versionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - int clickedTimes = 0; - - @Override - public boolean onPreferenceClick(Preference preference) { - clickedTimes++; - if (clickedTimes > 6) { - Toast.makeText(activity, R.string.no_developer_easter_egg, Toast.LENGTH_SHORT).show(); - clickedTimes = 0; - } - return true; - } - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Acknowledgement.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Acknowledgement.java deleted file mode 100644 index f3466268..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Acknowledgement.java +++ /dev/null @@ -1,27 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.net.Uri; - -public class Acknowledgement { - private String name; - private String introduction; - private Uri link; - - Acknowledgement(String name, String introduction, Uri link) { - this.name = name; - this.introduction = introduction; - this.link = link; - } - - public String getName() { - return name; - } - - public String getIntroduction() { - return introduction; - } - - public Uri getLink() { - return link; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AcknowledgementFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AcknowledgementFragment.java deleted file mode 100644 index feb13e66..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AcknowledgementFragment.java +++ /dev/null @@ -1,138 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - - -import android.app.Activity; -import android.content.Context; -import android.net.Uri; -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 androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import java.util.ArrayList; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.AcknowledgementRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.R; - -/** - * A simple {@link Fragment} subclass. - */ -public class AcknowledgementFragment extends Fragment { - - @BindView(R.id.recycler_view_acknowledgement_fragment) - RecyclerView recyclerView; - private Activity activity; - - public AcknowledgementFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_acknowledgement, container, false); - ButterKnife.bind(this, rootView); - - ArrayList acknowledgements = new ArrayList<>(); - acknowledgements.add(new Acknowledgement("ExoPlayer", - "An application level media player for Android", - Uri.parse("https://github.com/google/ExoPlayer"))); - acknowledgements.add(new Acknowledgement("GestureViews", - "ImageView and FrameLayout with gestures control and position animation", - Uri.parse("https://github.com/alexvasilkov/GestureViews"))); - acknowledgements.add(new Acknowledgement("Glide", - "A fast and efficient open source media management and image loading framework for Android", - Uri.parse("https://github.com/bumptech/glide"))); - acknowledgements.add(new Acknowledgement("RxAndroid", - "Android specific bindings for RxJava 2", - Uri.parse("https://github.com/ReactiveX/RxAndroid"))); - acknowledgements.add(new Acknowledgement("RxJava", - "Reactive extensions for the JVM", - Uri.parse("https://github.com/ReactiveX/RxJava"))); - acknowledgements.add(new Acknowledgement("Retrofit", - "Type-safe HTTP client for Android and Java by Square, Inc.", - Uri.parse("https://github.com/square/retrofit"))); - acknowledgements.add(new Acknowledgement("Dagger", - "A fast dependency injector for Java and Android.", - Uri.parse("https://github.com/google/dagger"))); - acknowledgements.add(new Acknowledgement("Butter Knife", - "Field and method binding for Android views", - Uri.parse("https://github.com/JakeWharton/butterknife"))); - acknowledgements.add(new Acknowledgement("Aspect Ratio ImageView", - "A simple imageview which scales the width or height aspect with the given ratio", - Uri.parse("https://github.com/santalu/aspect-ratio-imageview"))); - acknowledgements.add(new Acknowledgement("MaterialLoadingProgressBar", - "A styled ProgressBar", - Uri.parse("https://github.com/lsjwzh/MaterialLoadingProgressBar"))); - acknowledgements.add(new Acknowledgement("Markwon", - "A markdown library for Android", - Uri.parse("https://github.com/noties/Markwon"))); - acknowledgements.add(new Acknowledgement("android-gif-drawable", - "Views and Drawable for animated GIFs in Android.", - Uri.parse("https://github.com/koral--/android-gif-drawable"))); - acknowledgements.add(new Acknowledgement("SimpleSearchView", - "A simple SearchView for Android based on Material Design", - Uri.parse("https://github.com/Ferfalk/SimpleSearchView"))); - acknowledgements.add(new Acknowledgement("EventBus", - "A publish/subscribe event bus for Android and Java", - Uri.parse("https://github.com/greenrobot/EventBus"))); - acknowledgements.add(new Acknowledgement("Customized and Expandable TextView", - "Simple library to change the Textview as rectangle, circle and square shapes", - Uri.parse("https://github.com/Rajagopalr3/CustomizedTextView"))); - acknowledgements.add(new Acknowledgement("Rounded Bottom Sheet", - "Bottom sheet with rounded corners", - Uri.parse("https://github.com/Deishelon/RoundedBottomSheet"))); - acknowledgements.add(new Acknowledgement("Bridge", - "A library for avoiding TransactionTooLargeException during state saving and restoration", - Uri.parse("https://github.com/livefront/bridge"))); - acknowledgements.add(new Acknowledgement("Android-State", - "A utility library for Android to save objects in a Bundle without any boilerplate", - Uri.parse("https://github.com/evernote/android-state"))); - acknowledgements.add(new Acknowledgement("FlowLayout", - "A FlowLayout for Android, which allows child views flow to next row when there is no enough space.", - Uri.parse("https://github.com/nex3z/FlowLayout"))); - acknowledgements.add(new Acknowledgement("Gson", - "Gson is a Java library that can be used to convert Java Objects into their JSON representation.", - Uri.parse("https://github.com/google/gson"))); - acknowledgements.add(new Acknowledgement("Hauler", - "Hauler is an Android library containing custom layout which enables to easily create swipe to dismiss Activity.", - Uri.parse("https://github.com/futuredapp/hauler"))); - acknowledgements.add(new Acknowledgement("Slidr", - "Easily add slide to dismiss functionality to an Activity", - Uri.parse("https://github.com/r0adkll/Slidr"))); - acknowledgements.add(new Acknowledgement("commonmark-java", - "Java library for parsing and rendering Markdown text according to the CommonMark specification (and some extensions).", - Uri.parse("https://github.com/atlassian/commonmark-java"))); - acknowledgements.add(new Acknowledgement("AndroidFastScroll", - "Fast scroll for Android RecyclerView and more.", - Uri.parse("https://github.com/zhanghai/AndroidFastScroll"))); - acknowledgements.add(new Acknowledgement("Subsampling Scale Image View", - "A custom image view for Android, designed for photo galleries and displaying " + - "huge images (e.g. maps and building plans) without OutOfMemoryErrors.", - Uri.parse("https://github.com/davemorrissey/subsampling-scale-image-view"))); - acknowledgements.add(new Acknowledgement("BigImageViewer", - "Big image viewer supporting pan and zoom, with very little memory " + - "usage and full featured image loading choices. Powered by Subsampling Scale " + - "Image View, Fresco, Glide, and Picasso. Even with gif and webp support!", - Uri.parse("https://github.com/Piasy/BigImageViewer"))); - - AcknowledgementRecyclerViewAdapter adapter = new AcknowledgementRecyclerViewAdapter(activity, acknowledgements); - recyclerView.setLayoutManager(new LinearLayoutManager(activity)); - recyclerView.setAdapter(adapter); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AdvancedPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AdvancedPreferenceFragment.java deleted file mode 100644 index ff794aa5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/AdvancedPreferenceFragment.java +++ /dev/null @@ -1,237 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.widget.Toast; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.AsyncTask.DeleteAllPostLayoutsAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.DeleteAllSortTypesAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.DeleteAllSubredditsAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.DeleteAllThemesAsyncTask; -import ml.docilealligator.infinityforreddit.AsyncTask.DeleteAllUsersAsyncTask; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -/** - * A simple {@link Fragment} subclass. - */ -public class AdvancedPreferenceFragment extends PreferenceFragmentCompat { - - @Inject - RedditDataRoomDatabase mRedditDataRoomDatabase; - @Inject - @Named("default") - SharedPreferences mSharedPreferences; - @Inject - @Named("sort_type") - SharedPreferences mSortTypeSharedPreferences; - @Inject - @Named("post_layout") - SharedPreferences mPostLayoutSharedPreferences; - @Inject - @Named("light_theme") - SharedPreferences lightThemeSharedPreferences; - @Inject - @Named("dark_theme") - SharedPreferences darkThemeSharedPreferences; - @Inject - @Named("post_feed_scrolled_position_cache") - SharedPreferences postFeedScrolledPositionSharedPreferences; - @Inject - @Named("amoled_theme") - SharedPreferences amoledThemeSharedPreferences; - @Inject - @Named("main_activity_tabs") - SharedPreferences mainActivityTabsSharedPreferences; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences nsfwAndBlurringSharedPreferences; - private Activity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.advanced_preferences, rootKey); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - Preference deleteSubredditsPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_SUBREDDITS_DATA_IN_DATABASE); - Preference deleteUsersPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_USERS_DATA_IN_DATABASE); - Preference deleteSortTypePreference = findPreference(SharedPreferencesUtils.DELETE_ALL_SORT_TYPE_DATA_IN_DATABASE); - Preference deletePostLaoutPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_POST_LAYOUT_DATA_IN_DATABASE); - Preference deleteAllThemesPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_THEMES_IN_DATABASE); - Preference deletePostFeedScrolledPositionsPreference = findPreference(SharedPreferencesUtils.DELETE_FRONT_PAGE_SCROLLED_POSITIONS_IN_DATABASE); - Preference deleteAllLegacySettingsPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_LEGACY_SETTINGS); - Preference resetAllSettingsPreference = findPreference(SharedPreferencesUtils.RESET_ALL_SETTINGS); - - if (deleteSubredditsPreference != null) { - deleteSubredditsPreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> new DeleteAllSubredditsAsyncTask(mRedditDataRoomDatabase, - () -> Toast.makeText(activity, R.string.delete_all_subreddits_success, Toast.LENGTH_SHORT).show()).execute()) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - - if (deleteUsersPreference != null) { - deleteUsersPreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> new DeleteAllUsersAsyncTask(mRedditDataRoomDatabase, - () -> Toast.makeText(activity, R.string.delete_all_users_success, Toast.LENGTH_SHORT).show()).execute()) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - - if (deleteSortTypePreference != null) { - deleteSortTypePreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> new DeleteAllSortTypesAsyncTask(mSharedPreferences, mSortTypeSharedPreferences, () -> { - Toast.makeText(activity, R.string.delete_all_sort_types_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new RecreateActivityEvent()); - }).execute()) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - - if (deletePostLaoutPreference != null) { - deletePostLaoutPreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> new DeleteAllPostLayoutsAsyncTask(mSharedPreferences, mPostLayoutSharedPreferences, () -> { - Toast.makeText(activity, R.string.delete_all_post_layouts_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new RecreateActivityEvent()); - }).execute()) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - - if (deleteAllThemesPreference != null) { - deleteAllThemesPreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> new DeleteAllThemesAsyncTask(mRedditDataRoomDatabase, lightThemeSharedPreferences, - darkThemeSharedPreferences, amoledThemeSharedPreferences, () -> { - Toast.makeText(activity, R.string.delete_all_themes_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new RecreateActivityEvent()); - }).execute()) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - - if (deletePostFeedScrolledPositionsPreference != null) { - deletePostFeedScrolledPositionsPreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> { - postFeedScrolledPositionSharedPreferences.edit().clear().apply(); - Toast.makeText(activity, R.string.delete_all_front_page_scrolled_positions_success, Toast.LENGTH_SHORT).show(); - }) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - - if (deleteAllLegacySettingsPreference != null) { - deleteAllLegacySettingsPreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> { - SharedPreferences.Editor editor = mSharedPreferences.edit(); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME_LEGACY); - editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME_LEGACY); - editor.remove(SharedPreferencesUtils.NSFW_KEY_LEGACY); - editor.remove(SharedPreferencesUtils.BLUR_NSFW_KEY_LEGACY); - editor.remove(SharedPreferencesUtils.BLUR_SPOILER_KEY_LEGACY); - - SharedPreferences.Editor sortTypeEditor = mSortTypeSharedPreferences.edit(); - sortTypeEditor.remove(SharedPreferencesUtils.SORT_TYPE_ALL_POST_LEGACY); - sortTypeEditor.remove(SharedPreferencesUtils.SORT_TIME_ALL_POST_LEGACY); - sortTypeEditor.remove(SharedPreferencesUtils.SORT_TYPE_POPULAR_POST_LEGACY); - sortTypeEditor.remove(SharedPreferencesUtils.SORT_TIME_POPULAR_POST_LEGACY); - - SharedPreferences.Editor postLayoutEditor = mPostLayoutSharedPreferences.edit(); - postLayoutEditor.remove(SharedPreferencesUtils.POST_LAYOUT_ALL_POST_LEGACY); - postLayoutEditor.remove(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST_LEGACY); - - editor.apply(); - sortTypeEditor.apply(); - postLayoutEditor.apply(); - Toast.makeText(activity, R.string.delete_all_legacy_settings_success, Toast.LENGTH_SHORT).show(); - }) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - - if (resetAllSettingsPreference != null) { - resetAllSettingsPreference.setOnPreferenceClickListener(preference -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.are_you_sure) - .setPositiveButton(R.string.yes, (dialogInterface, i) - -> { - mSharedPreferences.edit().clear().apply(); - mainActivityTabsSharedPreferences.edit().clear().apply(); - nsfwAndBlurringSharedPreferences.edit().clear().apply(); - - Toast.makeText(activity, R.string.reset_all_settings_success, Toast.LENGTH_SHORT).show(); - EventBus.getDefault().post(new RecreateActivityEvent()); - }) - .setNegativeButton(R.string.no, null) - .show(); - return true; - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (AppCompatActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CreditsPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CreditsPreferenceFragment.java deleted file mode 100644 index dc33348b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CreditsPreferenceFragment.java +++ /dev/null @@ -1,136 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import ml.docilealligator.infinityforreddit.Activity.LinkResolverActivity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -/** - * A simple {@link PreferenceFragmentCompat} subclass. - */ -public class CreditsPreferenceFragment extends PreferenceFragmentCompat { - - private Activity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.credits_preferences, rootKey); - - Preference iconForegroundPreference = findPreference(SharedPreferencesUtils.ICON_FOREGROUND_KEY); - Preference iconBackgroundPreference = findPreference(SharedPreferencesUtils.ICON_BACKGROUND_KEY); - Preference errorImagePreference = findPreference(SharedPreferencesUtils.ERROR_IMAGE_KEY); - Preference gildedIconPreference = findPreference(SharedPreferencesUtils.GILDED_ICON_KEY); - Preference crosspostIconPreference = findPreference(SharedPreferencesUtils.CROSSPOST_ICON_KEY); - Preference thumbtackIconPreference = findPreference(SharedPreferencesUtils.THUMBTACK_ICON_KEY); - Preference bestRocketIconPreference = findPreference(SharedPreferencesUtils.BEST_ROCKET_ICON_KEY); - Preference materialIconsPreference = findPreference(SharedPreferencesUtils.MATERIAL_ICONS_KEY); - Preference nationalFlagsPreference = findPreference(SharedPreferencesUtils.NATIONAL_FLAGS); - Preference ufoAndCowPreference = findPreference(SharedPreferencesUtils.UFO_CAPTURING_ANIMATION); - - if (iconForegroundPreference != null) { - iconForegroundPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.freepik.com/free-photos-vectors/technology")); - startActivity(intent); - return true; - }); - } - - if (iconBackgroundPreference != null) { - iconBackgroundPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.freepik.com/free-photos-vectors/background")); - startActivity(intent); - return true; - }); - } - - if (errorImagePreference != null) { - errorImagePreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.freepik.com/free-photos-vectors/technology")); - startActivity(intent); - return true; - }); - } - - if (gildedIconPreference != null) { - gildedIconPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://br.flaticon.com/icone-gratis/medalha_1007239")); - startActivity(intent); - return true; - }); - } - - if (crosspostIconPreference != null) { - crosspostIconPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.flaticon.com/free-icon/crossed-arrows_2291")); - startActivity(intent); - return true; - }); - } - - if (thumbtackIconPreference != null) { - thumbtackIconPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.flaticon.com/free-icon/tack-save-button_61845#term=thumbtack&page=1&position=3")); - startActivity(intent); - return true; - }); - } - - if (bestRocketIconPreference != null) { - bestRocketIconPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.flaticon.com/free-icon/spring-swing-rocket_2929322?term=space%20ship&page=1&position=18")); - startActivity(intent); - return true; - }); - } - - if (materialIconsPreference != null) { - materialIconsPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://material.io/resources/icons/")); - startActivity(intent); - return true; - }); - } - - if (nationalFlagsPreference != null) { - nationalFlagsPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://www.flaticon.com/packs/countrys-flags")); - startActivity(intent); - return true; - }); - } - - if (ufoAndCowPreference != null) { - ufoAndCowPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, LinkResolverActivity.class); - intent.setData(Uri.parse("https://lottiefiles.com/33858-ufo-capturing-animation")); - startActivity(intent); - return true; - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeBottomAppBarFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeBottomAppBarFragment.java deleted file mode 100644 index 6e4bc2a1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeBottomAppBarFragment.java +++ /dev/null @@ -1,330 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Resources; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class CustomizeBottomAppBarFragment extends Fragment { - - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - - @BindView(R.id.info_text_view_customize_bottom_app_bar_fragment) - TextView infoTextView; - @BindView(R.id.divider_1_customize_bottom_app_bar_fragment) - View divider1; - @BindView(R.id.main_activity_group_summary_customize_bottom_app_bar_fragment) - TextView mainActivityGroupSummaryTextView; - @BindView(R.id.main_activity_option_count_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout mainActivityOptionCountLinearLayout; - @BindView(R.id.main_activity_option_count_text_view_customize_bottom_app_bar_fragment) - TextView mainActivityOptionCountTextView; - @BindView(R.id.main_activity_option_1_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout mainActivityOption1LinearLayout; - @BindView(R.id.main_activity_option_1_text_view_customize_bottom_app_bar_fragment) - TextView mainActivityOption1TextView; - @BindView(R.id.main_activity_option_2_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout mainActivityOption2LinearLayout; - @BindView(R.id.main_activity_option_2_text_view_customize_bottom_app_bar_fragment) - TextView mainActivityOption2TextView; - @BindView(R.id.main_activity_option_3_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout mainActivityOption3LinearLayout; - @BindView(R.id.main_activity_option_3_text_view_customize_bottom_app_bar_fragment) - TextView mainActivityOption3TextView; - @BindView(R.id.main_activity_option_4_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout mainActivityOption4LinearLayout; - @BindView(R.id.main_activity_option_4_text_view_customize_bottom_app_bar_fragment) - TextView mainActivityOption4TextView; - @BindView(R.id.main_activity_fab_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout mainActivityFABLinearLayout; - @BindView(R.id.main_activity_fab_text_view_customize_bottom_app_bar_fragment) - TextView mainActivityFABTextView; - - @BindView(R.id.divider_2_customize_bottom_app_bar_fragment) - View divider2; - @BindView(R.id.other_activities_group_summary_customize_bottom_app_bar_fragment) - TextView otherActivitiesGroupSummaryTextView; - @BindView(R.id.other_activities_option_count_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout otherActivitiesOptionCountLinearLayout; - @BindView(R.id.other_activities_option_count_text_view_customize_bottom_app_bar_fragment) - TextView otherActivitiesOptionCountTextView; - @BindView(R.id.other_activities_option_1_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout otherActivitiesOption1LinearLayout; - @BindView(R.id.other_activities_option_1_text_view_customize_bottom_app_bar_fragment) - TextView otherActivitiesOption1TextView; - @BindView(R.id.other_activities_option_2_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout otherActivitiesOption2LinearLayout; - @BindView(R.id.other_activities_option_2_text_view_customize_bottom_app_bar_fragment) - TextView otherActivitiesOption2TextView; - @BindView(R.id.other_activities_option_3_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout otherActivitiesOption3LinearLayout; - @BindView(R.id.other_activities_option_3_text_view_customize_bottom_app_bar_fragment) - TextView otherActivitiesOption3TextView; - @BindView(R.id.other_activities_option_4_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout otherActivitiesOption4LinearLayout; - @BindView(R.id.other_activities_option_4_text_view_customize_bottom_app_bar_fragment) - TextView otherActivitiesOption4TextView; - @BindView(R.id.other_activities_fab_linear_layout_customize_bottom_app_bar_fragment) - LinearLayout otherActivitiesFABLinearLayout; - @BindView(R.id.other_activities_fab_text_view_customize_bottom_app_bar_fragment) - TextView otherActivitiesFABTextView; - @Inject - @Named("bottom_app_bar") - SharedPreferences sharedPreferences; - private Activity activity; - private int mainActivityOptionCount; - private int mainActivityOption1; - private int mainActivityOption2; - private int mainActivityOption3; - private int mainActivityOption4; - private int mainActivityFAB; - private int otherActivitiesOptionCount; - private int otherActivitiesOption1; - private int otherActivitiesOption2; - private int otherActivitiesOption3; - private int otherActivitiesOption4; - private int otherActivitiesFAB; - - public CustomizeBottomAppBarFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_customize_bottom_app_bar, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - - if (accountName == null) { - infoTextView.setText(R.string.only_for_logged_in_user); - divider1.setVisibility(View.GONE); - mainActivityGroupSummaryTextView.setVisibility(View.GONE); - mainActivityOptionCountLinearLayout.setVisibility(View.GONE); - mainActivityOption1LinearLayout.setVisibility(View.GONE); - mainActivityOption2LinearLayout.setVisibility(View.GONE); - mainActivityOption3LinearLayout.setVisibility(View.GONE); - mainActivityOption4LinearLayout.setVisibility(View.GONE); - mainActivityFABLinearLayout.setVisibility(View.GONE); - divider2.setVisibility(View.GONE); - otherActivitiesGroupSummaryTextView.setVisibility(View.GONE); - otherActivitiesOptionCountLinearLayout.setVisibility(View.GONE); - otherActivitiesOption1LinearLayout.setVisibility(View.GONE); - otherActivitiesOption2LinearLayout.setVisibility(View.GONE); - otherActivitiesOption3LinearLayout.setVisibility(View.GONE); - otherActivitiesOption4LinearLayout.setVisibility(View.GONE); - otherActivitiesFABLinearLayout.setVisibility(View.GONE); - - return rootView; - } - - Resources resources = activity.getResources(); - String[] mainActivityOptions = resources.getStringArray(R.array.settings_main_activity_bottom_app_bar_options); - String[] fabOptions = resources.getStringArray(R.array.settings_bottom_app_bar_fab_options); - mainActivityOptionCount = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT, 4); - mainActivityOption1 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1, 0); - mainActivityOption2 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2, 1); - mainActivityOption3 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3, 2); - mainActivityOption4 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4, 3); - mainActivityFAB = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB, 0); - - mainActivityOptionCountTextView.setText(Integer.toString(mainActivityOptionCount)); - mainActivityOption1TextView.setText(mainActivityOptions[mainActivityOption1]); - mainActivityOption2TextView.setText(mainActivityOptions[mainActivityOption2]); - mainActivityOption3TextView.setText(mainActivityOptions[mainActivityOption3]); - mainActivityOption4TextView.setText(mainActivityOptions[mainActivityOption4]); - mainActivityFABTextView.setText(fabOptions[mainActivityFAB]); - - mainActivityOptionCountLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_count) - .setSingleChoiceItems(R.array.settings_bottom_app_bar_option_count_options, mainActivityOptionCount / 2 - 1, (dialogInterface, i) -> { - mainActivityOptionCount = (i + 1) * 2; - sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT, mainActivityOptionCount).apply(); - mainActivityOptionCountTextView.setText(Integer.toString(mainActivityOptionCount)); - dialogInterface.dismiss(); - }) - .show(); - }); - - mainActivityOption1LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_1) - .setSingleChoiceItems(mainActivityOptions, mainActivityOption1, (dialogInterface, i) -> { - mainActivityOption1 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1, mainActivityOption1).apply(); - mainActivityOption1TextView.setText(mainActivityOptions[mainActivityOption1]); - dialogInterface.dismiss(); - }) - .show(); - }); - - mainActivityOption2LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_2) - .setSingleChoiceItems(mainActivityOptions, mainActivityOption2, (dialogInterface, i) -> { - mainActivityOption2 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2, mainActivityOption2).apply(); - mainActivityOption2TextView.setText(mainActivityOptions[mainActivityOption2]); - dialogInterface.dismiss(); - }) - .show(); - }); - - mainActivityOption3LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_3) - .setSingleChoiceItems(mainActivityOptions, mainActivityOption3, (dialogInterface, i) -> { - mainActivityOption3 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3, mainActivityOption3).apply(); - mainActivityOption3TextView.setText(mainActivityOptions[mainActivityOption3]); - dialogInterface.dismiss(); - }) - .show(); - }); - - mainActivityOption4LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_4) - .setSingleChoiceItems(mainActivityOptions, mainActivityOption4, (dialogInterface, i) -> { - mainActivityOption4 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4, mainActivityOption4).apply(); - mainActivityOption4TextView.setText(mainActivityOptions[mainActivityOption4]); - dialogInterface.dismiss(); - }) - .show(); - }); - - mainActivityFABLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_fab) - .setSingleChoiceItems(fabOptions, mainActivityFAB, (dialogInterface, i) -> { - mainActivityFAB = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB, mainActivityFAB).apply(); - mainActivityFABTextView.setText(fabOptions[mainActivityFAB]); - dialogInterface.dismiss(); - }) - .show(); - }); - - String[] otherActivitiesOptions = resources.getStringArray(R.array.settings_other_activities_bottom_app_bar_options); - otherActivitiesOptionCount = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT, 4); - otherActivitiesOption1 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1, 0); - otherActivitiesOption2 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2, 1); - otherActivitiesOption3 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3, 2); - otherActivitiesOption4 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4, 3); - otherActivitiesFAB = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB, 0); - - otherActivitiesOptionCountTextView.setText(Integer.toString(otherActivitiesOptionCount)); - otherActivitiesOption1TextView.setText(otherActivitiesOptions[otherActivitiesOption1]); - otherActivitiesOption2TextView.setText(otherActivitiesOptions[otherActivitiesOption2]); - otherActivitiesOption3TextView.setText(otherActivitiesOptions[otherActivitiesOption3]); - otherActivitiesOption4TextView.setText(otherActivitiesOptions[otherActivitiesOption4]); - otherActivitiesFABTextView.setText(fabOptions[otherActivitiesFAB]); - - otherActivitiesOptionCountLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_count) - .setSingleChoiceItems(R.array.settings_bottom_app_bar_option_count_options, otherActivitiesOptionCount / 2 - 1, (dialogInterface, i) -> { - otherActivitiesOptionCount = (i + 1) * 2; - sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT, otherActivitiesOptionCount).apply(); - otherActivitiesOptionCountTextView.setText(Integer.toString(otherActivitiesOptionCount)); - dialogInterface.dismiss(); - }) - .show(); - }); - - otherActivitiesOption1LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_1) - .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption1, (dialogInterface, i) -> { - otherActivitiesOption1 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1, otherActivitiesOption1).apply(); - otherActivitiesOption1TextView.setText(otherActivitiesOptions[otherActivitiesOption1]); - dialogInterface.dismiss(); - }) - .show(); - }); - - otherActivitiesOption2LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_2) - .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption2, (dialogInterface, i) -> { - otherActivitiesOption2 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2, otherActivitiesOption2).apply(); - otherActivitiesOption2TextView.setText(otherActivitiesOptions[otherActivitiesOption2]); - dialogInterface.dismiss(); - }) - .show(); - }); - - otherActivitiesOption3LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_3) - .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption3, (dialogInterface, i) -> { - otherActivitiesOption3 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3, otherActivitiesOption3).apply(); - otherActivitiesOption3TextView.setText(otherActivitiesOptions[otherActivitiesOption3]); - dialogInterface.dismiss(); - }) - .show(); - }); - - otherActivitiesOption4LinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_option_4) - .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption4, (dialogInterface, i) -> { - otherActivitiesOption4 = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4, otherActivitiesOption4).apply(); - otherActivitiesOption4TextView.setText(otherActivitiesOptions[otherActivitiesOption4]); - dialogInterface.dismiss(); - }) - .show(); - }); - - otherActivitiesFABLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_bottom_app_bar_fab) - .setSingleChoiceItems(fabOptions, otherActivitiesFAB, (dialogInterface, i) -> { - otherActivitiesFAB = i; - sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB, otherActivitiesFAB).apply(); - otherActivitiesFABTextView.setText(fabOptions[otherActivitiesFAB]); - dialogInterface.dismiss(); - }) - .show(); - }); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeMainPageTabsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeMainPageTabsFragment.java deleted file mode 100644 index 979c2728..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/CustomizeMainPageTabsFragment.java +++ /dev/null @@ -1,563 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.EditText; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.switchmaterial.SwitchMaterial; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class CustomizeMainPageTabsFragment extends Fragment { - - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - - @BindView(R.id.info_text_view_customize_main_page_tabs_fragment) - TextView infoTextView; - @BindView(R.id.tab_count_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tabCountLinearLayout; - @BindView(R.id.tab_count_text_view_customize_main_page_tabs_fragment) - TextView tabCountTextView; - @BindView(R.id.show_tab_names_linear_layout_customize_main_page_tabs_fragment) - LinearLayout showTabNamesLinearLayout; - @BindView(R.id.show_tab_names_switch_material_customize_main_page_tabs_fragment) - SwitchMaterial showTabNamesSwitch; - @BindView(R.id.divider_1_customize_main_page_tabs_fragment) - View divider1; - @BindView(R.id.tab_1_group_summary_customize_main_page_tabs_fragment) - TextView tab1GroupSummaryTextView; - @BindView(R.id.tab_1_title_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab1TitleLinearLayout; - @BindView(R.id.tab_1_title_summary_text_view_customize_main_page_tabs_fragment) - TextView tab1TitleSummaryTextView; - @BindView(R.id.tab_1_type_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab1TypeLinearLayout; - @BindView(R.id.tab_1_type_summary_text_view_customize_main_page_tabs_fragment) - TextView tab1TypeSummaryTextView; - @BindView(R.id.tab_1_name_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab1NameLinearLayout; - @BindView(R.id.tab_1_name_title_text_view_customize_main_page_tabs_fragment) - TextView tab1NameTitleTextView; - @BindView(R.id.tab_1_name_summary_text_view_customize_main_page_tabs_fragment) - TextView tab1NameSummaryTextView; - @BindView(R.id.divider_2_customize_main_page_tabs_fragment) - View divider2; - @BindView(R.id.tab_2_group_summary_customize_main_page_tabs_fragment) - TextView tab2GroupSummaryTextView; - @BindView(R.id.tab_2_title_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab2TitleLinearLayout; - @BindView(R.id.tab_2_title_summary_text_view_customize_main_page_tabs_fragment) - TextView tab2TitleSummaryTextView; - @BindView(R.id.tab_2_type_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab2TypeLinearLayout; - @BindView(R.id.tab_2_type_summary_text_view_customize_main_page_tabs_fragment) - TextView tab2TypeSummaryTextView; - @BindView(R.id.tab_2_name_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab2NameLinearLayout; - @BindView(R.id.tab_2_name_title_text_view_customize_main_page_tabs_fragment) - TextView tab2NameTitleTextView; - @BindView(R.id.tab_2_name_summary_text_view_customize_main_page_tabs_fragment) - TextView tab2NameSummaryTextView; - @BindView(R.id.divider_3_customize_main_page_tabs_fragment) - View divider3; - @BindView(R.id.tab_3_group_summary_customize_main_page_tabs_fragment) - TextView tab3GroupSummaryTextView; - @BindView(R.id.tab_3_title_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab3TitleLinearLayout; - @BindView(R.id.tab_3_title_summary_text_view_customize_main_page_tabs_fragment) - TextView tab3TitleSummaryTextView; - @BindView(R.id.tab_3_type_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab3TypeLinearLayout; - @BindView(R.id.tab_3_type_summary_text_view_customize_main_page_tabs_fragment) - TextView tab3TypeSummaryTextView; - @BindView(R.id.tab_3_name_linear_layout_customize_main_page_tabs_fragment) - LinearLayout tab3NameLinearLayout; - @BindView(R.id.tab_3_name_title_text_view_customize_main_page_tabs_fragment) - TextView tab3NameTitleTextView; - @BindView(R.id.tab_3_name_summary_text_view_customize_main_page_tabs_fragment) - TextView tab3NameSummaryTextView; - @BindView(R.id.divider_4_customize_main_page_tabs_fragment) - View divider4; - @BindView(R.id.more_tabs_group_summary_customize_main_page_tabs_fragment) - TextView moreTabsGroupSummaryTextView; - @BindView(R.id.more_tabs_info_text_view_customize_main_page_tabs_fragment) - TextView moreTabsInfoTextView; - @BindView(R.id.show_subscribed_subreddits_linear_layout_customize_main_page_tabs_fragment) - LinearLayout showSubscribedSubredditsLinearLayout; - @BindView(R.id.show_subscribed_subreddits_switch_material_customize_main_page_tabs_fragment) - SwitchMaterial showSubscribedSubredditsSwitchMaterial; - @BindView(R.id.show_favorite_subscribed_subreddits_linear_layout_customize_main_page_tabs_fragment) - LinearLayout showFavoriteSubscribedSubredditsLinearLayout; - @BindView(R.id.show_favorite_subscribed_subreddits_switch_material_customize_main_page_tabs_fragment) - SwitchMaterial showFavoriteSubscribedSubredditsSwitchMaterial; - @Inject - @Named("main_activity_tabs") - SharedPreferences sharedPreferences; - private Activity activity; - private int tabCount; - private String tab1CurrentTitle; - private int tab1CurrentPostType; - private String tab1CurrentName; - private String tab2CurrentTitle; - private int tab2CurrentPostType; - private String tab2CurrentName; - private String tab3CurrentTitle; - private int tab3CurrentPostType; - private String tab3CurrentName; - - public CustomizeMainPageTabsFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_customize_main_page_tabs, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - - if (accountName == null) { - infoTextView.setText(R.string.only_for_logged_in_user); - divider1.setVisibility(View.GONE); - tabCountLinearLayout.setVisibility(View.GONE); - showTabNamesLinearLayout.setVisibility(View.GONE); - tab1GroupSummaryTextView.setVisibility(View.GONE); - tab1TitleLinearLayout.setVisibility(View.GONE); - tab1TypeLinearLayout.setVisibility(View.GONE); - divider2.setVisibility(View.GONE); - tab2GroupSummaryTextView.setVisibility(View.GONE); - tab2TitleLinearLayout.setVisibility(View.GONE); - tab2TypeLinearLayout.setVisibility(View.GONE); - divider3.setVisibility(View.GONE); - tab3GroupSummaryTextView.setVisibility(View.GONE); - tab3TitleLinearLayout.setVisibility(View.GONE); - tab3TypeLinearLayout.setVisibility(View.GONE); - divider4.setVisibility(View.GONE); - moreTabsGroupSummaryTextView.setVisibility(View.GONE); - moreTabsInfoTextView.setVisibility(View.GONE); - showSubscribedSubredditsLinearLayout.setVisibility(View.GONE); - showFavoriteSubscribedSubredditsLinearLayout.setVisibility(View.GONE); - - return rootView; - } - - tabCount = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_COUNT, 3); - tabCountTextView.setText(Integer.toString(tabCount)); - tabCountLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_count) - .setSingleChoiceItems(R.array.settings_main_page_tab_count, tabCount - 1, (dialogInterface, i) -> { - tabCount = i + 1; - sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_COUNT, tabCount).apply(); - tabCountTextView.setText(Integer.toString(tabCount)); - dialogInterface.dismiss(); - }) - .show(); - }); - - boolean showTabNames = sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true); - showTabNamesSwitch.setChecked(showTabNames); - showTabNamesSwitch.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, b).apply()); - showTabNamesLinearLayout.setOnClickListener(view -> showTabNamesSwitch.performClick()); - - String[] typeValues = activity.getResources().getStringArray(R.array.settings_tab_post_type); - - tab1CurrentTitle = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.home)); - tab1CurrentPostType = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_HOME); - tab1CurrentName = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME, ""); - tab1TypeSummaryTextView.setText(typeValues[tab1CurrentPostType]); - tab1TitleSummaryTextView.setText(tab1CurrentTitle); - tab1NameSummaryTextView.setText(tab1CurrentName); - applyTab1NameView(tab1NameLinearLayout, tab1NameTitleTextView, tab1CurrentPostType); - - View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_edit_text, null); - EditText editText = dialogView.findViewById(R.id.edit_text_edit_text_dialog); - - tab1TitleLinearLayout.setOnClickListener(view -> { - editText.setHint(R.string.settings_tab_title); - editText.setText(tab1CurrentTitle); - editText.requestFocus(); - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - if (dialogView.getParent() != null) { - ((ViewGroup) dialogView.getParent()).removeView(dialogView); - } - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_title) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - tab1CurrentTitle = editText.getText().toString(); - sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, tab1CurrentTitle).apply(); - tab1TitleSummaryTextView.setText(tab1CurrentTitle); - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .show(); - }); - - tab1TypeLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_title) - .setSingleChoiceItems(typeValues, tab1CurrentPostType, (dialogInterface, i) -> { - tab1CurrentPostType = i; - sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE, i).apply(); - tab1TypeSummaryTextView.setText(typeValues[i]); - applyTab1NameView(tab1NameLinearLayout, tab1NameTitleTextView, i); - dialogInterface.dismiss(); - }) - .setNegativeButton(R.string.cancel, null) - .show(); - }); - - tab1NameLinearLayout.setOnClickListener(view -> { - int titleId; - switch (tab1CurrentPostType) { - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: - titleId = R.string.settings_tab_subreddit_name; - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: - titleId = R.string.settings_tab_multi_reddit_name; - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: - titleId = R.string.settings_tab_username; - break; - default: - return; - } - editText.setText(tab1CurrentName); - editText.setHint(titleId); - editText.requestFocus(); - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - if (dialogView.getParent() != null) { - ((ViewGroup) dialogView.getParent()).removeView(dialogView); - } - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(titleId) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - tab1CurrentName = editText.getText().toString(); - sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME, tab1CurrentName).apply(); - tab1NameSummaryTextView.setText(tab1CurrentName); - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .show(); - }); - - tab2CurrentTitle = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, getString(R.string.popular)); - tab2CurrentPostType = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_POPULAR); - tab2CurrentName = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME, ""); - tab2TypeSummaryTextView.setText(typeValues[tab2CurrentPostType]); - tab2TitleSummaryTextView.setText(tab2CurrentTitle); - tab2NameSummaryTextView.setText(tab2CurrentName); - applyTab2NameView(tab2NameLinearLayout, tab2NameTitleTextView, tab2CurrentPostType); - - tab2TitleLinearLayout.setOnClickListener(view -> { - editText.setHint(R.string.settings_tab_title); - editText.setText(tab2CurrentTitle); - editText.requestFocus(); - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - if (dialogView.getParent() != null) { - ((ViewGroup) dialogView.getParent()).removeView(dialogView); - } - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_title) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - tab2CurrentTitle = editText.getText().toString(); - sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, tab2CurrentTitle).apply(); - tab2TitleSummaryTextView.setText(tab2CurrentTitle); - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .show(); - }); - - tab2TypeLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_title) - .setSingleChoiceItems(typeValues, tab2CurrentPostType, (dialogInterface, i) -> { - tab2CurrentPostType = i; - sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE, i).apply(); - tab2TypeSummaryTextView.setText(typeValues[i]); - applyTab2NameView(tab2NameLinearLayout, tab2NameTitleTextView, i); - dialogInterface.dismiss(); - }) - .setNegativeButton(R.string.cancel, null) - .show(); - }); - - tab2NameLinearLayout.setOnClickListener(view -> { - int titleId; - switch (tab2CurrentPostType) { - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: - titleId = R.string.settings_tab_subreddit_name; - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: - titleId = R.string.settings_tab_multi_reddit_name; - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: - titleId = R.string.settings_tab_username; - break; - default: - return; - } - editText.setText(tab2CurrentName); - editText.setHint(titleId); - editText.requestFocus(); - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - if (dialogView.getParent() != null) { - ((ViewGroup) dialogView.getParent()).removeView(dialogView); - } - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(titleId) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - tab2CurrentName = editText.getText().toString(); - sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME, tab2CurrentName).apply(); - tab2NameSummaryTextView.setText(tab2CurrentName); - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .show(); - }); - - tab3CurrentTitle = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE, getString(R.string.all)); - tab3CurrentPostType = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_ALL); - tab3CurrentName = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME, ""); - tab3TypeSummaryTextView.setText(typeValues[tab3CurrentPostType]); - tab3TitleSummaryTextView.setText(tab3CurrentTitle); - tab3NameSummaryTextView.setText(tab3CurrentName); - applyTab3NameView(tab3NameLinearLayout, tab3NameTitleTextView, tab3CurrentPostType); - - tab3TitleLinearLayout.setOnClickListener(view -> { - editText.setHint(R.string.settings_tab_title); - editText.setText(tab3CurrentTitle); - editText.requestFocus(); - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - if (dialogView.getParent() != null) { - ((ViewGroup) dialogView.getParent()).removeView(dialogView); - } - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_title) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - tab3CurrentTitle = editText.getText().toString(); - sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE, tab3CurrentTitle).apply(); - tab3TitleSummaryTextView.setText(tab3CurrentTitle); - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .show(); - }); - - tab3TypeLinearLayout.setOnClickListener(view -> { - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(R.string.settings_tab_title) - .setSingleChoiceItems(typeValues, tab3CurrentPostType, (dialogInterface, i) -> { - tab3CurrentPostType = i; - sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE, i).apply(); - tab3TypeSummaryTextView.setText(typeValues[i]); - applyTab3NameView(tab3NameLinearLayout, tab3NameTitleTextView, i); - dialogInterface.dismiss(); - }) - .setNegativeButton(R.string.cancel, null) - .show(); - }); - - tab3NameLinearLayout.setOnClickListener(view -> { - int titleId; - switch (tab3CurrentPostType) { - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: - titleId = R.string.settings_tab_subreddit_name; - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: - titleId = R.string.settings_tab_multi_reddit_name; - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: - titleId = R.string.settings_tab_username; - break; - default: - return; - } - editText.setText(tab3CurrentName); - editText.setHint(titleId); - editText.requestFocus(); - InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); - if (imm != null) { - imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); - } - if (dialogView.getParent() != null) { - ((ViewGroup) dialogView.getParent()).removeView(dialogView); - } - new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) - .setTitle(titleId) - .setView(dialogView) - .setPositiveButton(R.string.ok, (dialogInterface, i) - -> { - tab3CurrentName = editText.getText().toString(); - sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME, tab3CurrentName).apply(); - tab3NameSummaryTextView.setText(tab3CurrentName); - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { - if (imm != null) { - imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); - } - }) - .show(); - }); - - showSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, false)); - showSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, b).apply()); - showSubscribedSubredditsLinearLayout.setOnClickListener(view -> { - showSubscribedSubredditsSwitchMaterial.performClick(); - }); - - showFavoriteSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, false)); - showFavoriteSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, b).apply()); - showFavoriteSubscribedSubredditsLinearLayout.setOnClickListener(view -> { - showFavoriteSubscribedSubredditsSwitchMaterial.performClick(); - }); - - return rootView; - } - - private void applyTab1NameView(LinearLayout linearLayout, TextView titleTextView, int postType) { - switch (postType) { - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_subreddit_name); - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_multi_reddit_name); - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_username); - break; - default: - linearLayout.setVisibility(View.GONE); - } - } - - private void applyTab2NameView(LinearLayout linearLayout, TextView titleTextView, int postType) { - switch (postType) { - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_subreddit_name); - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_multi_reddit_name); - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_username); - break; - default: - linearLayout.setVisibility(View.GONE); - } - } - - private void applyTab3NameView(LinearLayout linearLayout, TextView titleTextView, int postType) { - switch (postType) { - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_subreddit_name); - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_multi_reddit_name); - break; - case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: - linearLayout.setVisibility(View.VISIBLE); - titleTextView.setText(R.string.settings_tab_username); - break; - default: - linearLayout.setVisibility(View.GONE); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DataSavingModePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DataSavingModePreferenceFragment.java deleted file mode 100644 index caded180..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DataSavingModePreferenceFragment.java +++ /dev/null @@ -1,39 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.os.Bundle; - -import androidx.preference.ListPreference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import ml.docilealligator.infinityforreddit.Event.ChangeDataSavingModeEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeDisableImagePreviewEvent; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class DataSavingModePreferenceFragment extends PreferenceFragmentCompat { - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.data_saving_mode_preferences, rootKey); - - ListPreference dataSavingModeListPreference = findPreference(SharedPreferencesUtils.DATA_SAVING_MODE); - SwitchPreference disableImagePreviewPreference = findPreference(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW); - - if (dataSavingModeListPreference != null) { - dataSavingModeListPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeDataSavingModeEvent((String) newValue)); - return true; - }); - } - - if (disableImagePreviewPreference != null) { - disableImagePreviewPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeDisableImagePreviewEvent((Boolean) newValue)); - return true; - }); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DownloadLocationPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DownloadLocationPreferenceFragment.java deleted file mode 100644 index 61163598..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/DownloadLocationPreferenceFragment.java +++ /dev/null @@ -1,118 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE; - -public class DownloadLocationPreferenceFragment extends PreferenceFragmentCompat { - private static final int IMAGE_DOWNLOAD_LOCATION_REQUEST_CODE = 10; - private static final int GIF_DOWNLOAD_LOCATION_REQUEST_CODE = 11; - private static final int VIDEO_DOWNLOAD_LOCATION_REQUEST_CODE = 12; - - Preference imageDownloadLocationPreference; - Preference gifDownloadLocationPreference; - Preference videoDownloadLocationPreference; - private Activity activity; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - setPreferencesFromResource(R.xml.download_location_preferences, rootKey); - imageDownloadLocationPreference = findPreference(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION); - gifDownloadLocationPreference = findPreference(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION); - videoDownloadLocationPreference = findPreference(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION); - - if (imageDownloadLocationPreference != null) { - String downloadLocation = sharedPreferences.getString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, ""); - if (!downloadLocation.equals("")) { - imageDownloadLocationPreference.setSummary(downloadLocation); - } - - imageDownloadLocationPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(ACTION_OPEN_DOCUMENT_TREE); - intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - startActivityForResult(intent, IMAGE_DOWNLOAD_LOCATION_REQUEST_CODE); - return true; - }); - } - - if (gifDownloadLocationPreference != null) { - String downloadLocation = sharedPreferences.getString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, ""); - if (!downloadLocation.equals("")) { - gifDownloadLocationPreference.setSummary(downloadLocation); - } - - gifDownloadLocationPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(ACTION_OPEN_DOCUMENT_TREE); - intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - startActivityForResult(intent, GIF_DOWNLOAD_LOCATION_REQUEST_CODE); - return true; - }); - } - - if (videoDownloadLocationPreference != null) { - String downloadLocation = sharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, ""); - if (!downloadLocation.equals("")) { - videoDownloadLocationPreference.setSummary(downloadLocation); - } - - videoDownloadLocationPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(ACTION_OPEN_DOCUMENT_TREE); - intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - startActivityForResult(intent, VIDEO_DOWNLOAD_LOCATION_REQUEST_CODE); - return true; - }); - } - } - - @Override - public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) { - if (requestCode == IMAGE_DOWNLOAD_LOCATION_REQUEST_CODE) { - activity.getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - sharedPreferences.edit().putString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, data.getDataString()).apply(); - if (imageDownloadLocationPreference != null) { - imageDownloadLocationPreference.setSummary(data.getDataString()); - } - } else if (requestCode == GIF_DOWNLOAD_LOCATION_REQUEST_CODE) { - activity.getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - sharedPreferences.edit().putString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, data.getDataString()).apply(); - if (gifDownloadLocationPreference != null) { - gifDownloadLocationPreference.setSummary(data.getDataString()); - } - } else if (requestCode == VIDEO_DOWNLOAD_LOCATION_REQUEST_CODE) { - activity.getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - sharedPreferences.edit().putString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, data.getDataString()).apply(); - if (videoDownloadLocationPreference != null) { - videoDownloadLocationPreference.setSummary(data.getDataString()); - } - } - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FilterPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FilterPreferenceFragment.java deleted file mode 100644 index a0555d5d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FilterPreferenceFragment.java +++ /dev/null @@ -1,38 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import ml.docilealligator.infinityforreddit.Activity.SubredditFilterPopularAndAllActivity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class FilterPreferenceFragment extends PreferenceFragmentCompat { - - private Activity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.filter_preferences, rootKey); - - Preference subredditFilterPopularAndAllPreference = findPreference(SharedPreferencesUtils.SUBREDDIT_FILTER_POPULAR_AND_ALL); - - subredditFilterPopularAndAllPreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, SubredditFilterPopularAndAllActivity.class); - activity.startActivity(intent); - return true; - }); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreferenceFragment.java deleted file mode 100644 index 78ae7d82..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreferenceFragment.java +++ /dev/null @@ -1,80 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.preference.ListPreference; -import androidx.preference.PreferenceFragmentCompat; - -import org.greenrobot.eventbus.EventBus; - -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class FontPreferenceFragment extends PreferenceFragmentCompat { - private Activity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.font_preferences, rootKey); - ListPreference fontFamilyPreference = findPreference(SharedPreferencesUtils.FONT_FAMILY_KEY); - ListPreference titleFontFamilyPreference = findPreference(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY); - ListPreference contentFontFamilyPreference = findPreference(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY); - ListPreference fontSizePreference = findPreference(SharedPreferencesUtils.FONT_SIZE_KEY); - ListPreference titleFontSizePreference = findPreference(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY); - ListPreference contentFontSizePreference = findPreference(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY); - - if (fontFamilyPreference != null) { - fontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - activity.recreate(); - return true; - }); - } - - if (titleFontFamilyPreference != null) { - titleFontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - } - - if (contentFontFamilyPreference != null) { - contentFontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - } - - if (fontSizePreference != null) { - fontSizePreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - activity.recreate(); - return true; - }); - } - - if (titleFontSizePreference != null) { - titleFontSizePreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - } - - if (contentFontSizePreference != null) { - contentFontSizePreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreviewFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreviewFragment.java deleted file mode 100644 index 9cd93e01..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/FontPreviewFragment.java +++ /dev/null @@ -1,29 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.fragment.app.Fragment; - -import ml.docilealligator.infinityforreddit.R; - -/** - * A simple {@link Fragment} subclass. - * Use the {@link FontPreviewFragment#newInstance} factory method to - * create an instance of this fragment. - */ -public class FontPreviewFragment extends Fragment { - - public FontPreviewFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View rootView = inflater.inflate(R.layout.fragment_font_preview, container, false); - return rootView; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/GesturesAndButtonsPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/GesturesAndButtonsPreferenceFragment.java deleted file mode 100644 index 3c1bde13..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/GesturesAndButtonsPreferenceFragment.java +++ /dev/null @@ -1,88 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.Event.ChangeLockBottomAppBarEvent; -import ml.docilealligator.infinityforreddit.Fragment.ChangePullToRefreshEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -/** - * A simple {@link Fragment} subclass. - */ -public class GesturesAndButtonsPreferenceFragment extends PreferenceFragmentCompat { - - @Inject - @Named("default") - SharedPreferences sharedPreferences; - private Activity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.gestures_and_buttons_preference, rootKey); - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - SwitchPreference lockJumpToNextTopLevelCommentButtonSwitch = - findPreference(SharedPreferencesUtils.LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON); - SwitchPreference lockBottomAppBarSwitch = findPreference(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR); - SwitchPreference swipeUpToHideJumpToNextTopLevelCommentButtonSwitch = - findPreference(SharedPreferencesUtils.SWIPE_UP_TO_HIDE_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON); - SwitchPreference pullToRefreshSwitch = findPreference(SharedPreferencesUtils.PULL_TO_REFRESH); - - if (lockJumpToNextTopLevelCommentButtonSwitch != null && lockBottomAppBarSwitch != null && - swipeUpToHideJumpToNextTopLevelCommentButtonSwitch != null) { - lockJumpToNextTopLevelCommentButtonSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - if ((Boolean) newValue) { - swipeUpToHideJumpToNextTopLevelCommentButtonSwitch.setVisible(false); - } else { - swipeUpToHideJumpToNextTopLevelCommentButtonSwitch.setVisible(true); - } - return true; - }); - - if (sharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false)) { - lockBottomAppBarSwitch.setVisible(true); - lockBottomAppBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeLockBottomAppBarEvent((Boolean) newValue)); - return true; - }); - } - - if (!sharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON, false)) { - swipeUpToHideJumpToNextTopLevelCommentButtonSwitch.setVisible(true); - } - } - - if (pullToRefreshSwitch != null) { - pullToRefreshSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - EventBus.getDefault().post(new ChangePullToRefreshEvent((Boolean) newValue)); - return true; - } - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ImmersiveInterfacePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ImmersiveInterfacePreferenceFragment.java deleted file mode 100644 index 019f3593..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ImmersiveInterfacePreferenceFragment.java +++ /dev/null @@ -1,46 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.os.Bundle; - -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class ImmersiveInterfacePreferenceFragment extends PreferenceFragmentCompat { - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.immersive_interface_preferences, rootKey); - - SwitchPreference immersiveInterfaceSwitch = findPreference(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY); - SwitchPreference immersiveInterfaceIgnoreNavBarSwitch = findPreference(SharedPreferencesUtils.IMMERSIVE_INTERFACE_IGNORE_NAV_BAR_KEY); - - if (immersiveInterfaceSwitch != null && immersiveInterfaceIgnoreNavBarSwitch != null) { - immersiveInterfaceSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - if ((Boolean) newValue) { - immersiveInterfaceIgnoreNavBarSwitch.setVisible(true); - } else { - immersiveInterfaceIgnoreNavBarSwitch.setVisible(false); - } - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - - if (immersiveInterfaceSwitch.isChecked()) { - immersiveInterfaceIgnoreNavBarSwitch.setVisible(true); - } else { - immersiveInterfaceIgnoreNavBarSwitch.setVisible(false); - } - - immersiveInterfaceIgnoreNavBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/InterfacePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/InterfacePreferenceFragment.java deleted file mode 100644 index 29f33fc8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/InterfacePreferenceFragment.java +++ /dev/null @@ -1,101 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - - -import android.os.Build; -import android.os.Bundle; - -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import ml.docilealligator.infinityforreddit.Event.ChangeCompactLayoutToolbarHiddenByDefaultEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeDefaultPostLayoutEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeLongPressToHideToolbarInCompactLayoutEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeShowAbsoluteNumberOfVotesEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeVoteButtonsPositionEvent; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Event.ShowDividerInCompactLayoutPreferenceEvent; -import ml.docilealligator.infinityforreddit.Event.ShowThumbnailOnTheRightInCompactLayoutEvent; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class InterfacePreferenceFragment extends PreferenceFragmentCompat { - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.interface_preference, rootKey); - - Preference immersiveInterfaceEntryPreference = findPreference(SharedPreferencesUtils.IMMERSIVE_INTERFACE_ENTRY_KEY); - SwitchPreference bottomAppBarSwitch = findPreference(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY); - SwitchPreference voteButtonsOnTheRightSwitch = findPreference(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY); - ListPreference defaultPostLayoutSwitch = findPreference(SharedPreferencesUtils.DEFAULT_POST_LAYOUT_KEY); - SwitchPreference showDividerInCompactLayout = findPreference(SharedPreferencesUtils.SHOW_DIVIDER_IN_COMPACT_LAYOUT); - SwitchPreference showThumbnailOnTheRightInCompactLayout = findPreference(SharedPreferencesUtils.SHOW_THUMBNAIL_ON_THE_LEFT_IN_COMPACT_LAYOUT); - SwitchPreference showAbsoluteNumberOfVotes = findPreference(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES); - SwitchPreference longPressToHideToolbarInCompactLayoutSwitch = findPreference(SharedPreferencesUtils.LONG_PRESS_TO_HIDE_TOOLBAR_IN_COMPACT_LAYOUT); - SwitchPreference postCompactLayoutToolbarHiddenByDefaultSwitch = findPreference(SharedPreferencesUtils.POST_COMPACT_LAYOUT_TOOLBAR_HIDDEN_BY_DEFAULT); - - if (immersiveInterfaceEntryPreference != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - immersiveInterfaceEntryPreference.setVisible(true); - } - - if (bottomAppBarSwitch != null) { - bottomAppBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - } - - if (voteButtonsOnTheRightSwitch != null) { - voteButtonsOnTheRightSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeVoteButtonsPositionEvent((Boolean) newValue)); - return true; - }); - } - - if (defaultPostLayoutSwitch != null) { - defaultPostLayoutSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeDefaultPostLayoutEvent(Integer.parseInt((String) newValue))); - return true; - }); - } - - if (showDividerInCompactLayout != null) { - showDividerInCompactLayout.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ShowDividerInCompactLayoutPreferenceEvent((Boolean) newValue)); - return true; - }); - } - - if (showThumbnailOnTheRightInCompactLayout != null) { - showThumbnailOnTheRightInCompactLayout.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ShowThumbnailOnTheRightInCompactLayoutEvent((Boolean) newValue)); - return true; - }); - } - - if (showAbsoluteNumberOfVotes != null) { - showAbsoluteNumberOfVotes.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeShowAbsoluteNumberOfVotesEvent((Boolean) newValue)); - return true; - }); - } - - if (longPressToHideToolbarInCompactLayoutSwitch != null) { - longPressToHideToolbarInCompactLayoutSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeLongPressToHideToolbarInCompactLayoutEvent((Boolean) newValue)); - return true; - }); - } - - if (postCompactLayoutToolbarHiddenByDefaultSwitch != null) { - postCompactLayoutToolbarHiddenByDefaultSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeCompactLayoutToolbarHiddenByDefaultEvent((Boolean) newValue)); - return true; - }); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MainPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MainPreferenceFragment.java deleted file mode 100644 index 32aec40d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MainPreferenceFragment.java +++ /dev/null @@ -1,51 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.biometric.BiometricManager; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; -import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; - -public class MainPreferenceFragment extends PreferenceFragmentCompat { - - @Inject - @Named("default") - SharedPreferences sharedPreferences; - private AppCompatActivity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.main_preferences, rootKey); - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - Preference securityPreference = findPreference(SharedPreferencesUtils.SECURITY); - - BiometricManager biometricManager = BiometricManager.from(activity); - if (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) != BiometricManager.BIOMETRIC_SUCCESS) { - if (securityPreference != null) { - securityPreference.setVisible(false); - } - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (AppCompatActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MiscellaneousPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MiscellaneousPreferenceFragment.java deleted file mode 100644 index 1b8c69d9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/MiscellaneousPreferenceFragment.java +++ /dev/null @@ -1,67 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.Event.ChangeSavePostFeedScrolledPositionEvent; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class MiscellaneousPreferenceFragment extends PreferenceFragmentCompat { - - @Inject - @Named("post_feed_scrolled_position_cache") - SharedPreferences cache; - private Activity activity; - - public MiscellaneousPreferenceFragment() { - // Required empty public constructor - } - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.miscellaneous_preferences, rootKey); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - SwitchPreference confirmToExitSwitch = findPreference(SharedPreferencesUtils.CONFIRM_TO_EXIT); - SwitchPreference savePostFeedScrolledPositionSwitch = findPreference(SharedPreferencesUtils.SAVE_FRONT_PAGE_SCROLLED_POSITION); - - if (confirmToExitSwitch != null) { - confirmToExitSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new RecreateActivityEvent()); - return true; - }); - } - - if (savePostFeedScrolledPositionSwitch != null) { - savePostFeedScrolledPositionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - if (!(Boolean) newValue) { - cache.edit().clear().apply(); - } - EventBus.getDefault().post(new ChangeSavePostFeedScrolledPositionEvent((Boolean) newValue)); - return true; - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (AppCompatActivity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NotificationPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NotificationPreferenceFragment.java deleted file mode 100644 index 141e4ea4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NotificationPreferenceFragment.java +++ /dev/null @@ -1,127 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.preference.ListPreference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; -import androidx.work.Constraints; -import androidx.work.ExistingPeriodicWorkPolicy; -import androidx.work.NetworkType; -import androidx.work.PeriodicWorkRequest; -import androidx.work.WorkManager; - -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.PullNotificationWorker; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -/** - * A simple {@link Fragment} subclass. - */ -public class NotificationPreferenceFragment extends PreferenceFragmentCompat { - - @Inject - @Named("default") - SharedPreferences sharedPreferences; - private boolean enableNotification; - private long notificationInterval; - private WorkManager workManager; - private Activity activity; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.notification_preferences, rootKey); - - workManager = WorkManager.getInstance(activity); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - SwitchPreference enableNotificationSwitchPreference = findPreference(SharedPreferencesUtils.ENABLE_NOTIFICATION_KEY); - ListPreference notificationIntervalListPreference = findPreference(SharedPreferencesUtils.NOTIFICATION_INTERVAL_KEY); - - enableNotification = sharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_NOTIFICATION_KEY, true); - notificationInterval = Long.parseLong(sharedPreferences.getString(SharedPreferencesUtils.NOTIFICATION_INTERVAL_KEY, "1")); - - if (enableNotification) { - if (notificationIntervalListPreference != null) { - notificationIntervalListPreference.setVisible(true); - } - } - - if (enableNotificationSwitchPreference != null) { - enableNotificationSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { - enableNotification = ((Boolean) newValue); - if (notificationIntervalListPreference != null) { - notificationIntervalListPreference.setVisible(enableNotification); - } - - if (enableNotification) { - TimeUnit timeUnit = (notificationInterval == 15 || notificationInterval == 30) ? TimeUnit.MINUTES : TimeUnit.HOURS; - - Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); - - PeriodicWorkRequest pullNotificationRequest = - new PeriodicWorkRequest.Builder(PullNotificationWorker.class, - notificationInterval, timeUnit) - .setConstraints(constraints) - .setInitialDelay(notificationInterval, timeUnit) - .build(); - - workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, - ExistingPeriodicWorkPolicy.REPLACE, pullNotificationRequest); - } else { - workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); - } - return true; - }); - } - - if (notificationIntervalListPreference != null) { - notificationIntervalListPreference.setOnPreferenceChangeListener((preference, newValue) -> { - notificationInterval = Long.parseLong((String) newValue); - - if (enableNotification) { - TimeUnit timeUnit = (notificationInterval == 15 || notificationInterval == 30) ? TimeUnit.MINUTES : TimeUnit.HOURS; - - Constraints constraints = new Constraints.Builder() - .setRequiredNetworkType(NetworkType.CONNECTED) - .build(); - - PeriodicWorkRequest pullNotificationRequest = - new PeriodicWorkRequest.Builder(PullNotificationWorker.class, - notificationInterval, timeUnit) - .setConstraints(constraints) - .setInitialDelay(notificationInterval, timeUnit) - .build(); - - workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, - ExistingPeriodicWorkPolicy.REPLACE, pullNotificationRequest); - } else { - workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); - } - - return true; - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NsfwAndBlurringFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NsfwAndBlurringFragment.java deleted file mode 100644 index 470d10d5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NsfwAndBlurringFragment.java +++ /dev/null @@ -1,112 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.LinearLayout; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.fragment.app.Fragment; - -import com.google.android.material.switchmaterial.SwitchMaterial; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Named; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWBlurEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeNSFWEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSpoilerBlurEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class NsfwAndBlurringFragment extends Fragment { - - public static final String EXTRA_ACCOUNT_NAME = "EAN"; - - @BindView(R.id.enable_nsfw_linear_layout_nsfw_and_spoiler_fragment) - LinearLayout enableNsfwLinearLayout; - @BindView(R.id.enable_nsfw_switch_nsfw_and_spoiler_fragment) - SwitchMaterial enableNsfwSwitchMaterial; - @BindView(R.id.blur_nsfw_linear_layout_nsfw_and_spoiler_fragment) - LinearLayout blurNsfwLinearLayout; - @BindView(R.id.blur_nsfw_switch_nsfw_and_spoiler_fragment) - SwitchMaterial blurNsfwSwitchMaterial; - @BindView(R.id.blur_spoiler_linear_layout_nsfw_and_spoiler_fragment) - LinearLayout blurSpoilerLinearLayout; - @BindView(R.id.blur_spoiler_switch_nsfw_and_spoiler_fragment) - SwitchMaterial blurSpoilerSwitchMaterial; - @Inject - @Named("nsfw_and_spoiler") - SharedPreferences nsfwAndBlurringSharedPreferences; - - private Activity activity; - - public NsfwAndBlurringFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_nsfw_and_spoiler, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); - - boolean enableNsfw = nsfwAndBlurringSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); - boolean blurNsfw = nsfwAndBlurringSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, true); - boolean blurSpoiler = nsfwAndBlurringSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_SPOILER_BASE, false); - - if (enableNsfw) { - blurNsfwLinearLayout.setVisibility(View.VISIBLE); - } - - enableNsfwSwitchMaterial.setChecked(enableNsfw); - blurNsfwSwitchMaterial.setChecked(blurNsfw); - blurSpoilerSwitchMaterial.setChecked(blurSpoiler); - - enableNsfwLinearLayout.setOnClickListener(view -> enableNsfwSwitchMaterial.performClick()); - enableNsfwSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> { - nsfwAndBlurringSharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, b).apply(); - if (b) { - blurNsfwLinearLayout.setVisibility(View.VISIBLE); - } else { - blurNsfwLinearLayout.setVisibility(View.GONE); - } - EventBus.getDefault().post(new ChangeNSFWEvent(b)); - }); - - blurNsfwLinearLayout.setOnClickListener(view -> blurNsfwSwitchMaterial.performClick()); - blurNsfwSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> { - nsfwAndBlurringSharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, b).apply(); - EventBus.getDefault().post(new ChangeNSFWBlurEvent(b)); - }); - - blurSpoilerLinearLayout.setOnClickListener(view -> blurSpoilerSwitchMaterial.performClick()); - blurSpoilerSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> { - nsfwAndBlurringSharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_SPOILER_BASE, b).apply(); - EventBus.getDefault().post(new ChangeSpoilerBlurEvent(b)); - }); - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (AppCompatActivity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NumberOfColumnsInPostFeedPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NumberOfColumnsInPostFeedPreferenceFragment.java deleted file mode 100644 index 04052e07..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/NumberOfColumnsInPostFeedPreferenceFragment.java +++ /dev/null @@ -1,14 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.os.Bundle; - -import androidx.preference.PreferenceFragmentCompat; - -import ml.docilealligator.infinityforreddit.R; - -public class NumberOfColumnsInPostFeedPreferenceFragment extends PreferenceFragmentCompat { - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.number_of_columns_in_post_feed_preferences, rootKey); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SecurityPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SecurityPreferenceFragment.java deleted file mode 100644 index 9ee09d5c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SecurityPreferenceFragment.java +++ /dev/null @@ -1,77 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.content.Context; -import android.content.SharedPreferences; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.biometric.BiometricPrompt; -import androidx.core.content.ContextCompat; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import java.util.concurrent.Executor; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.Event.ChangeRequireAuthToAccountSectionEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; -import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; - -public class SecurityPreferenceFragment extends PreferenceFragmentCompat { - - private AppCompatActivity activity; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.security_preferences, rootKey); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - SwitchPreference requireAuthToAccountSectionSwitch = findPreference(SharedPreferencesUtils.REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER); - - if (requireAuthToAccountSectionSwitch != null) { - requireAuthToAccountSectionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeRequireAuthToAccountSectionEvent((Boolean) newValue)); - return true; - }); - } - } - - @Override - public void onResume() { - super.onResume(); - Executor executor = ContextCompat.getMainExecutor(activity); - BiometricPrompt biometricPrompt = new BiometricPrompt(SecurityPreferenceFragment.this, - executor, new BiometricPrompt.AuthenticationCallback() { - @Override - public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) { - activity.onBackPressed(); - } - }); - - BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() - .setTitle(activity.getString(R.string.unlock)) - .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) - .build(); - - biometricPrompt.authenticate(promptInfo); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (AppCompatActivity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SwipeActionPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SwipeActionPreferenceFragment.java deleted file mode 100644 index 4fe474ec..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/SwipeActionPreferenceFragment.java +++ /dev/null @@ -1,82 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.os.Bundle; - -import androidx.preference.ListPreference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import ml.docilealligator.infinityforreddit.Event.ChangeDisableSwipingBetweenTabsEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeEnableSwipeActionSwitchEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSwipeActionEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeSwipeActionThresholdEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeVibrateWhenActionTriggeredEvent; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class SwipeActionPreferenceFragment extends PreferenceFragmentCompat { - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.swipe_action_preferences, rootKey); - - SwitchPreference enableSwipeActionSwitch = findPreference(SharedPreferencesUtils.ENABLE_SWIPE_ACTION); - ListPreference swipeLeftActionListPreference = findPreference(SharedPreferencesUtils.SWIPE_LEFT_ACTION); - ListPreference swipeRightActionListPreference = findPreference(SharedPreferencesUtils.SWIPE_RIGHT_ACTION); - SwitchPreference vibrateWhenActionTriggeredSwitch = findPreference(SharedPreferencesUtils.VIBRATE_WHEN_ACTION_TRIGGERED); - SwitchPreference disableSwipingBetweenTabsSwitch = findPreference(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS); - ListPreference swipeActionThresholdListPreference = findPreference(SharedPreferencesUtils.SWIPE_ACTION_THRESHOLD); - - if (enableSwipeActionSwitch != null) { - enableSwipeActionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeEnableSwipeActionSwitchEvent((Boolean) newValue)); - return true; - }); - } - - if (swipeLeftActionListPreference != null) { - swipeLeftActionListPreference.setOnPreferenceChangeListener((preference, newValue) -> { - if (swipeRightActionListPreference != null) { - EventBus.getDefault().post(new ChangeSwipeActionEvent(Integer.parseInt((String) newValue), Integer.parseInt(swipeRightActionListPreference.getValue()))); - } else { - EventBus.getDefault().post(new ChangeSwipeActionEvent(Integer.parseInt((String) newValue), -1)); - } - return true; - }); - } - - if (swipeRightActionListPreference != null) { - swipeRightActionListPreference.setOnPreferenceChangeListener((preference, newValue) -> { - if (swipeLeftActionListPreference != null) { - EventBus.getDefault().post(new ChangeSwipeActionEvent(Integer.parseInt(swipeLeftActionListPreference.getValue()), Integer.parseInt((String) newValue))); - } else { - EventBus.getDefault().post(new ChangeSwipeActionEvent(-1, Integer.parseInt((String) newValue))); - } - return true; - }); - } - - if (vibrateWhenActionTriggeredSwitch != null) { - vibrateWhenActionTriggeredSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeVibrateWhenActionTriggeredEvent((Boolean) newValue)); - return true; - }); - } - - if (disableSwipingBetweenTabsSwitch != null) { - disableSwipingBetweenTabsSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeDisableSwipingBetweenTabsEvent((Boolean) newValue)); - return true; - }); - } - - if (swipeActionThresholdListPreference != null) { - swipeActionThresholdListPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeSwipeActionThresholdEvent(Float.parseFloat((String) newValue))); - return true; - }); - } - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ThemePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ThemePreferenceFragment.java deleted file mode 100644 index 01c55179..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/ThemePreferenceFragment.java +++ /dev/null @@ -1,193 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.content.Context; -import android.content.Intent; -import android.content.res.Configuration; -import android.os.Build; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.app.AppCompatDelegate; -import androidx.fragment.app.Fragment; -import androidx.lifecycle.ViewModelProvider; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; - -import ml.docilealligator.infinityforreddit.Activity.CustomThemeListingActivity; -import ml.docilealligator.infinityforreddit.Activity.CustomizeThemeActivity; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeViewModel; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Event.RecreateActivityEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.Utils.CustomThemeSharedPreferencesUtils; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; -import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; - -/** - * A simple {@link Fragment} subclass. - */ -public class ThemePreferenceFragment extends PreferenceFragmentCompat { - - private AppCompatActivity activity; - @Inject - RedditDataRoomDatabase redditDataRoomDatabase; - @Inject - CustomThemeWrapper customThemeWrapper; - public CustomThemeViewModel customThemeViewModel; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.theme_preferences, rootKey); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ListPreference themePreference = findPreference(SharedPreferencesUtils.THEME_KEY); - SwitchPreference amoledDarkSwitch = findPreference(SharedPreferencesUtils.AMOLED_DARK_KEY); - Preference customizeLightThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_LIGHT_THEME); - Preference customizeDarkThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_DARK_THEME); - Preference customizeAmoledThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_AMOLED_THEME); - Preference selectAndCustomizeThemePreference = findPreference(SharedPreferencesUtils.MANAGE_THEMES); - - boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; - if (themePreference != null && amoledDarkSwitch != null) { - if (systemDefault) { - themePreference.setEntries(R.array.settings_theme_q); - } else { - themePreference.setEntries(R.array.settings_theme); - } - - themePreference.setOnPreferenceChangeListener((preference, newValue) -> { - int option = Integer.parseInt((String) newValue); - switch (option) { - case 0: - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); - break; - case 1: - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); - if (amoledDarkSwitch.isChecked()) { - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); - } else { - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); - } - break; - case 2: - if (systemDefault) { - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM); - } else { - AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_AUTO_BATTERY); - } - - if((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) { - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); - } else { - if (amoledDarkSwitch.isChecked()) { - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); - } else { - customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); - } - } - } - return true; - }); - } - - if (amoledDarkSwitch != null) { - amoledDarkSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_NO) { - EventBus.getDefault().post(new RecreateActivityEvent()); - activity.recreate(); - } - return true; - }); - } - - if (customizeLightThemePreference != null) { - customizeLightThemePreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_TYPE, CustomizeThemeActivity.EXTRA_LIGHT_THEME); - startActivity(intent); - return true; - }); - } - - if (customizeDarkThemePreference != null) { - customizeDarkThemePreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_TYPE, CustomizeThemeActivity.EXTRA_DARK_THEME); - startActivity(intent); - return true; - }); - } - - if (customizeAmoledThemePreference != null) { - customizeAmoledThemePreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, CustomizeThemeActivity.class); - intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_TYPE, CustomizeThemeActivity.EXTRA_AMOLED_THEME); - startActivity(intent); - return true; - }); - } - - if (selectAndCustomizeThemePreference != null) { - selectAndCustomizeThemePreference.setOnPreferenceClickListener(preference -> { - Intent intent = new Intent(activity, CustomThemeListingActivity.class); - startActivity(intent); - return true; - }); - } - - customThemeViewModel = new ViewModelProvider(this, - new CustomThemeViewModel.Factory(redditDataRoomDatabase)) - .get(CustomThemeViewModel.class); - customThemeViewModel.getCurrentLightThemeLiveData().observe(this, customTheme -> { - if (customizeLightThemePreference != null) { - if (customTheme != null) { - customizeLightThemePreference.setVisible(true); - customizeLightThemePreference.setSummary(customTheme.name); - } else { - customizeLightThemePreference.setVisible(false); - } - } - }); - customThemeViewModel.getCurrentDarkThemeLiveData().observe(this, customTheme -> { - if (customizeDarkThemePreference != null) { - if (customTheme != null) { - customizeDarkThemePreference.setVisible(true); - customizeDarkThemePreference.setSummary(customTheme.name); - } else { - customizeDarkThemePreference.setVisible(false); - } - } - }); - customThemeViewModel.getCurrentAmoledThemeLiveData().observe(this, customTheme -> { - if (customizeAmoledThemePreference != null) { - if (customTheme != null) { - customizeAmoledThemePreference.setVisible(true); - customizeAmoledThemePreference.setSummary(customTheme.name); - } else { - customizeAmoledThemePreference.setVisible(false); - } - } - }); - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (AppCompatActivity) context; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TimeFormatPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TimeFormatPreferenceFragment.java deleted file mode 100644 index f0adfe12..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TimeFormatPreferenceFragment.java +++ /dev/null @@ -1,38 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.os.Bundle; - -import androidx.preference.ListPreference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import ml.docilealligator.infinityforreddit.Event.ChangeShowElapsedTimeEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeTimeFormatEvent; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class TimeFormatPreferenceFragment extends PreferenceFragmentCompat { - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.time_format_preferences, rootKey); - - SwitchPreference showElapsedTimeSwitch = findPreference(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY); - ListPreference timeFormatList = findPreference(SharedPreferencesUtils.TIME_FORMAT_KEY); - - if (showElapsedTimeSwitch != null) { - showElapsedTimeSwitch.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeShowElapsedTimeEvent((Boolean) newValue)); - return true; - }); - } - - if (timeFormatList != null) { - timeFormatList.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeTimeFormatEvent((String) newValue)); - return true; - }); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Translation.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Translation.java deleted file mode 100644 index 80968ae4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/Translation.java +++ /dev/null @@ -1,44 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.R; - -public class Translation { - public String language; - public String contributors; - public int flagDrawableId; - - public Translation(String language, String contributors, int flagDrawableId) { - this.language = language; - this.contributors = contributors; - this.flagDrawableId = flagDrawableId; - } - - public static ArrayList getTranslationContributors() { - ArrayList translationContributors = new ArrayList<>(); - translationContributors.add(new Translation("български", "Кристиян", R.drawable.flag_bulgaria)); - translationContributors.add(new Translation("简体中文", "cdggqa, Gloria, Justin, Steps", R.drawable.flag_china)); - translationContributors.add(new Translation("繁體中文", "", R.drawable.flag_china)); - translationContributors.add(new Translation("Hrvatski", "Josip", R.drawable.flag_croatia)); - translationContributors.add(new Translation("Nederlands", "Khawkfist", R.drawable.flag_netherlands)); - translationContributors.add(new Translation("Française", "367, Finn Olmsted, oursonbleu, Owen, pinembour", R.drawable.flag_france)); - translationContributors.add(new Translation("Deutsche", "Jorge, Netto Hikari, Nikodiamond3, translatewingman, translatorwiz", R.drawable.flag_germany)); - translationContributors.add(new Translation("Ελληνικά", "Marios, Viktor", R.drawable.flag_greece)); - translationContributors.add(new Translation("हिंदी", "a, Arya, charu, Mrigendra Bhandari, raghav, Sachin, Ved", R.drawable.flag_india)); - translationContributors.add(new Translation("Magyar", "Zoltan", R.drawable.flag_hungary)); - translationContributors.add(new Translation("Italiana", "Daniele Basso, DanOlivaw, Gianni00palmieri, Gillauino, Matisse, Simoneg. work, ztiaa", R.drawable.flag_italy)); - translationContributors.add(new Translation("日本語", "Hira, Issa, Mrigendra Bhandari, Ryan", R.drawable.flag_japan)); - translationContributors.add(new Translation("한국어", "noname", R.drawable.flag_south_korea)); - translationContributors.add(new Translation("norsk", "", R.drawable.flag_norway)); - translationContributors.add(new Translation("Português", "Bruno Guerreiro, Lucas, Ricky", R.drawable.flag_portugal)); - translationContributors.add(new Translation("Português (BR)", "Laura Vasconcellos Pereira Felippe, Ricky, Super_Iguanna", R.drawable.flag_brazil)); - translationContributors.add(new Translation("Română", "", R.drawable.flag_romania)); - translationContributors.add(new Translation("русский язык", "aveblazer, flexagoon, Georgiy, Vova", R.drawable.flag_russia)); - translationContributors.add(new Translation("Español", "Alejandro, Jorge, Miguel, mvstermoe, Nana Snixx, Sofia Flores", R.drawable.flag_spain)); - translationContributors.add(new Translation("svenska", "Marcus Nordberg", R.drawable.flag_sweden)); - translationContributors.add(new Translation("Türk", "Emir481, Faoiltiarna, Mehmet Yavuz, Serif", R.drawable.flag_turkey)); - translationContributors.add(new Translation("Tiếng Việt", "Kai, Laezzy, Lmao, Ryan, viecdet69", R.drawable.flag_vietnam)); - return translationContributors; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TranslationFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TranslationFragment.java deleted file mode 100644 index 44ad57e8..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/TranslationFragment.java +++ /dev/null @@ -1,58 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import javax.inject.Inject; - -import butterknife.BindView; -import butterknife.ButterKnife; -import ml.docilealligator.infinityforreddit.Adapter.TranslationFragmentRecyclerViewAdapter; -import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; - -public class TranslationFragment extends Fragment { - - @BindView(R.id.recycler_view_translation_fragment) - RecyclerView recyclerView; - @Inject - CustomThemeWrapper customThemeWrapper; - private Activity activity; - - public TranslationFragment() { - // Required empty public constructor - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - // Inflate the layout for this fragment - View rootView = inflater.inflate(R.layout.fragment_translation, container, false); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ButterKnife.bind(this, rootView); - - TranslationFragmentRecyclerViewAdapter adapter = new TranslationFragmentRecyclerViewAdapter(activity, customThemeWrapper); - recyclerView.setLayoutManager(new LinearLayoutManager(activity)); - recyclerView.setAdapter(adapter); - - return rootView; - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - activity = (Activity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/VideoPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/VideoPreferenceFragment.java deleted file mode 100644 index aa8bc2dd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Settings/VideoPreferenceFragment.java +++ /dev/null @@ -1,113 +0,0 @@ -package ml.docilealligator.infinityforreddit.Settings; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.res.Configuration; -import android.os.Bundle; - -import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; -import androidx.preference.ListPreference; -import androidx.preference.Preference; -import androidx.preference.PreferenceFragmentCompat; -import androidx.preference.SeekBarPreference; -import androidx.preference.SwitchPreference; - -import org.greenrobot.eventbus.EventBus; - -import javax.inject.Inject; -import javax.inject.Named; - -import ml.docilealligator.infinityforreddit.Event.ChangeAutoplayNsfwVideosEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeMuteAutoplayingVideosEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeMuteNSFWVideoEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeStartAutoplayVisibleAreaOffsetEvent; -import ml.docilealligator.infinityforreddit.Event.ChangeVideoAutoplayEvent; -import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; - -public class VideoPreferenceFragment extends PreferenceFragmentCompat { - - private Activity activity; - @Inject - @Named("default") - SharedPreferences sharedPreferences; - - @Override - public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { - setPreferencesFromResource(R.xml.video_preferences, rootKey); - - ((Infinity) activity.getApplication()).getAppComponent().inject(this); - - ListPreference videoAutoplayListPreference = findPreference(SharedPreferencesUtils.VIDEO_AUTOPLAY); - SwitchPreference muteAutoplayingVideosSwitchPreference = findPreference(SharedPreferencesUtils.MUTE_AUTOPLAYING_VIDEOS); - SwitchPreference muteNSFWVideosSwitchPreference = findPreference(SharedPreferencesUtils.MUTE_NSFW_VIDEO); - SwitchPreference autoplayNsfwVideosSwitchPreference = findPreference(SharedPreferencesUtils.AUTOPLAY_NSFW_VIDEOS); - SeekBarPreference startAutoplayVisibleAreaOffsetPortrait = findPreference(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT); - SeekBarPreference startAutoplayVisibleAreaOffsetLandscape = findPreference(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_LANDSCAPE); - - if (videoAutoplayListPreference != null && autoplayNsfwVideosSwitchPreference != null) { - videoAutoplayListPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeVideoAutoplayEvent((String) newValue)); - return true; - }); - - autoplayNsfwVideosSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeAutoplayNsfwVideosEvent((Boolean) newValue)); - return true; - }); - } - - if (muteNSFWVideosSwitchPreference != null) { - muteNSFWVideosSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeMuteNSFWVideoEvent((Boolean) newValue)); - return true; - }); - } - - if (muteAutoplayingVideosSwitchPreference != null) { - muteAutoplayingVideosSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { - EventBus.getDefault().post(new ChangeMuteAutoplayingVideosEvent((Boolean) newValue)); - return true; - }); - } - - int orientation = getResources().getConfiguration().orientation; - - if (startAutoplayVisibleAreaOffsetPortrait != null) { - startAutoplayVisibleAreaOffsetPortrait.setSummary( - getString(R.string.settings_start_autoplay_visible_area_offset_portrait_summary, - sharedPreferences.getInt(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT, 75))); - startAutoplayVisibleAreaOffsetPortrait.setOnPreferenceChangeListener((Preference.OnPreferenceChangeListener) (preference, newValue) -> { - if (orientation == Configuration.ORIENTATION_PORTRAIT) { - EventBus.getDefault().post(new ChangeStartAutoplayVisibleAreaOffsetEvent((Integer) newValue)); - } - startAutoplayVisibleAreaOffsetPortrait.setSummary( - getString(R.string.settings_start_autoplay_visible_area_offset_portrait_summary, (Integer) newValue)); - return true; - }); - } - - if (startAutoplayVisibleAreaOffsetLandscape != null) { - startAutoplayVisibleAreaOffsetLandscape.setSummary( - getString(R.string.settings_start_autoplay_visible_area_offset_portrait_summary, - sharedPreferences.getInt(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_LANDSCAPE, 50))); - startAutoplayVisibleAreaOffsetLandscape.setOnPreferenceChangeListener((Preference.OnPreferenceChangeListener) (preference, newValue) -> { - if (orientation == Configuration.ORIENTATION_LANDSCAPE) { - EventBus.getDefault().post(new ChangeStartAutoplayVisibleAreaOffsetEvent((Integer) newValue)); - } - startAutoplayVisibleAreaOffsetLandscape.setSummary( - getString(R.string.settings_start_autoplay_visible_area_offset_landscape_summary, (Integer) newValue)); - return true; - }); - } - } - - @Override - public void onAttach(@NonNull Context context) { - super.onAttach(context); - this.activity = (AppCompatActivity) context; - } -} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/FetchSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/FetchSubredditData.java deleted file mode 100644 index f75ed256..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/FetchSubredditData.java +++ /dev/null @@ -1,94 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import androidx.annotation.NonNull; - -import com.facebook.common.internal.ImmutableMap; - -import java.util.ArrayList; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class FetchSubredditData { - public static void fetchSubredditData(Retrofit retrofit, String subredditName, final FetchSubredditDataListener fetchSubredditDataListener) { - RedditAPI api = retrofit.create(RedditAPI.class); - - Call subredditData = api.getSubredditData(subredditName); - subredditData.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseSubredditData.parseSubredditData(response.body(), new ParseSubredditData.ParseSubredditDataListener() { - @Override - public void onParseSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { - fetchSubredditDataListener.onFetchSubredditDataSuccess(subredditData, nCurrentOnlineSubscribers); - } - - @Override - public void onParseSubredditDataFail() { - fetchSubredditDataListener.onFetchSubredditDataFail(); - } - }); - } else { - fetchSubredditDataListener.onFetchSubredditDataFail(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchSubredditDataListener.onFetchSubredditDataFail(); - } - }); - } - - static void fetchSubredditListingData(Retrofit retrofit, String query, String after, String sortType, String accessToken, - boolean nsfw, final FetchSubredditListingDataListener fetchSubredditListingDataListener) { - RedditAPI api = retrofit.create(RedditAPI.class); - - Map headers = accessToken != null ? APIUtils.getOAuthHeader(accessToken) : ImmutableMap.of(); - Call subredditDataCall = api.searchSubreddits(query, after, sortType, nsfw ? 1 : 0, headers); - subredditDataCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - ParseSubredditData.parseSubredditListingData(response.body(), nsfw, - new ParseSubredditData.ParseSubredditListingDataListener() { - @Override - public void onParseSubredditListingDataSuccess(ArrayList subredditData, String after) { - fetchSubredditListingDataListener.onFetchSubredditListingDataSuccess(subredditData, after); - } - - @Override - public void onParseSubredditListingDataFail() { - fetchSubredditListingDataListener.onFetchSubredditListingDataFail(); - } - }); - } else { - fetchSubredditListingDataListener.onFetchSubredditListingDataFail(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchSubredditListingDataListener.onFetchSubredditListingDataFail(); - } - }); - } - - public interface FetchSubredditDataListener { - void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers); - - void onFetchSubredditDataFail(); - } - - interface FetchSubredditListingDataListener { - void onFetchSubredditListingDataSuccess(ArrayList subredditData, String after); - - void onFetchSubredditListingDataFail(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/ParseSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/ParseSubredditData.java deleted file mode 100644 index 1a4bcb74..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/ParseSubredditData.java +++ /dev/null @@ -1,173 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import android.os.AsyncTask; - -import androidx.annotation.Nullable; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; -import ml.docilealligator.infinityforreddit.Utils.Utils; - -class ParseSubredditData { - static void parseSubredditData(String response, ParseSubredditDataListener parseSubredditDataListener) { - new ParseSubredditDataAsyncTask(response, parseSubredditDataListener).execute(); - } - - static void parseSubredditListingData(String response, boolean nsfw, ParseSubredditListingDataListener parseSubredditListingDataListener) { - new ParseSubredditListingDataAsyncTask(response, nsfw, parseSubredditListingDataListener).execute(); - } - - @Nullable - private static SubredditData parseSubredditData(JSONObject subredditDataJsonObject, boolean nsfw) throws JSONException { - boolean isNSFW = !subredditDataJsonObject.isNull(JSONUtils.OVER18_KEY) && subredditDataJsonObject.getBoolean(JSONUtils.OVER18_KEY); - if (!nsfw && isNSFW) { - return null; - } - String id = subredditDataJsonObject.getString(JSONUtils.NAME_KEY); - String subredditFullName = subredditDataJsonObject.getString(JSONUtils.DISPLAY_NAME_KEY); - String description = subredditDataJsonObject.getString(JSONUtils.PUBLIC_DESCRIPTION_KEY).trim(); - String sidebarDescription = Utils.modifyMarkdown(subredditDataJsonObject.getString(JSONUtils.DESCRIPTION_KEY).trim()); - long createdUTC = subredditDataJsonObject.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; - String suggestedCommentSort = subredditDataJsonObject.getString(JSONUtils.SUGGESTED_COMMENT_SORT_KEY); - - String bannerImageUrl; - if (subredditDataJsonObject.isNull(JSONUtils.BANNER_BACKGROUND_IMAGE_KEY)) { - bannerImageUrl = ""; - } else { - bannerImageUrl = subredditDataJsonObject.getString(JSONUtils.BANNER_BACKGROUND_IMAGE_KEY); - } - if (bannerImageUrl.equals("") && !subredditDataJsonObject.isNull(JSONUtils.BANNER_IMG_KEY)) { - bannerImageUrl = subredditDataJsonObject.getString(JSONUtils.BANNER_IMG_KEY); - } - - String iconUrl; - if (subredditDataJsonObject.isNull(JSONUtils.COMMUNITY_ICON_KEY)) { - iconUrl = ""; - } else { - iconUrl = subredditDataJsonObject.getString(JSONUtils.COMMUNITY_ICON_KEY); - } - if (iconUrl.equals("") && !subredditDataJsonObject.isNull(JSONUtils.ICON_IMG_KEY)) { - iconUrl = subredditDataJsonObject.getString(JSONUtils.ICON_IMG_KEY); - } - - int nSubscribers = 0; - if (!subredditDataJsonObject.isNull(JSONUtils.SUBSCRIBERS_KEY)) { - nSubscribers = subredditDataJsonObject.getInt(JSONUtils.SUBSCRIBERS_KEY); - } - - return new SubredditData(id, subredditFullName, iconUrl, bannerImageUrl, description, - sidebarDescription, nSubscribers, createdUTC, suggestedCommentSort, isNSFW); - } - - interface ParseSubredditDataListener { - void onParseSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers); - - void onParseSubredditDataFail(); - } - - interface ParseSubredditListingDataListener { - void onParseSubredditListingDataSuccess(ArrayList subredditData, String after); - - void onParseSubredditListingDataFail(); - } - - private static class ParseSubredditDataAsyncTask extends AsyncTask { - private JSONObject jsonResponse; - private boolean parseFailed; - private ParseSubredditDataListener parseSubredditDataListener; - private SubredditData subredditData; - private int mNCurrentOnlineSubscribers; - - ParseSubredditDataAsyncTask(String response, ParseSubredditDataListener parseSubredditDataListener) { - this.parseSubredditDataListener = parseSubredditDataListener; - try { - jsonResponse = new JSONObject(response); - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseSubredditDataListener.onParseSubredditDataFail(); - } - } - - @Override - protected Void doInBackground(Void... voids) { - try { - JSONObject data = jsonResponse.getJSONObject(JSONUtils.DATA_KEY); - mNCurrentOnlineSubscribers = data.getInt(JSONUtils.ACTIVE_USER_COUNT_KEY); - subredditData = parseSubredditData(data, true); - } catch (JSONException e) { - parseFailed = true; - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - parseSubredditDataListener.onParseSubredditDataSuccess(subredditData, mNCurrentOnlineSubscribers); - } else { - parseSubredditDataListener.onParseSubredditDataFail(); - } - } - } - - private static class ParseSubredditListingDataAsyncTask extends AsyncTask { - private JSONObject jsonResponse; - private boolean nsfw; - private boolean parseFailed; - private ParseSubredditListingDataListener parseSubredditListingDataListener; - private ArrayList subredditListingData; - private String after; - - ParseSubredditListingDataAsyncTask(String response, boolean nsfw, ParseSubredditListingDataListener parseSubredditListingDataListener) { - this.parseSubredditListingDataListener = parseSubredditListingDataListener; - try { - jsonResponse = new JSONObject(response); - this.nsfw = nsfw; - parseFailed = false; - subredditListingData = new ArrayList<>(); - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - @Override - protected Void doInBackground(Void... voids) { - try { - if (!parseFailed) { - JSONArray children = jsonResponse.getJSONObject(JSONUtils.DATA_KEY) - .getJSONArray(JSONUtils.CHILDREN_KEY); - for (int i = 0; i < children.length(); i++) { - JSONObject data = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); - SubredditData subredditData = parseSubredditData(data, nsfw); - if (subredditData != null) { - subredditListingData.add(subredditData); - } - } - after = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); - } - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - parseSubredditListingDataListener.onParseSubredditListingDataFail(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - parseSubredditListingDataListener.onParseSubredditListingDataSuccess(subredditListingData, after); - } else { - parseSubredditListingDataListener.onParseSubredditListingDataFail(); - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditDao.java deleted file mode 100644 index d6b07312..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -@Dao -public interface SubredditDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(SubredditData SubredditData); - - @Query("DELETE FROM subreddits") - void deleteAllSubreddits(); - - @Query("SELECT * from subreddits WHERE name = :namePrefixed COLLATE NOCASE LIMIT 1") - LiveData getSubredditLiveDataByName(String namePrefixed); - - @Query("SELECT * from subreddits WHERE name = :namePrefixed COLLATE NOCASE LIMIT 1") - SubredditData getSubredditData(String namePrefixed); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditData.java deleted file mode 100644 index f05e5912..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditData.java +++ /dev/null @@ -1,88 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.PrimaryKey; - -@Entity(tableName = "subreddits") -public class SubredditData { - @PrimaryKey - @NonNull - @ColumnInfo(name = "id") - private String id; - @ColumnInfo(name = "name") - private String name; - @ColumnInfo(name = "icon") - private String iconUrl; - @ColumnInfo(name = "banner") - private String bannerUrl; - @ColumnInfo(name = "description") - private String description; - @ColumnInfo(name = "sidebar_description") - private String sidebarDescription; - @ColumnInfo(name = "subscribers_count") - private int nSubscribers; - @ColumnInfo(name = "created_utc") - private long createdUTC; - @ColumnInfo(name = "suggested_comment_sort") - private String suggestedCommentSort; - @ColumnInfo(name = "over18") - private boolean isNSFW; - - public SubredditData(@NonNull String id, String name, String iconUrl, String bannerUrl, - String description, String sidebarDescription, int nSubscribers, long createdUTC, - String suggestedCommentSort, boolean isNSFW) { - this.id = id; - this.name = name; - this.iconUrl = iconUrl; - this.bannerUrl = bannerUrl; - this.description = description; - this.sidebarDescription = sidebarDescription; - this.nSubscribers = nSubscribers; - this.createdUTC = createdUTC; - this.suggestedCommentSort = suggestedCommentSort; - this.isNSFW = isNSFW; - } - - @NonNull - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getIconUrl() { - return iconUrl; - } - - public String getBannerUrl() { - return bannerUrl; - } - - public String getDescription() { - return description; - } - - public String getSidebarDescription() { - return sidebarDescription; - } - - public int getNSubscribers() { - return nSubscribers; - } - - public long getCreatedUTC() { - return createdUTC; - } - - public String getSuggestedCommentSort() { - return suggestedCommentSort; - } - - public boolean isNSFW() { - return isNSFW; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSource.java deleted file mode 100644 index b260c985..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSource.java +++ /dev/null @@ -1,108 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.PageKeyedDataSource; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -public class SubredditListingDataSource extends PageKeyedDataSource { - - private Retrofit retrofit; - private String query; - private SortType sortType; - private String accessToken; - private boolean nsfw; - - private MutableLiveData paginationNetworkStateLiveData; - private MutableLiveData initialLoadStateLiveData; - private MutableLiveData hasSubredditLiveData; - - private LoadParams params; - private LoadCallback callback; - - SubredditListingDataSource(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { - this.retrofit = retrofit; - this.query = query; - this.sortType = sortType; - this.accessToken = accessToken; - this.nsfw = nsfw; - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasSubredditLiveData = new MutableLiveData<>(); - } - - MutableLiveData getPaginationNetworkStateLiveData() { - return paginationNetworkStateLiveData; - } - - MutableLiveData getInitialLoadStateLiveData() { - return initialLoadStateLiveData; - } - - MutableLiveData hasSubredditLiveData() { - return hasSubredditLiveData; - } - - @Override - public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { - initialLoadStateLiveData.postValue(NetworkState.LOADING); - - FetchSubredditData.fetchSubredditListingData(retrofit, query, null, sortType.getType().value, accessToken, nsfw, - new FetchSubredditData.FetchSubredditListingDataListener() { - @Override - public void onFetchSubredditListingDataSuccess(ArrayList subredditData, String after) { - if (subredditData.size() == 0) { - hasSubredditLiveData.postValue(false); - } else { - hasSubredditLiveData.postValue(true); - } - - callback.onResult(subredditData, null, after); - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onFetchSubredditListingDataFail() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving subreddit list")); - } - }); - } - - @Override - public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { - - } - - @Override - public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { - this.params = params; - this.callback = callback; - - if (params.key.equals("") || params.key.equals("null")) { - return; - } - - FetchSubredditData.fetchSubredditListingData(retrofit, query, params.key, sortType.getType().value, accessToken, nsfw, - new FetchSubredditData.FetchSubredditListingDataListener() { - @Override - public void onFetchSubredditListingDataSuccess(ArrayList subredditData, String after) { - callback.onResult(subredditData, after); - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onFetchSubredditListingDataFail() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving subreddit list")); - } - }); - } - - void retryLoadingMore() { - loadAfter(params, callback); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSourceFactory.java deleted file mode 100644 index 22e57d26..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingDataSourceFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.DataSource; - -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -public class SubredditListingDataSourceFactory extends DataSource.Factory { - private Retrofit retrofit; - private String query; - private SortType sortType; - private String accessToken; - private boolean nsfw; - - private SubredditListingDataSource subredditListingDataSource; - private MutableLiveData subredditListingDataSourceMutableLiveData; - - SubredditListingDataSourceFactory(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { - this.retrofit = retrofit; - this.query = query; - this.sortType = sortType; - this.accessToken = accessToken; - this.nsfw = nsfw; - subredditListingDataSourceMutableLiveData = new MutableLiveData<>(); - } - - @NonNull - @Override - public DataSource create() { - subredditListingDataSource = new SubredditListingDataSource(retrofit, query, sortType, accessToken, nsfw); - subredditListingDataSourceMutableLiveData.postValue(subredditListingDataSource); - return subredditListingDataSource; - } - - public MutableLiveData getSubredditListingDataSourceMutableLiveData() { - return subredditListingDataSourceMutableLiveData; - } - - SubredditListingDataSource getSubredditListingDataSource() { - return subredditListingDataSource; - } - - void changeSortType(SortType sortType) { - this.sortType = sortType; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingViewModel.java deleted file mode 100644 index 80c1f4b9..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditListingViewModel.java +++ /dev/null @@ -1,98 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; -import androidx.paging.LivePagedListBuilder; -import androidx.paging.PagedList; - -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -public class SubredditListingViewModel extends ViewModel { - private SubredditListingDataSourceFactory subredditListingDataSourceFactory; - private LiveData paginationNetworkState; - private LiveData initialLoadingState; - private LiveData hasSubredditLiveData; - private LiveData> subreddits; - private MutableLiveData sortTypeLiveData; - - public SubredditListingViewModel(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { - subredditListingDataSourceFactory = new SubredditListingDataSourceFactory(retrofit, query, sortType, accessToken, nsfw); - - initialLoadingState = Transformations.switchMap(subredditListingDataSourceFactory.getSubredditListingDataSourceMutableLiveData(), - SubredditListingDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(subredditListingDataSourceFactory.getSubredditListingDataSourceMutableLiveData(), - SubredditListingDataSource::getPaginationNetworkStateLiveData); - hasSubredditLiveData = Transformations.switchMap(subredditListingDataSourceFactory.getSubredditListingDataSourceMutableLiveData(), - SubredditListingDataSource::hasSubredditLiveData); - - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - subreddits = Transformations.switchMap(sortTypeLiveData, sort -> { - subredditListingDataSourceFactory.changeSortType(sortTypeLiveData.getValue()); - return new LivePagedListBuilder(subredditListingDataSourceFactory, pagedListConfig).build(); - }); - } - - public LiveData> getSubreddits() { - return subreddits; - } - - public LiveData getPaginationNetworkState() { - return paginationNetworkState; - } - - public LiveData getInitialLoadingState() { - return initialLoadingState; - } - - public LiveData hasSubredditLiveData() { - return hasSubredditLiveData; - } - - public void refresh() { - subredditListingDataSourceFactory.getSubredditListingDataSource().invalidate(); - } - - public void retryLoadingMore() { - subredditListingDataSourceFactory.getSubredditListingDataSource().retryLoadingMore(); - } - - public void changeSortType(SortType sortType) { - sortTypeLiveData.postValue(sortType); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Retrofit retrofit; - private String query; - private SortType sortType; - private String accessToken; - private boolean nsfw; - - public Factory(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { - this.retrofit = retrofit; - this.query = query; - this.sortType = sortType; - this.accessToken = accessToken; - this.nsfw = nsfw; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new SubredditListingViewModel(retrofit, query, sortType, accessToken, nsfw); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditRepository.java deleted file mode 100644 index 66817e40..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditRepository.java +++ /dev/null @@ -1,40 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import android.os.AsyncTask; - -import androidx.lifecycle.LiveData; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SubredditRepository { - private SubredditDao mSubredditDao; - private LiveData mSubredditLiveData; - - SubredditRepository(RedditDataRoomDatabase redditDataRoomDatabase, String subredditName) { - mSubredditDao = redditDataRoomDatabase.subredditDao(); - mSubredditLiveData = mSubredditDao.getSubredditLiveDataByName(subredditName); - } - - LiveData getSubredditLiveData() { - return mSubredditLiveData; - } - - public void insert(SubredditData subredditData) { - new InsertAsyncTask(mSubredditDao).execute(subredditData); - } - - private static class InsertAsyncTask extends AsyncTask { - - private SubredditDao mAsyncTaskDao; - - InsertAsyncTask(SubredditDao dao) { - mAsyncTaskDao = dao; - } - - @Override - protected Void doInBackground(final SubredditData... params) { - mAsyncTaskDao.insert(params[0]); - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditSubscription.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditSubscription.java deleted file mode 100644 index 5475e319..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditSubscription.java +++ /dev/null @@ -1,120 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import android.os.AsyncTask; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Retrofit; - -public class SubredditSubscription { - public static void subscribeToSubreddit(Retrofit oauthRetrofit, Retrofit retrofit, - String accessToken, String subredditName, String accountName, - RedditDataRoomDatabase redditDataRoomDatabase, - SubredditSubscriptionListener subredditSubscriptionListener) { - subredditSubscription(oauthRetrofit, retrofit, accessToken, subredditName, accountName, "sub", - redditDataRoomDatabase, subredditSubscriptionListener); - } - - public static void unsubscribeToSubreddit(Retrofit oauthRetrofit, String accessToken, - String subredditName, String accountName, - RedditDataRoomDatabase redditDataRoomDatabase, - SubredditSubscriptionListener subredditSubscriptionListener) { - subredditSubscription(oauthRetrofit, null, accessToken, subredditName, accountName, "unsub", - redditDataRoomDatabase, subredditSubscriptionListener); - } - - private static void subredditSubscription(Retrofit oauthRetrofit, Retrofit retrofit, String accessToken, - String subredditName, String accountName, String action, - RedditDataRoomDatabase redditDataRoomDatabase, - SubredditSubscriptionListener subredditSubscriptionListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Map params = new HashMap<>(); - params.put(APIUtils.ACTION_KEY, action); - params.put(APIUtils.SR_NAME_KEY, subredditName); - - Call subredditSubscriptionCall = api.subredditSubscription(APIUtils.getOAuthHeader(accessToken), params); - subredditSubscriptionCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - if (action.equals("sub")) { - FetchSubredditData.fetchSubredditData(retrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { - @Override - public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { - new UpdateSubscriptionAsyncTask(redditDataRoomDatabase, - subredditData, accountName, true).execute(); - } - - @Override - public void onFetchSubredditDataFail() { - - } - }); - } else { - new UpdateSubscriptionAsyncTask(redditDataRoomDatabase, subredditName, accountName, false).execute(); - } - subredditSubscriptionListener.onSubredditSubscriptionSuccess(); - } else { - subredditSubscriptionListener.onSubredditSubscriptionFail(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - subredditSubscriptionListener.onSubredditSubscriptionFail(); - } - }); - } - - public interface SubredditSubscriptionListener { - void onSubredditSubscriptionSuccess(); - - void onSubredditSubscriptionFail(); - } - - private static class UpdateSubscriptionAsyncTask extends AsyncTask { - - private RedditDataRoomDatabase redditDataRoomDatabase; - private String subredditName; - private String accountName; - private SubscribedSubredditData subscribedSubredditData; - private boolean isSubscribing; - - UpdateSubscriptionAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String subredditName, - String accountName, boolean isSubscribing) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.subredditName = subredditName; - this.accountName = accountName; - this.isSubscribing = isSubscribing; - } - - UpdateSubscriptionAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, SubredditData subredditData, - String accountName, boolean isSubscribing) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.subscribedSubredditData = new SubscribedSubredditData(subredditData.getId(), subredditData.getName(), - subredditData.getIconUrl(), accountName, false); - this.accountName = accountName; - this.isSubscribing = isSubscribing; - } - - @Override - protected Void doInBackground(Void... voids) { - if (isSubscribing) { - redditDataRoomDatabase.subscribedSubredditDao().insert(subscribedSubredditData); - } else { - redditDataRoomDatabase.subscribedSubredditDao().deleteSubscribedSubreddit(subredditName, accountName); - } - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditViewModel.java deleted file mode 100644 index 46829c3b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditViewModel.java +++ /dev/null @@ -1,51 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SubredditViewModel extends AndroidViewModel { - private SubredditRepository mSubredditRepository; - private LiveData mSubredditLiveData; - - public SubredditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String id) { - super(application); - mSubredditRepository = new SubredditRepository(redditDataRoomDatabase, id); - mSubredditLiveData = mSubredditRepository.getSubredditLiveData(); - } - - public LiveData getSubredditLiveData() { - return mSubredditLiveData; - } - - public void insert(SubredditData subredditData) { - mSubredditRepository.insert(subredditData); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - - @NonNull - private final Application mApplication; - private final RedditDataRoomDatabase mRedditDataRoomDatabase; - private final String mSubredditName; - - public Factory(@NonNull Application application, RedditDataRoomDatabase redditDataRoomDatabase, String subredditname) { - mApplication = application; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mSubredditName = subredditname; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - //noinspection unchecked - return (T) new SubredditViewModel(mApplication, mRedditDataRoomDatabase, mSubredditName); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditWithSelection.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditWithSelection.java deleted file mode 100644 index a8cd289f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Subreddit/SubredditWithSelection.java +++ /dev/null @@ -1,101 +0,0 @@ -package ml.docilealligator.infinityforreddit.Subreddit; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.Nullable; - -import java.util.ArrayList; -import java.util.List; - -import ml.docilealligator.infinityforreddit.SubscribedSubreddit.SubscribedSubredditData; - -public class SubredditWithSelection implements Parcelable { - private String name; - private String iconUrl; - private boolean selected; - - public SubredditWithSelection(String name, String iconUrl) { - this.name = name; - this.iconUrl = iconUrl; - selected = false; - } - - protected SubredditWithSelection(Parcel in) { - super(); - name = in.readString(); - iconUrl = in.readString(); - selected = in.readByte() != 0; - } - - public static final Creator CREATOR = new Creator() { - @Override - public SubredditWithSelection createFromParcel(Parcel in) { - return new SubredditWithSelection(in); - } - - @Override - public SubredditWithSelection[] newArray(int size) { - return new SubredditWithSelection[size]; - } - }; - - public String getName() { - return name; - } - - public String getIconUrl() { - return iconUrl; - } - - public boolean isSelected() { - return selected; - } - - public void setSelected(boolean selected) { - this.selected = selected; - } - - public static ArrayList convertSubscribedSubreddits( - List subscribedSubredditData) { - ArrayList subredditWithSelections = new ArrayList<>(); - for (SubscribedSubredditData s : subscribedSubredditData) { - subredditWithSelections.add(new SubredditWithSelection(s.getName(), s.getIconUrl())); - } - - return subredditWithSelections; - } - - public static SubredditWithSelection convertSubreddit(SubredditData subreddit) { - return new SubredditWithSelection(subreddit.getName(), subreddit.getIconUrl()); - } - - public int compareName(SubredditWithSelection subredditWithSelection) { - if (subredditWithSelection != null) { - return name.compareToIgnoreCase(subredditWithSelection.getName()); - } else { - return -1; - } - } - - @Override - public boolean equals(@Nullable Object obj) { - if (!(obj instanceof SubredditWithSelection)) { - return false; - } else { - return this.getName().compareToIgnoreCase(((SubredditWithSelection) obj).getName()) == 0; - } - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(name); - parcel.writeString(iconUrl); - parcel.writeByte((byte) (selected ? 1 : 0)); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/DeleteSubredditFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/DeleteSubredditFilter.java deleted file mode 100644 index 63b856dc..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/DeleteSubredditFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubredditFilter; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class DeleteSubredditFilter { - public interface DeleteSubredditFilterListener { - void success(); - } - - public static void deleteSubredditFilter(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, - DeleteSubredditFilterListener deleteSubredditFilterListener) { - new DeleteSubredditFilterAsyncTask(redditDataRoomDatabase, subredditFilter, deleteSubredditFilterListener).execute(); - } - - private static class DeleteSubredditFilterAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private SubredditFilter subredditFilter; - private DeleteSubredditFilterListener deleteSubredditFilterListener; - - DeleteSubredditFilterAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, - DeleteSubredditFilterListener deleteSubredditFilterListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.subredditFilter = subredditFilter; - this.deleteSubredditFilterListener = deleteSubredditFilterListener; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.subredditFilterDao().deleteSubredditFilter(subredditFilter); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - deleteSubredditFilterListener.success(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/FetchSubredditFilters.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/FetchSubredditFilters.java deleted file mode 100644 index 74864fc7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/FetchSubredditFilters.java +++ /dev/null @@ -1,42 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubredditFilter; - -import android.os.AsyncTask; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class FetchSubredditFilters { - public interface FetchSubredditFiltersListener { - void success(ArrayListsubredditFilters); - } - - public static void fetchSubredditFilters(RedditDataRoomDatabase redditDataRoomDatabase, - FetchSubredditFiltersListener fetchSubredditFiltersListener) { - new FetchSubredditFiltersAsyncTask(redditDataRoomDatabase, fetchSubredditFiltersListener).execute(); - } - - private static class FetchSubredditFiltersAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private ArrayList subredditFilters; - private FetchSubredditFiltersListener fetchSubredditFiltersListener; - - FetchSubredditFiltersAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, - FetchSubredditFiltersListener fetchSubredditFiltersListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.fetchSubredditFiltersListener = fetchSubredditFiltersListener; - } - - @Override - protected Void doInBackground(Void... voids) { - subredditFilters = (ArrayList) redditDataRoomDatabase.subredditFilterDao().getAllSubredditFilters(); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - fetchSubredditFiltersListener.success(subredditFilters); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/InsertSubredditFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/InsertSubredditFilter.java deleted file mode 100644 index b91fa1e2..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/InsertSubredditFilter.java +++ /dev/null @@ -1,41 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubredditFilter; - -import android.os.AsyncTask; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class InsertSubredditFilter { - public interface InsertSubredditFilterListener { - void success(); - } - - public static void insertSubredditFilter(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, - InsertSubredditFilterListener insertSubredditFilterListener) { - new InsertSubredditFilterAsyncTask(redditDataRoomDatabase, subredditFilter, insertSubredditFilterListener).execute(); - } - - private static class InsertSubredditFilterAsyncTask extends AsyncTask { - private RedditDataRoomDatabase redditDataRoomDatabase; - private SubredditFilter subredditFilter; - private InsertSubredditFilterListener insertSubredditFilterListener; - - InsertSubredditFilterAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, - InsertSubredditFilterListener insertSubredditFilterListener) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - this.subredditFilter = subredditFilter; - this.insertSubredditFilterListener = insertSubredditFilterListener; - } - - @Override - protected Void doInBackground(Void... voids) { - redditDataRoomDatabase.subredditFilterDao().insert(subredditFilter); - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - super.onPostExecute(aVoid); - insertSubredditFilterListener.success(); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java deleted file mode 100644 index ddfa01f0..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilter.java +++ /dev/null @@ -1,68 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubredditFilter; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; - -@Entity(tableName = "subreddit_filter", primaryKeys = {"subreddit_name", "type"}) -public class SubredditFilter implements Parcelable { - public static int TYPE_POPULAR_AND_ALL = 0; - @NonNull - @ColumnInfo(name = "subreddit_name") - private String subredditName; - @ColumnInfo(name = "type") - private int type; - - public SubredditFilter(@NonNull String subredditName, int type) { - this.subredditName = subredditName; - this.type = type; - } - - protected SubredditFilter(Parcel in) { - subredditName = in.readString(); - type = in.readInt(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public SubredditFilter createFromParcel(Parcel in) { - return new SubredditFilter(in); - } - - @Override - public SubredditFilter[] newArray(int size) { - return new SubredditFilter[size]; - } - }; - - @NonNull - public String getSubredditName() { - return subredditName; - } - - public void setSubredditName(@NonNull String subredditName) { - this.subredditName = subredditName; - } - - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel parcel, int i) { - parcel.writeString(subredditName); - parcel.writeInt(type); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterDao.java deleted file mode 100644 index fb5d3829..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterDao.java +++ /dev/null @@ -1,25 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubredditFilter; - -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 SubredditFilterDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(SubredditFilter subredditFilter); - - @Query("SELECT * FROM subreddit_filter") - LiveData> getAllSubredditFiltersLiveData(); - - @Query("SELECT * FROM subreddit_filter") - List getAllSubredditFilters(); - - @Delete - void deleteSubredditFilter(SubredditFilter subredditFilter); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterViewModel.java deleted file mode 100644 index 557e879d..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubredditFilter/SubredditFilterViewModel.java +++ /dev/null @@ -1,36 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubredditFilter; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SubredditFilterViewModel extends ViewModel { - private LiveData> subredditFilterLiveData; - - public SubredditFilterViewModel(RedditDataRoomDatabase redditDataRoomDatabase) { - subredditFilterLiveData = redditDataRoomDatabase.subredditFilterDao().getAllSubredditFiltersLiveData(); - } - - public LiveData> getSubredditFilterLiveData() { - return subredditFilterLiveData; - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private RedditDataRoomDatabase redditDataRoomDatabase; - - public Factory(RedditDataRoomDatabase redditDataRoomDatabase) { - this.redditDataRoomDatabase = redditDataRoomDatabase; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new SubredditFilterViewModel(redditDataRoomDatabase); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditDao.java deleted file mode 100644 index 225c4cb4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditDao.java +++ /dev/null @@ -1,33 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedSubreddit; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -import java.util.List; - -@Dao -public interface SubscribedSubredditDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(SubscribedSubredditData subscribedSubredditData); - - @Query("DELETE FROM subscribed_subreddits") - void deleteAllSubscribedSubreddits(); - - @Query("SELECT * from subscribed_subreddits WHERE username = :accountName ORDER BY name COLLATE NOCASE ASC") - LiveData> getAllSubscribedSubreddits(String accountName); - - @Query("SELECT * from subscribed_subreddits WHERE username = :accountName COLLATE NOCASE ORDER BY name COLLATE NOCASE ASC") - List getAllSubscribedSubredditsList(String accountName); - - @Query("SELECT * from subscribed_subreddits WHERE username = :accountName COLLATE NOCASE AND is_favorite = 1 ORDER BY name COLLATE NOCASE ASC") - LiveData> getAllFavoriteSubscribedSubreddits(String accountName); - - @Query("SELECT * from subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE LIMIT 1") - SubscribedSubredditData getSubscribedSubreddit(String subredditName, String accountName); - - @Query("DELETE FROM subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE") - void deleteSubscribedSubreddit(String subredditName, String accountName); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditData.java deleted file mode 100644 index 167e6423..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditData.java +++ /dev/null @@ -1,65 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedSubreddit; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.ForeignKey; - -import ml.docilealligator.infinityforreddit.Account.Account; - -@Entity(tableName = "subscribed_subreddits", primaryKeys = {"id", "username"}, - foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", - childColumns = "username", onDelete = ForeignKey.CASCADE)) -public class SubscribedSubredditData { - @NonNull - @ColumnInfo(name = "id") - private String id; - @ColumnInfo(name = "name") - private String name; - @ColumnInfo(name = "icon") - private String iconUrl; - @NonNull - @ColumnInfo(name = "username") - private String username; - @ColumnInfo(name = "is_favorite") - private boolean favorite; - - public SubscribedSubredditData(@NonNull String id, String name, String iconUrl, @NonNull String username, - boolean favorite) { - this.id = id; - this.name = name; - this.iconUrl = iconUrl; - this.username = username; - this.favorite = favorite; - } - - @NonNull - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getIconUrl() { - return iconUrl; - } - - @NonNull - public String getUsername() { - return username; - } - - public void setUsername(@NonNull String username) { - this.username = username; - } - - public boolean isFavorite() { - return favorite; - } - - public void setFavorite(boolean favorite) { - this.favorite = favorite; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditRepository.java deleted file mode 100644 index aa5fbc0f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditRepository.java +++ /dev/null @@ -1,48 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedSubreddit; - -import android.os.AsyncTask; - -import androidx.lifecycle.LiveData; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SubscribedSubredditRepository { - private SubscribedSubredditDao mSubscribedSubredditDao; - private LiveData> mAllSubscribedSubreddits; - private LiveData> mAllFavoriteSubscribedSubreddits; - - SubscribedSubredditRepository(RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - mSubscribedSubredditDao = redditDataRoomDatabase.subscribedSubredditDao(); - mAllSubscribedSubreddits = mSubscribedSubredditDao.getAllSubscribedSubreddits(accountName); - mAllFavoriteSubscribedSubreddits = mSubscribedSubredditDao.getAllFavoriteSubscribedSubreddits(accountName); - } - - LiveData> getAllSubscribedSubreddits() { - return mAllSubscribedSubreddits; - } - - public LiveData> getAllFavoriteSubscribedSubreddits() { - return mAllFavoriteSubscribedSubreddits; - } - - public void insert(SubscribedSubredditData subscribedSubredditData) { - new insertAsyncTask(mSubscribedSubredditDao).execute(subscribedSubredditData); - } - - private static class insertAsyncTask extends AsyncTask { - - private SubscribedSubredditDao mAsyncTaskDao; - - insertAsyncTask(SubscribedSubredditDao dao) { - mAsyncTaskDao = dao; - } - - @Override - protected Void doInBackground(final SubscribedSubredditData... params) { - mAsyncTaskDao.insert(params[0]); - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditViewModel.java deleted file mode 100644 index 79e3dd2b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedSubreddit/SubscribedSubredditViewModel.java +++ /dev/null @@ -1,56 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedSubreddit; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SubscribedSubredditViewModel extends AndroidViewModel { - private SubscribedSubredditRepository mSubscribedSubredditRepository; - private LiveData> mAllSubscribedSubreddits; - private LiveData> mAllFavoriteSubscribedSubreddits; - - public SubscribedSubredditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - super(application); - mSubscribedSubredditRepository = new SubscribedSubredditRepository(redditDataRoomDatabase, accountName); - mAllSubscribedSubreddits = mSubscribedSubredditRepository.getAllSubscribedSubreddits(); - mAllFavoriteSubscribedSubreddits = mSubscribedSubredditRepository.getAllFavoriteSubscribedSubreddits(); - } - - public LiveData> getAllSubscribedSubreddits() { - return mAllSubscribedSubreddits; - } - - public LiveData> getAllFavoriteSubscribedSubreddits() { - return mAllFavoriteSubscribedSubreddits; - } - - public void insert(SubscribedSubredditData subscribedSubredditData) { - mSubscribedSubredditRepository.insert(subscribedSubredditData); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Application mApplication; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private String mAccountName; - - public Factory(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - this.mApplication = application; - this.mRedditDataRoomDatabase = redditDataRoomDatabase; - this.mAccountName = accountName; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new SubscribedSubredditViewModel(mApplication, mRedditDataRoomDatabase, mAccountName); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserDao.java deleted file mode 100644 index 66660b8c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserDao.java +++ /dev/null @@ -1,30 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedUserDatabase; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -import java.util.List; - -@Dao -public interface SubscribedUserDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(SubscribedUserData subscribedUserData); - - @Query("SELECT * FROM subscribed_users WHERE username = :accountName COLLATE NOCASE ORDER BY name COLLATE NOCASE ASC") - LiveData> getAllSubscribedUsers(String accountName); - - @Query("SELECT * FROM subscribed_users WHERE username = :accountName COLLATE NOCASE ORDER BY name COLLATE NOCASE ASC") - List getAllSubscribedUsersList(String accountName); - - @Query("SELECT * FROM subscribed_users WHERE username = :accountName COLLATE NOCASE AND is_favorite = 1 ORDER BY name COLLATE NOCASE ASC") - LiveData> getAllFavoriteSubscribedUsers(String accountName); - - @Query("SELECT * FROM subscribed_users WHERE name = :name COLLATE NOCASE AND username = :accountName COLLATE NOCASE LIMIT 1") - SubscribedUserData getSubscribedUser(String name, String accountName); - - @Query("DELETE FROM subscribed_users WHERE name = :name COLLATE NOCASE AND username = :accountName COLLATE NOCASE") - void deleteSubscribedUser(String name, String accountName); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserData.java deleted file mode 100644 index 6c7bb7e7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserData.java +++ /dev/null @@ -1,57 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedUserDatabase; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.ForeignKey; - -import ml.docilealligator.infinityforreddit.Account.Account; - -@Entity(tableName = "subscribed_users", primaryKeys = {"name", "username"}, - foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", - childColumns = "username", onDelete = ForeignKey.CASCADE)) -public class SubscribedUserData { - @NonNull - @ColumnInfo(name = "name") - private String name; - @ColumnInfo(name = "icon") - private String iconUrl; - @NonNull - @ColumnInfo(name = "username") - private String username; - @ColumnInfo(name = "is_favorite") - private boolean favorite; - - public SubscribedUserData(@NonNull String name, String iconUrl, @NonNull String username, boolean favorite) { - this.name = name; - this.iconUrl = iconUrl; - this.username = username; - this.favorite = favorite; - } - - @NonNull - public String getName() { - return name; - } - - public String getIconUrl() { - return iconUrl; - } - - @NonNull - public String getUsername() { - return username; - } - - public void setUsername(@NonNull String username) { - this.username = username; - } - - public boolean isFavorite() { - return favorite; - } - - public void setFavorite(boolean favorite) { - this.favorite = favorite; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserRepository.java deleted file mode 100644 index f5a1c1ab..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserRepository.java +++ /dev/null @@ -1,48 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedUserDatabase; - -import android.os.AsyncTask; - -import androidx.lifecycle.LiveData; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SubscribedUserRepository { - private SubscribedUserDao mSubscribedUserDao; - private LiveData> mAllSubscribedUsers; - private LiveData> mAllFavoriteSubscribedUsers; - - SubscribedUserRepository(RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - mSubscribedUserDao = redditDataRoomDatabase.subscribedUserDao(); - mAllSubscribedUsers = mSubscribedUserDao.getAllSubscribedUsers(accountName); - mAllFavoriteSubscribedUsers = mSubscribedUserDao.getAllFavoriteSubscribedUsers(accountName); - } - - LiveData> getAllSubscribedSubreddits() { - return mAllSubscribedUsers; - } - - LiveData> getAllFavoriteSubscribedSubreddits() { - return mAllFavoriteSubscribedUsers; - } - - public void insert(SubscribedUserData subscribedUserData) { - new SubscribedUserRepository.insertAsyncTask(mSubscribedUserDao).execute(subscribedUserData); - } - - private static class insertAsyncTask extends AsyncTask { - - private SubscribedUserDao mAsyncTaskDao; - - insertAsyncTask(SubscribedUserDao dao) { - mAsyncTaskDao = dao; - } - - @Override - protected Void doInBackground(final SubscribedUserData... params) { - mAsyncTaskDao.insert(params[0]); - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserViewModel.java deleted file mode 100644 index 9f1b033f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/SubscribedUserDatabase/SubscribedUserViewModel.java +++ /dev/null @@ -1,56 +0,0 @@ -package ml.docilealligator.infinityforreddit.SubscribedUserDatabase; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import java.util.List; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class SubscribedUserViewModel extends AndroidViewModel { - private SubscribedUserRepository mSubscribedUserRepository; - private LiveData> mAllSubscribedUsers; - private LiveData> mAllFavoriteSubscribedUsers; - - public SubscribedUserViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - super(application); - mSubscribedUserRepository = new SubscribedUserRepository(redditDataRoomDatabase, accountName); - mAllSubscribedUsers = mSubscribedUserRepository.getAllSubscribedSubreddits(); - mAllFavoriteSubscribedUsers = mSubscribedUserRepository.getAllFavoriteSubscribedSubreddits(); - } - - public LiveData> getAllSubscribedUsers() { - return mAllSubscribedUsers; - } - - public LiveData> getAllFavoriteSubscribedUsers() { - return mAllFavoriteSubscribedUsers; - } - - public void insert(SubscribedUserData subscribedUserData) { - mSubscribedUserRepository.insert(subscribedUserData); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Application mApplication; - private RedditDataRoomDatabase mRedditDataRoomDatabase; - private String mAccountName; - - public Factory(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { - mApplication = application; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mAccountName = accountName; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new SubscribedUserViewModel(mApplication, mRedditDataRoomDatabase, mAccountName); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/BlockUser.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/BlockUser.java deleted file mode 100644 index ca6dd1d1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/BlockUser.java +++ /dev/null @@ -1,40 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import retrofit2.Retrofit; - -public class BlockUser { - public interface BlockUserListener { - void success(); - void failed(); - } - - public static void blockUser(Retrofit oauthRetrofit, String accessToken, String username, BlockUserListener blockUserListener) { - Map params = new HashMap<>(); - params.put(APIUtils.NAME_KEY, username); - oauthRetrofit.create(RedditAPI.class).blockUser(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull Response response) { - if (response.isSuccessful()) { - blockUserListener.success(); - } else { - blockUserListener.failed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - blockUserListener.failed(); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/FetchUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/FetchUserData.java deleted file mode 100644 index f214bec1..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/FetchUserData.java +++ /dev/null @@ -1,87 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import androidx.annotation.NonNull; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Retrofit; - -public class FetchUserData { - public static void fetchUserData(Retrofit retrofit, String userName, FetchUserDataListener fetchUserDataListener) { - RedditAPI api = retrofit.create(RedditAPI.class); - - Call userInfo = api.getUserData(userName); - userInfo.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParseUserData.parseUserData(response.body(), new ParseUserData.ParseUserDataListener() { - @Override - public void onParseUserDataSuccess(UserData userData) { - fetchUserDataListener.onFetchUserDataSuccess(userData); - } - - @Override - public void onParseUserDataFailed() { - fetchUserDataListener.onFetchUserDataFailed(); - } - }); - } else { - fetchUserDataListener.onFetchUserDataFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchUserDataListener.onFetchUserDataFailed(); - } - }); - } - - public static void fetchUserListingData(Retrofit retrofit, String query, String after, String sortType, boolean nsfw, - FetchUserListingDataListener fetchUserListingDataListener) { - RedditAPI api = retrofit.create(RedditAPI.class); - - Call userInfo = api.searchUsers(query, after, sortType, nsfw ? 1 : 0); - userInfo.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - ParseUserData.parseUserListingData(response.body(), new ParseUserData.ParseUserListingDataListener() { - @Override - public void onParseUserListingDataSuccess(ArrayList userData, String after) { - fetchUserListingDataListener.onFetchUserListingDataSuccess(userData, after); - } - - @Override - public void onParseUserListingDataFailed() { - fetchUserListingDataListener.onFetchUserListingDataFailed(); - } - }); - } else { - fetchUserListingDataListener.onFetchUserListingDataFailed(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - fetchUserListingDataListener.onFetchUserListingDataFailed(); - } - }); - } - - public interface FetchUserDataListener { - void onFetchUserDataSuccess(UserData userData); - - void onFetchUserDataFailed(); - } - - public interface FetchUserListingDataListener { - void onFetchUserListingDataSuccess(ArrayList userData, String after); - - void onFetchUserListingDataFailed(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/ParseUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/ParseUserData.java deleted file mode 100644 index e640d7e3..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/ParseUserData.java +++ /dev/null @@ -1,156 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import android.os.AsyncTask; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.Utils.JSONUtils; - -public class ParseUserData { - static void parseUserData(String response, ParseUserDataListener parseUserDataListener) { - new ParseUserDataAsyncTask(response, parseUserDataListener).execute(); - } - - static void parseUserListingData(String response, ParseUserListingDataListener parseUserListingDataListener) { - new ParseUserListingDataAsyncTask(response, parseUserListingDataListener).execute(); - } - - private static UserData parseUserDataBase(JSONObject userDataJson) throws JSONException { - if(userDataJson == null) { - return null; - } - - userDataJson = userDataJson.getJSONObject(JSONUtils.DATA_KEY); - String userName = userDataJson.getString(JSONUtils.NAME_KEY); - String iconImageUrl = userDataJson.getString(JSONUtils.ICON_IMG_KEY); - String bannerImageUrl = ""; - boolean canBeFollowed; - if (userDataJson.has(JSONUtils.SUBREDDIT_KEY) && !userDataJson.isNull(JSONUtils.SUBREDDIT_KEY)) { - bannerImageUrl = userDataJson.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.BANNER_IMG_KEY); - canBeFollowed = true; - } else { - canBeFollowed = false; - } - int linkKarma = userDataJson.getInt(JSONUtils.LINK_KARMA_KEY); - int commentKarma = userDataJson.getInt(JSONUtils.COMMENT_KARMA_KEY); - int awarderKarma = userDataJson.getInt(JSONUtils.AWARDER_KARMA_KEY); - int awardeeKarma = userDataJson.getInt(JSONUtils.AWARDEE_KARMA_KEY); - int totalKarma = userDataJson.getInt(JSONUtils.TOTAL_KARMA_KEY); - long cakeday = userDataJson.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; - boolean isGold = userDataJson.getBoolean(JSONUtils.IS_GOLD_KEY); - boolean isFriend = userDataJson.getBoolean(JSONUtils.IS_FRIEND_KEY); - boolean isNsfw = userDataJson.getJSONObject(JSONUtils.SUBREDDIT_KEY).getBoolean(JSONUtils.OVER_18_KEY); - String description = userDataJson.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.PUBLIC_DESCRIPTION_KEY); - - return new UserData(userName, iconImageUrl, bannerImageUrl, linkKarma, commentKarma, awarderKarma, - awardeeKarma, totalKarma, cakeday, isGold, isFriend, canBeFollowed, isNsfw, description); - } - - interface ParseUserDataListener { - void onParseUserDataSuccess(UserData userData); - - void onParseUserDataFailed(); - } - - interface ParseUserListingDataListener { - void onParseUserListingDataSuccess(ArrayList userData, String after); - - void onParseUserListingDataFailed(); - } - - private static class ParseUserDataAsyncTask extends AsyncTask { - private JSONObject jsonResponse; - private ParseUserDataListener parseUserDataListener; - private boolean parseFailed; - - private UserData userData; - - ParseUserDataAsyncTask(String response, ParseUserDataListener parseUserDataListener) { - try { - jsonResponse = new JSONObject(response); - this.parseUserDataListener = parseUserDataListener; - parseFailed = false; - } catch (JSONException e) { - e.printStackTrace(); - parseUserDataListener.onParseUserDataFailed(); - } - } - - @Override - protected Void doInBackground(Void... voids) { - try { - userData = parseUserDataBase(jsonResponse); - } catch (JSONException e) { - parseFailed = true; - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - parseUserDataListener.onParseUserDataSuccess(userData); - } else { - parseUserDataListener.onParseUserDataFailed(); - } - } - } - - private static class ParseUserListingDataAsyncTask extends AsyncTask { - private String response; - private JSONObject jsonResponse; - private ParseUserListingDataListener parseUserListingDataListener; - private String after; - private boolean parseFailed; - - private ArrayList userDataArrayList; - - ParseUserListingDataAsyncTask(String response, ParseUserListingDataListener parseUserListingDataListener) { - this.parseUserListingDataListener = parseUserListingDataListener; - this.response = response; - try { - jsonResponse = new JSONObject(response); - parseFailed = false; - userDataArrayList = new ArrayList<>(); - } catch (JSONException e) { - e.printStackTrace(); - parseFailed = true; - } - } - - @Override - protected Void doInBackground(Void... voids) { - try { - if (!parseFailed) { - after = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); - JSONArray children = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); - for (int i = 0; i < children.length(); i++) { - userDataArrayList.add(parseUserDataBase(children.getJSONObject(i))); - } - } - } catch (JSONException e) { - parseFailed = true; - e.printStackTrace(); - } - return null; - } - - @Override - protected void onPostExecute(Void aVoid) { - if (!parseFailed) { - parseUserListingDataListener.onParseUserListingDataSuccess(userDataArrayList, after); - } else { - if (response.equals("\"{}\"")) { - parseUserListingDataListener.onParseUserListingDataSuccess(new ArrayList<>(), null); - } else { - parseUserListingDataListener.onParseUserListingDataFailed(); - } - } - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserDao.java deleted file mode 100644 index b7221c26..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserDao.java +++ /dev/null @@ -1,22 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import androidx.lifecycle.LiveData; -import androidx.room.Dao; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; - -@Dao -public interface UserDao { - @Insert(onConflict = OnConflictStrategy.REPLACE) - void insert(UserData userData); - - @Query("DELETE FROM users") - void deleteAllUsers(); - - @Query("SELECT * FROM users WHERE name = :userName COLLATE NOCASE LIMIT 1") - LiveData getUserLiveData(String userName); - - @Query("SELECT * FROM users WHERE name = :userName COLLATE NOCASE LIMIT 1") - UserData getUserData(String userName); -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserData.java deleted file mode 100644 index 2e4243c7..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserData.java +++ /dev/null @@ -1,116 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import androidx.annotation.NonNull; -import androidx.room.ColumnInfo; -import androidx.room.Entity; -import androidx.room.PrimaryKey; - -@Entity(tableName = "users") -public class UserData { - @PrimaryKey - @NonNull - @ColumnInfo(name = "name") - private String name; - @ColumnInfo(name = "icon") - private String iconUrl; - @ColumnInfo(name = "banner") - private String banner; - @ColumnInfo(name = "link_karma") - private int linkKarma; - @ColumnInfo(name = "comment_karma") - private int commentKarma; - @ColumnInfo(name = "awarder_karma") - private int awarderKarma; - @ColumnInfo(name = "awardee_karma") - private int awardeeKarma; - @ColumnInfo(name = "total_karma") - private int totalKarma; - @ColumnInfo(name = "created_utc") - private long cakeday; - @ColumnInfo(name = "is_gold") - private boolean isGold; - @ColumnInfo(name = "is_friend") - private boolean isFriend; - @ColumnInfo(name = "can_be_followed") - private boolean canBeFollowed; - @ColumnInfo(name = "over_18") - private boolean isNSFW; - @ColumnInfo(name = "description") - private String description; - - public UserData(@NonNull String name, String iconUrl, String banner, int linkKarma, int commentKarma, - int awarderKarma, int awardeeKarma, int totalKarma, long cakeday, boolean isGold, - boolean isFriend, boolean canBeFollowed, boolean isNSFW, String description) { - this.name = name; - this.iconUrl = iconUrl; - this.banner = banner; - this.commentKarma = commentKarma; - this.linkKarma = linkKarma; - this.awarderKarma = awarderKarma; - this.awarderKarma = awardeeKarma; - this.totalKarma = totalKarma; - this.cakeday = cakeday; - this.isGold = isGold; - this.isFriend = isFriend; - this.canBeFollowed = canBeFollowed; - this.isNSFW = isNSFW; - this.description = description; - } - - @NonNull - public String getName() { - return name; - } - - public String getIconUrl() { - return iconUrl; - } - - public String getBanner() { - return banner; - } - - public int getLinkKarma() { - return linkKarma; - } - - public int getCommentKarma() { - return commentKarma; - } - - public int getAwarderKarma() { - return awarderKarma; - } - - public int getAwardeeKarma() { - return awardeeKarma; - } - - public int getTotalKarma() { - return totalKarma; - } - - public long getCakeday() { - return cakeday; - } - - public boolean isGold() { - return isGold; - } - - public boolean isFriend() { - return isFriend; - } - - public boolean isCanBeFollowed() { - return canBeFollowed; - } - - public boolean isNSFW() { - return isNSFW; - } - - public String getDescription() { - return description; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserFollowing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserFollowing.java deleted file mode 100644 index d49acf25..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserFollowing.java +++ /dev/null @@ -1,118 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import android.os.AsyncTask; - -import androidx.annotation.NonNull; - -import java.util.HashMap; -import java.util.Map; - -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserDao; -import ml.docilealligator.infinityforreddit.SubscribedUserDatabase.SubscribedUserData; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Retrofit; - -public class UserFollowing { - public static void followUser(Retrofit oauthRetrofit, Retrofit retrofit, - String accessToken, String username, String accountName, - SubscribedUserDao subscribedUserDao, - UserFollowingListener userFollowingListener) { - userFollowing(oauthRetrofit, retrofit, accessToken, username, accountName, "sub", - subscribedUserDao, userFollowingListener); - } - - public static void unfollowUser(Retrofit oauthRetrofit, Retrofit retrofit, - String accessToken, String username, String accountName, - SubscribedUserDao subscribedUserDao, - UserFollowingListener userFollowingListener) { - userFollowing(oauthRetrofit, retrofit, accessToken, username, accountName, "unsub", - subscribedUserDao, userFollowingListener); - } - - private static void userFollowing(Retrofit oauthRetrofit, Retrofit retrofit, String accessToken, - String username, String accountName, String action, SubscribedUserDao subscribedUserDao, - UserFollowingListener userFollowingListener) { - RedditAPI api = oauthRetrofit.create(RedditAPI.class); - - Map params = new HashMap<>(); - params.put(APIUtils.ACTION_KEY, action); - params.put(APIUtils.SR_NAME_KEY, "u_" + username); - - Call subredditSubscriptionCall = api.subredditSubscription(APIUtils.getOAuthHeader(accessToken), params); - subredditSubscriptionCall.enqueue(new Callback() { - @Override - public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { - if (response.isSuccessful()) { - if (action.equals("sub")) { - FetchUserData.fetchUserData(retrofit, username, new FetchUserData.FetchUserDataListener() { - @Override - public void onFetchUserDataSuccess(UserData userData) { - new UpdateSubscriptionAsyncTask(subscribedUserDao, userData, accountName, true).execute(); - } - - @Override - public void onFetchUserDataFailed() { - - } - }); - } else { - new UpdateSubscriptionAsyncTask(subscribedUserDao, username, accountName, false).execute(); - } - userFollowingListener.onUserFollowingSuccess(); - } else { - userFollowingListener.onUserFollowingFail(); - } - } - - @Override - public void onFailure(@NonNull Call call, @NonNull Throwable t) { - userFollowingListener.onUserFollowingFail(); - } - }); - } - - public interface UserFollowingListener { - void onUserFollowingSuccess(); - - void onUserFollowingFail(); - } - - private static class UpdateSubscriptionAsyncTask extends AsyncTask { - - private SubscribedUserDao subscribedUserDao; - private String username; - private String accountName; - private SubscribedUserData subscribedUserData; - private boolean isSubscribing; - - UpdateSubscriptionAsyncTask(SubscribedUserDao subscribedUserDao, String username, - String accountName, boolean isSubscribing) { - this.subscribedUserDao = subscribedUserDao; - this.username = username; - this.accountName = accountName; - this.isSubscribing = isSubscribing; - } - - UpdateSubscriptionAsyncTask(SubscribedUserDao subscribedUserDao, UserData userData, - String accountName, boolean isSubscribing) { - this.subscribedUserDao = subscribedUserDao; - this.subscribedUserData = new SubscribedUserData(userData.getName(), userData.getIconUrl(), - accountName, false); - this.accountName = accountName; - this.isSubscribing = isSubscribing; - } - - @Override - protected Void doInBackground(Void... voids) { - if (isSubscribing) { - subscribedUserDao.insert(subscribedUserData); - } else { - subscribedUserDao.deleteSubscribedUser(username, accountName); - } - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSource.java deleted file mode 100644 index fc6b1f60..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSource.java +++ /dev/null @@ -1,106 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.PageKeyedDataSource; - -import java.util.ArrayList; - -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -public class UserListingDataSource extends PageKeyedDataSource { - - private Retrofit retrofit; - private String query; - private SortType sortType; - private boolean nsfw; - - private MutableLiveData paginationNetworkStateLiveData; - private MutableLiveData initialLoadStateLiveData; - private MutableLiveData hasUserLiveData; - - private PageKeyedDataSource.LoadParams params; - private PageKeyedDataSource.LoadCallback callback; - - UserListingDataSource(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { - this.retrofit = retrofit; - this.query = query; - this.sortType = sortType; - this.nsfw = nsfw; - paginationNetworkStateLiveData = new MutableLiveData<>(); - initialLoadStateLiveData = new MutableLiveData<>(); - hasUserLiveData = new MutableLiveData<>(); - } - - MutableLiveData getPaginationNetworkStateLiveData() { - return paginationNetworkStateLiveData; - } - - MutableLiveData getInitialLoadStateLiveData() { - return initialLoadStateLiveData; - } - - MutableLiveData hasUserLiveData() { - return hasUserLiveData; - } - - @Override - public void loadInitial(@NonNull PageKeyedDataSource.LoadInitialParams params, @NonNull PageKeyedDataSource.LoadInitialCallback callback) { - initialLoadStateLiveData.postValue(NetworkState.LOADING); - - FetchUserData.fetchUserListingData(retrofit, query, null, sortType.getType().value, nsfw, - new FetchUserData.FetchUserListingDataListener() { - @Override - public void onFetchUserListingDataSuccess(ArrayList UserData, String after) { - if (UserData.size() == 0) { - hasUserLiveData.postValue(false); - } else { - hasUserLiveData.postValue(true); - } - - callback.onResult(UserData, null, after); - initialLoadStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onFetchUserListingDataFailed() { - initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving ml.docilealligator.infinityforreddit.User list")); - } - }); - } - - @Override - public void loadBefore(@NonNull PageKeyedDataSource.LoadParams params, @NonNull PageKeyedDataSource.LoadCallback callback) { - - } - - @Override - public void loadAfter(@NonNull PageKeyedDataSource.LoadParams params, @NonNull PageKeyedDataSource.LoadCallback callback) { - this.params = params; - this.callback = callback; - - if (params.key.equals("null") || params.key.equals("")) { - return; - } - - FetchUserData.fetchUserListingData(retrofit, query, params.key, sortType.getType().value, nsfw, - new FetchUserData.FetchUserListingDataListener() { - @Override - public void onFetchUserListingDataSuccess(ArrayList UserData, String after) { - callback.onResult(UserData, after); - paginationNetworkStateLiveData.postValue(NetworkState.LOADED); - } - - @Override - public void onFetchUserListingDataFailed() { - paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving ml.docilealligator.infinityforreddit.User list")); - } - }); - } - - void retryLoadingMore() { - loadAfter(params, callback); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSourceFactory.java deleted file mode 100644 index ee0a49c0..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingDataSourceFactory.java +++ /dev/null @@ -1,46 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import androidx.annotation.NonNull; -import androidx.lifecycle.MutableLiveData; -import androidx.paging.DataSource; - -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -public class UserListingDataSourceFactory extends DataSource.Factory { - private Retrofit retrofit; - private String query; - private SortType sortType; - private boolean nsfw; - - private UserListingDataSource userListingDataSource; - private MutableLiveData userListingDataSourceMutableLiveData; - - UserListingDataSourceFactory(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { - this.retrofit = retrofit; - this.query = query; - this.sortType = sortType; - this.nsfw = nsfw; - userListingDataSourceMutableLiveData = new MutableLiveData<>(); - } - - @NonNull - @Override - public DataSource create() { - userListingDataSource = new UserListingDataSource(retrofit, query, sortType, nsfw); - userListingDataSourceMutableLiveData.postValue(userListingDataSource); - return userListingDataSource; - } - - public MutableLiveData getUserListingDataSourceMutableLiveData() { - return userListingDataSourceMutableLiveData; - } - - UserListingDataSource getUserListingDataSource() { - return userListingDataSource; - } - - void changeSortType(SortType sortType) { - this.sortType = sortType; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingViewModel.java deleted file mode 100644 index f2816f3c..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserListingViewModel.java +++ /dev/null @@ -1,96 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import androidx.annotation.NonNull; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.lifecycle.Transformations; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; -import androidx.paging.LivePagedListBuilder; -import androidx.paging.PagedList; - -import ml.docilealligator.infinityforreddit.NetworkState; -import ml.docilealligator.infinityforreddit.SortType; -import retrofit2.Retrofit; - -public class UserListingViewModel extends ViewModel { - private UserListingDataSourceFactory userListingDataSourceFactory; - private LiveData paginationNetworkState; - private LiveData initialLoadingState; - private LiveData hasUserLiveData; - private LiveData> users; - private MutableLiveData sortTypeLiveData; - - public UserListingViewModel(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { - userListingDataSourceFactory = new UserListingDataSourceFactory(retrofit, query, sortType, nsfw); - - initialLoadingState = Transformations.switchMap(userListingDataSourceFactory.getUserListingDataSourceMutableLiveData(), - UserListingDataSource::getInitialLoadStateLiveData); - paginationNetworkState = Transformations.switchMap(userListingDataSourceFactory.getUserListingDataSourceMutableLiveData(), - UserListingDataSource::getPaginationNetworkStateLiveData); - hasUserLiveData = Transformations.switchMap(userListingDataSourceFactory.getUserListingDataSourceMutableLiveData(), - UserListingDataSource::hasUserLiveData); - - sortTypeLiveData = new MutableLiveData<>(); - sortTypeLiveData.postValue(sortType); - - PagedList.Config pagedListConfig = - (new PagedList.Config.Builder()) - .setEnablePlaceholders(false) - .setPageSize(25) - .build(); - - users = Transformations.switchMap(sortTypeLiveData, sort -> { - userListingDataSourceFactory.changeSortType(sortTypeLiveData.getValue()); - return (new LivePagedListBuilder(userListingDataSourceFactory, pagedListConfig)).build(); - }); - } - - public LiveData> getUsers() { - return users; - } - - public LiveData getPaginationNetworkState() { - return paginationNetworkState; - } - - public LiveData getInitialLoadingState() { - return initialLoadingState; - } - - public LiveData hasUser() { - return hasUserLiveData; - } - - public void refresh() { - userListingDataSourceFactory.getUserListingDataSource().invalidate(); - } - - public void retryLoadingMore() { - userListingDataSourceFactory.getUserListingDataSource().retryLoadingMore(); - } - - public void changeSortType(SortType sortType) { - sortTypeLiveData.postValue(sortType); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - private Retrofit retrofit; - private String query; - private SortType sortType; - private boolean nsfw; - - public Factory(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { - this.retrofit = retrofit; - this.query = query; - this.sortType = sortType; - this.nsfw = nsfw; - } - - @NonNull - @Override - public T create(@NonNull Class modelClass) { - return (T) new UserListingViewModel(retrofit, query, sortType, nsfw); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserRepository.java deleted file mode 100644 index af0b5bb4..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserRepository.java +++ /dev/null @@ -1,40 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import android.os.AsyncTask; - -import androidx.lifecycle.LiveData; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class UserRepository { - private UserDao mUserDao; - private LiveData mUserLiveData; - - UserRepository(RedditDataRoomDatabase redditDataRoomDatabase, String userName) { - mUserDao = redditDataRoomDatabase.userDao(); - mUserLiveData = mUserDao.getUserLiveData(userName); - } - - LiveData getUserLiveData() { - return mUserLiveData; - } - - public void insert(UserData userData) { - new InsertAsyncTask(mUserDao).execute(userData); - } - - private static class InsertAsyncTask extends AsyncTask { - - private UserDao mAsyncTaskDao; - - InsertAsyncTask(UserDao dao) { - mAsyncTaskDao = dao; - } - - @Override - protected Void doInBackground(final UserData... params) { - mAsyncTaskDao.insert(params[0]); - return null; - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserViewModel.java deleted file mode 100644 index 93f185ae..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/User/UserViewModel.java +++ /dev/null @@ -1,50 +0,0 @@ -package ml.docilealligator.infinityforreddit.User; - -import android.app.Application; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.ViewModel; -import androidx.lifecycle.ViewModelProvider; - -import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; - -public class UserViewModel extends AndroidViewModel { - private UserRepository mSubredditRepository; - private LiveData mUserLiveData; - - public UserViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String id) { - super(application); - mSubredditRepository = new UserRepository(redditDataRoomDatabase, id); - mUserLiveData = mSubredditRepository.getUserLiveData(); - } - - public LiveData getUserLiveData() { - return mUserLiveData; - } - - public void insert(UserData userData) { - mSubredditRepository.insert(userData); - } - - public static class Factory extends ViewModelProvider.NewInstanceFactory { - - @NonNull - private final Application mApplication; - private final RedditDataRoomDatabase mRedditDataRoomDatabase; - private final String mUsername; - - public Factory(@NonNull Application application, RedditDataRoomDatabase redditDataRoomDatabase, String username) { - mApplication = application; - mRedditDataRoomDatabase = redditDataRoomDatabase; - mUsername = username; - } - - @Override - public T create(Class modelClass) { - //noinspection unchecked - return (T) new UserViewModel(mApplication, mRedditDataRoomDatabase, mUsername); - } - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/APIUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/APIUtils.java deleted file mode 100644 index a8be1ebd..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/APIUtils.java +++ /dev/null @@ -1,123 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -import android.util.Base64; - -import java.util.HashMap; -import java.util.Map; - -import okhttp3.MediaType; -import okhttp3.RequestBody; - -/** - * Created by alex on 2/23/18. - */ - -public class APIUtils { - public static final String OAUTH_URL = "https://www.reddit.com/api/v1/authorize.compact"; - public static final String OAUTH_API_BASE_URI = "https://oauth.reddit.com"; - public static final String API_BASE_URI = "https://www.reddit.com"; - public static final String API_UPLOAD_MEDIA_URI = "https://reddit-uploaded-media.s3-accelerate.amazonaws.com"; - public static final String API_UPLOAD_VIDEO_URI = "https://reddit-uploaded-video.s3-accelerate.amazonaws.com"; - public static final String GFYCAT_API_BASE_URI = "https://api.gfycat.com/v1/gfycats/"; - public static final String REDGIFS_API_BASE_URI = "https://api.redgifs.com/v1/gfycats/"; - public static final String IMGUR_API_BASE_URI = "https://api.imgur.com/3/"; - public static final String PUSHSHIFT_API_BASE_URI = "https://api.pushshift.io/"; - - public static final String CLIENT_ID_KEY = "client_id"; - public static final String CLIENT_ID = "NOe2iKrPPzwscA"; - public static final String IMGUR_CLIENT_ID = "Client-ID cc671794e0ab397"; - public static final String RESPONSE_TYPE_KEY = "response_type"; - public static final String RESPONSE_TYPE = "code"; - public static final String STATE_KEY = "state"; - public static final String STATE = "23ro8xlxvzp4asqd"; - public static final String REDIRECT_URI_KEY = "redirect_uri"; - public static final String REDIRECT_URI = "infinity://localhost"; - public static final String DURATION_KEY = "duration"; - public static final String DURATION = "permanent"; - public static final String SCOPE_KEY = "scope"; - public static final String SCOPE = "identity edit flair history modconfig modflair modlog modposts modwiki mysubreddits privatemessages read report save submit subscribe vote wikiedit wikiread creddits modcontributors modmail modothers livemanage account modself"; - public static final String ACCESS_TOKEN_KEY = "access_token"; - - public static final String AUTHORIZATION_KEY = "Authorization"; - public static final String AUTHORIZATION_BASE = "bearer "; - public static final String USER_AGENT_KEY = "User-Agent"; - public static final String USER_AGENT = "android:ml.docilealligator.infinityforreddit:v4.1.0-beta5 (by /u/Hostilenemy)"; - - public static final String GRANT_TYPE_KEY = "grant_type"; - public static final String GRANT_TYPE_REFRESH_TOKEN = "refresh_token"; - public static final String REFRESH_TOKEN_KEY = "refresh_token"; - - public static final String DIR_KEY = "dir"; - public static final String ID_KEY = "id"; - public static final String RANK_KEY = "rank"; - public static final String DIR_UPVOTE = "1"; - public static final String DIR_UNVOTE = "0"; - public static final String DIR_DOWNVOTE = "-1"; - public static final String RANK = "10"; - - public static final String ACTION_KEY = "action"; - public static final String SR_NAME_KEY = "sr_name"; - - public static final String API_TYPE_KEY = "api_type"; - public static final String API_TYPE_JSON = "json"; - public static final String RETURN_RTJSON_KEY = "return_rtjson"; - public static final String TEXT_KEY = "text"; - public static final String URL_KEY = "url"; - public static final String VIDEO_POSTER_URL_KEY = "video_poster_url"; - public static final String THING_ID_KEY = "thing_id"; - - public static final String SR_KEY = "sr"; - public static final String TITLE_KEY = "title"; - public static final String FLAIR_TEXT_KEY = "flair_text"; - public static final String SPOILER_KEY = "spoiler"; - public static final String NSFW_KEY = "nsfw"; - public static final String CROSSPOST_FULLNAME_KEY = "crosspost_fullname"; - public static final String KIND_KEY = "kind"; - public static final String KIND_SELF = "self"; - public static final String KIND_LINK = "link"; - public static final String KIND_IMAGE = "image"; - public static final String KIND_VIDEO = "video"; - public static final String KIND_VIDEOGIF = "videogif"; - public static final String KIND_CROSSPOST = "crosspost"; - - public static final String FILEPATH_KEY = "filepath"; - public static final String MIMETYPE_KEY = "mimetype"; - - public static final String LINK_KEY = "link"; - public static final String FLAIR_TEMPLATE_ID_KEY = "flair_template_id"; - public static final String FLAIR_ID_KEY = "flair_id"; - - public static final String MAKE_FAVORITE_KEY = "make_favorite"; - - public static final String MULTIPATH_KEY = "multipath"; - public static final String MODEL_KEY = "model"; - - public static final String REASON_KEY = "reason"; - - public static final String SUBJECT_KEY = "subject"; - public static final String TO_KEY = "to"; - - public static final String NAME_KEY = "name"; - - public static final String GILD_TYPE = "gild_type"; - public static final String IS_ANONYMOUS = "is_anonymous"; - - public static Map getHttpBasicAuthHeader() { - Map params = new HashMap<>(); - String credentials = String.format("%s:%s", APIUtils.CLIENT_ID, ""); - String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); - params.put(APIUtils.AUTHORIZATION_KEY, auth); - return params; - } - - public static Map getOAuthHeader(String accessToken) { - Map params = new HashMap<>(); - params.put(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + accessToken); - params.put(APIUtils.USER_AGENT_KEY, APIUtils.USER_AGENT); - return params; - } - - public static RequestBody getRequestBody(String s) { - return RequestBody.create(MediaType.parse("text/plain"), s); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/CustomThemeSharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/CustomThemeSharedPreferencesUtils.java deleted file mode 100644 index 98998ab5..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/CustomThemeSharedPreferencesUtils.java +++ /dev/null @@ -1,173 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -import android.content.SharedPreferences; - -import ml.docilealligator.infinityforreddit.CustomTheme.CustomTheme; - -public class CustomThemeSharedPreferencesUtils { - public static final int LIGHT = 0; - public static final int DARK = 1; - public static final int AMOLED = 2; - public static final String LIGHT_THEME_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.light_theme"; - public static final String DARK_THEME_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.dark_theme"; - public static final String AMOLED_THEME_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.amoled_theme"; - public static final String LIGHT_STATUS_BAR = "lightStatusBar"; - public static final String LIGHT_NAV_BAR = "lightNavBar"; - public static final String CHANGE_STATUS_BAR_ICON_COLOR_AFTER_TOOLBAR_COLLAPSED_IN_IMMERSIVE_INTERFACE = "changeStatusBarIconColorImmersive"; - public static final String COLOR_PRIMARY = "colorPrimary"; - public static final String COLOR_PRIMARY_DARK = "colorPrimaryDark"; - public static final String COLOR_ACCENT = "colorAccent"; - public static final String COLOR_PRIMARY_LIGHT_THEME = "colorPrimaryLightTheme"; - public static final String POST_TITLE_COLOR = "postTitleColor"; - public static final String POST_CONTENT_COLOR = "postContentColor"; - public static final String COMMENT_COLOR = "commentColor"; - public static final String PRIMARY_TEXT_COLOR = "primaryTextColor"; - public static final String SECONDARY_TEXT_COLOR = "secondaryTextColor"; - public static final String BUTTON_TEXT_COLOR = "buttonTextColor"; - public static final String BACKGROUND_COLOR = "backgroundColor"; - public static final String CARD_VIEW_BACKGROUND_COLOR = "cardViewBackgroundColor"; - 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"; - public static final String BOTTOM_APP_BAR_ICON_COLOR = "bottomAppBarIconColor"; - public static final String POST_ICON_AND_INFO_COLOR = "postIconAndInfoColor"; - public static final String COMMENT_ICON_AND_INFO_COLOR = "commentIconAndInfoColor"; - public static final String TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR = "toolbarPrimaryTextAndIconColor"; - public static final String TOOLBAR_SECONDARY_TEXT_COLOR = "toolbarSecondaryTextColor"; - public static final String CIRCULAR_PROGRESS_BAR_BACKGROUND = "circularProgressBarBackground"; - public static final String TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND = "tabLayoutWithExpandedCollapsingToolbarTabBackground"; - public static final String TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR = "tabLayoutWithExpandedCollapsingToolbarTextColor"; - public static final String TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR = "tabLayoutWithExpandedCollapsingToolbarTabIndicator"; - public static final String TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND = "tabLayoutWithCollapsedCollapsingToolbarTabBackground"; - public static final String TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR = "tabLayoutWithCollapsedCollapsingToolbarTextColor"; - public static final String TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR = "tabLayoutWithCollapsedCollapsingToolbarTabIndicator"; - public static final String NAV_BAR_COLOR = "navBarColor"; - public static final String UPVOTED = "upvoted"; - public static final String DOWNVOTED = "downvoted"; - public static final String POST_TYPE_BACKGROUND_COLOR = "postTypeBackgroundColor"; - public static final String POST_TYPE_TEXT_COLOR = "postTypeTextColor"; - public static final String SPOILER_BACKGROUND_COLOR = "spoilerBackgroundColor"; - public static final String SPOILER_TEXT_COLOR = "spoilerTextColor"; - public static final String NSFW_BACKGROUND_COLOR = "nsfwBackgroundColor"; - public static final String NSFW_TEXT_COLOR = "nsfwTextColor"; - public static final String FLAIR_BACKGROUND_COLOR = "flairBackgroundColor"; - public static final String FLAIR_TEXT_COLOR = "flairTextColor"; - public static final String AWARDS_BACKGROUND_COLOR = "awardsBackgroundColor"; - public static final String AWARDS_TEXT_COLOR = "awardsTextColor"; - public static final String ARCHIVED_ICON_TINT = "archivedIconTint"; - public static final String LOCKED_ICON_TINT = "lockedIconTint"; - public static final String CROSSPOST_ICON_TINT = "crosspostIconTint"; - public static final String STICKIED_POST_ICON_TINT = "stickiedPost"; - public static final String NO_PREVIEW_POST_TYPE_ICON_TINT = "noPreviewPostTypeIconTint"; - public static final String SUBSCRIBED = "subscribed"; - public static final String UNSUBSCRIBED = "unsubscribed"; - public static final String USERNAME = "username"; - public static final String SUBREDDIT = "subreddit"; - public static final String AUTHOR_FLAIR_TEXT_COLOR = "authorFlairTextColor"; - public static final String SUBMITTER = "submitter"; - public static final String MODERATOR = "moderator"; - public static final String SINGLE_COMMENT_THREAD_BACKGROUND_COLOR = "singleCommentThreadBackgroundColor"; - public static final String UNREAD_MESSAGE_BACKGROUND_COLOR = "unreadMessageBackgroundColor"; - public static final String DIVIDER_COLOR = "dividerColor"; - public static final String NO_PREVIEW_POST_TYPE_BACKGROUND_COLOR = "noPreviewLinkBackgroundColor"; - public static final String VOTE_AND_REPLY_UNAVAILABLE_BUTTON_COLOR = "voteAndReplyUnavailableButtonColor"; - public static final String COMMENT_VERTICAL_BAR_COLOR_1 = "commentVerticalBarColor1"; - public static final String COMMENT_VERTICAL_BAR_COLOR_2 = "commentVerticalBarColor2"; - public static final String COMMENT_VERTICAL_BAR_COLOR_3 = "commentVerticalBarColor3"; - public static final String COMMENT_VERTICAL_BAR_COLOR_4 = "commentVerticalBarColor4"; - public static final String COMMENT_VERTICAL_BAR_COLOR_5 = "commentVerticalBarColor5"; - public static final String COMMENT_VERTICAL_BAR_COLOR_6 = "commentVerticalBarColor6"; - public static final String COMMENT_VERTICAL_BAR_COLOR_7 = "commentVerticalBarColor7"; - public static final String FAB_ICON_COLOR = "fabIconColor"; - public static final String CHIP_TEXT_COLOR = "chipTextColor"; - public static final String LINK_COLOR = "linkColor"; - public static final String RECEIVED_MESSAGE_TEXT_COLOR = "receivedMessageTextColor"; - public static final String SENT_MESSAGE_TEXT_COLOR = "sentMessageTextColor"; - public static final String RECEIVED_MESSAGE_BACKROUND_COLOR = "receivedMessageBackgroundColor"; - public static final String SENT_MESSAGE_BACKGROUND_COLOR = "sentMessageBackgroundColor"; - public static final String SEND_MESSAGE_ICON_COLOR = "sentMessageIconColor"; - public static final String FULLY_COLLAPSED_COMMENT_BACKGROUND_COLOR = "fullyCollapsedCommentBackgroundColor"; - public static final String AWARDED_COMMENT_BACKGROUND_COLOR = "awardedCommentBackgroundColor"; - - public static void insertThemeToSharedPreferences(CustomTheme customTheme, SharedPreferences themeSharedPreferences) { - SharedPreferences.Editor editor = themeSharedPreferences.edit(); - editor.putInt(COLOR_PRIMARY, customTheme.colorPrimary); - editor.putInt(COLOR_PRIMARY_DARK, customTheme.colorPrimaryDark); - editor.putInt(COLOR_ACCENT, customTheme.colorAccent); - editor.putInt(COLOR_PRIMARY_LIGHT_THEME, customTheme.colorPrimaryLightTheme); - editor.putInt(PRIMARY_TEXT_COLOR, customTheme.primaryTextColor); - editor.putInt(SECONDARY_TEXT_COLOR, customTheme.secondaryTextColor); - editor.putInt(POST_TITLE_COLOR, customTheme.postTitleColor); - editor.putInt(POST_CONTENT_COLOR, customTheme.postContentColor); - editor.putInt(COMMENT_COLOR, customTheme.commentColor); - editor.putInt(BUTTON_TEXT_COLOR, customTheme.buttonTextColor); - editor.putInt(BACKGROUND_COLOR, customTheme.backgroundColor); - editor.putInt(CARD_VIEW_BACKGROUND_COLOR, customTheme.cardViewBackgroundColor); - editor.putInt(COMMENT_BACKGROUND_COLOR, customTheme.commentBackgroundColor); - editor.putInt(BOTTOM_APP_BAR_BACKGROUND_COLOR, customTheme.bottomAppBarBackgroundColor); - editor.putInt(PRIMARY_ICON_COLOR, customTheme.primaryIconColor); - editor.putInt(BOTTOM_APP_BAR_ICON_COLOR, customTheme.bottomAppBarIconColor); - editor.putInt(POST_ICON_AND_INFO_COLOR, customTheme.postIconAndInfoColor); - editor.putInt(COMMENT_ICON_AND_INFO_COLOR, customTheme.commentIconAndInfoColor); - editor.putInt(TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR, customTheme.toolbarPrimaryTextAndIconColor); - editor.putInt(TOOLBAR_SECONDARY_TEXT_COLOR, customTheme.toolbarSecondaryTextColor); - editor.putInt(CIRCULAR_PROGRESS_BAR_BACKGROUND, customTheme.circularProgressBarBackground); - editor.putInt(TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground); - editor.putInt(TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR, customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor); - editor.putInt(TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR, customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator); - editor.putInt(TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground); - editor.putInt(TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR, customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor); - editor.putInt(TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR, customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator); - editor.putInt(NAV_BAR_COLOR, customTheme.navBarColor); - editor.putInt(UPVOTED, customTheme.upvoted); - editor.putInt(DOWNVOTED, customTheme.downvoted); - editor.putInt(POST_TYPE_BACKGROUND_COLOR, customTheme.postTypeBackgroundColor); - editor.putInt(POST_TYPE_TEXT_COLOR, customTheme.postTypeTextColor); - editor.putInt(SPOILER_BACKGROUND_COLOR, customTheme.spoilerBackgroundColor); - editor.putInt(SPOILER_TEXT_COLOR, customTheme.spoilerTextColor); - editor.putInt(NSFW_BACKGROUND_COLOR, customTheme.nsfwBackgroundColor); - editor.putInt(NSFW_TEXT_COLOR, customTheme.nsfwTextColor); - editor.putInt(FLAIR_BACKGROUND_COLOR, customTheme.flairBackgroundColor); - editor.putInt(FLAIR_TEXT_COLOR, customTheme.flairTextColor); - editor.putInt(AWARDS_BACKGROUND_COLOR, customTheme.awardsBackgroundColor); - editor.putInt(AWARDS_TEXT_COLOR, customTheme.awardsTextColor); - editor.putInt(ARCHIVED_ICON_TINT, customTheme.archivedTint); - editor.putInt(LOCKED_ICON_TINT, customTheme.lockedIconTint); - editor.putInt(CROSSPOST_ICON_TINT, customTheme.crosspostIconTint); - editor.putInt(STICKIED_POST_ICON_TINT, customTheme.stickiedPostIconTint); - editor.putInt(NO_PREVIEW_POST_TYPE_ICON_TINT, customTheme.noPreviewPostTypeIconTint); - editor.putInt(SUBSCRIBED, customTheme.subscribed); - editor.putInt(UNSUBSCRIBED, customTheme.unsubscribed); - editor.putInt(USERNAME, customTheme.username); - editor.putInt(SUBREDDIT, customTheme.subreddit); - editor.putInt(AUTHOR_FLAIR_TEXT_COLOR, customTheme.authorFlairTextColor); - editor.putInt(SUBMITTER, customTheme.submitter); - editor.putInt(MODERATOR, customTheme.moderator); - editor.putInt(SINGLE_COMMENT_THREAD_BACKGROUND_COLOR, customTheme.singleCommentThreadBackgroundColor); - editor.putInt(UNREAD_MESSAGE_BACKGROUND_COLOR, customTheme.unreadMessageBackgroundColor); - editor.putInt(DIVIDER_COLOR, customTheme.dividerColor); - editor.putInt(NO_PREVIEW_POST_TYPE_BACKGROUND_COLOR, customTheme.noPreviewPostTypeBackgroundColor); - editor.putInt(VOTE_AND_REPLY_UNAVAILABLE_BUTTON_COLOR, customTheme.voteAndReplyUnavailableButtonColor); - editor.putInt(COMMENT_VERTICAL_BAR_COLOR_1, customTheme.commentVerticalBarColor1); - editor.putInt(COMMENT_VERTICAL_BAR_COLOR_2, customTheme.commentVerticalBarColor2); - editor.putInt(COMMENT_VERTICAL_BAR_COLOR_3, customTheme.commentVerticalBarColor3); - editor.putInt(COMMENT_VERTICAL_BAR_COLOR_4, customTheme.commentVerticalBarColor4); - editor.putInt(COMMENT_VERTICAL_BAR_COLOR_5, customTheme.commentVerticalBarColor5); - editor.putInt(COMMENT_VERTICAL_BAR_COLOR_6, customTheme.commentVerticalBarColor6); - editor.putInt(COMMENT_VERTICAL_BAR_COLOR_7, customTheme.commentVerticalBarColor7); - editor.putInt(FAB_ICON_COLOR, customTheme.fabIconColor); - editor.putInt(CHIP_TEXT_COLOR, customTheme.chipTextColor); - editor.putInt(LINK_COLOR, customTheme.linkColor); - editor.putInt(RECEIVED_MESSAGE_TEXT_COLOR, customTheme.receivedMessageTextColor); - editor.putInt(SENT_MESSAGE_TEXT_COLOR, customTheme.sentMessageTextColor); - editor.putInt(RECEIVED_MESSAGE_BACKROUND_COLOR, customTheme.receivedMessageBackgroundColor); - editor.putInt(SENT_MESSAGE_BACKGROUND_COLOR, customTheme.sentMessageBackgroundColor); - editor.putInt(SEND_MESSAGE_ICON_COLOR, customTheme.sendMessageIconColor); - editor.putInt(FULLY_COLLAPSED_COMMENT_BACKGROUND_COLOR, customTheme.fullyCollapsedCommentBackgroundColor); - editor.putInt(AWARDED_COMMENT_BACKGROUND_COLOR, customTheme.awardedCommentBackgroundColor); - editor.putBoolean(LIGHT_STATUS_BAR, customTheme.isLightStatusBar); - editor.putBoolean(LIGHT_NAV_BAR, customTheme.isLightNavBar); - editor.putBoolean(CHANGE_STATUS_BAR_ICON_COLOR_AFTER_TOOLBAR_COLLAPSED_IN_IMMERSIVE_INTERFACE, customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface); - editor.apply(); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GetPathUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GetPathUtils.java deleted file mode 100644 index 1ccb6b47..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GetPathUtils.java +++ /dev/null @@ -1,238 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -import android.annotation.TargetApi; -import android.content.ContentUris; -import android.content.Context; -import android.database.Cursor; -import android.net.Uri; -import android.os.Build; -import android.os.Environment; -import android.provider.DocumentsContract; -import android.provider.MediaStore; - -import androidx.core.content.ContextCompat; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -public class GetPathUtils { - - private static final String PATH_TREE = "tree"; - private static final String PRIMARY_TYPE = "primary"; - private static final String RAW_TYPE = "raw"; - - @TargetApi(Build.VERSION_CODES.KITKAT) - public static String getFilePathFromUri(final Context context, final Uri uri) { - - // DocumentProvider - if (DocumentsContract.isDocumentUri(context, uri)) { - // ExternalStorageProvider - if (isExternalStorageDocument(uri)) { - final String docId = DocumentsContract.getDocumentId(uri); - //Timber.d("docId -> %s", docId); - final String[] split = docId.split(":"); - final String type = split[0]; - - if (PRIMARY_TYPE.equalsIgnoreCase(type)) { - return Environment.getExternalStorageDirectory() + "/" + split[1]; - } else { - // TODO handle non-primary volumes - StringBuilder path = new StringBuilder(); - String pathSegment[] = docId.split(":"); - return path.append(getRemovableStorageRootPath(context, pathSegment[0])).append(File.separator).append(pathSegment[1]).toString(); - } - } else if (isDownloadsDocument(uri)) { // DownloadsProvider - - final String id = DocumentsContract.getDocumentId(uri); - - if (id.contains("raw:")) { - return id.substring(id.indexOf(File.separator)); - } else { - Uri contentUri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); - - return getDataColumn(context, contentUri, null, null); - } - - } else if (isMediaDocument(uri)) { // MediaProvider - final String docId = DocumentsContract.getDocumentId(uri); - final String[] split = docId.split(":"); - final String type = split[0]; - - Uri contentUri = null; - if ("image".equals(type)) { - contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; - } else if ("video".equals(type)) { - contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; - } else if ("audio".equals(type)) { - contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; - } - - final String selection = "_id=?"; - final String[] selectionArgs = new String[]{ - split[1] - }; - - return getDataColumn(context, contentUri, selection, selectionArgs); - } - } else if ("content".equalsIgnoreCase(uri.getScheme())) { // MediaStore (and general) - return getDataColumn(context, uri, null, null); - } else if ("file".equalsIgnoreCase(uri.getScheme())) { // File - return uri.getPath(); - } - - return null; - } - - /** - * Get the value of the data column for this Uri. This is useful for - * MediaStore Uris, and other file-based ContentProviders. - * - * @param context The context. - * @param uri The Uri to query. - * @param selection (Optional) Filter used in the query. - * @param selectionArgs (Optional) Selection arguments used in the query. - * @return The value of the _data column, which is typically a file path. - */ - public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { - - Cursor cursor = null; - final String column = MediaStore.MediaColumns.DATA; - final String[] projection = {column}; - try { - cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, - null); - if (cursor != null && cursor.moveToFirst()) { - final int column_index = cursor.getColumnIndexOrThrow(column); - return cursor.getString(column_index); - } - } finally { - if (cursor != null) - cursor.close(); - } - - return null; - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is ExternalStorageProvider. - */ - public static boolean isExternalStorageDocument(Uri uri) { - return "com.android.externalstorage.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is DownloadsProvider. - */ - public static boolean isDownloadsDocument(Uri uri) { - return "com.android.providers.downloads.documents".equals(uri.getAuthority()); - } - - /** - * @param uri The Uri to check. - * @return Whether the Uri authority is MediaProvider. - */ - public static boolean isMediaDocument(Uri uri) { - return "com.android.providers.media.documents".equals(uri.getAuthority()); - } - - /** - * @param uri - * @return file path of Uri - */ - public static String getDirectoryPathFromUri(Context context, Uri uri) { - - if ("file".equals(uri.getScheme())) { - return uri.getPath(); - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT - && isTreeUri(uri)) { - - String treeId = getTreeDocumentId(uri); - - if (treeId != null) { - String[] paths = treeId.split(":"); - String type = paths[0]; - String subPath = paths.length == 2 ? paths[1] : ""; - - if (RAW_TYPE.equalsIgnoreCase(type)) { - return treeId.substring(treeId.indexOf(File.separator)); - } else if (PRIMARY_TYPE.equalsIgnoreCase(type)) { - return Environment.getExternalStorageDirectory() + File.separator + subPath; - } else { - StringBuilder path = new StringBuilder(); - String[] pathSegment = treeId.split(":"); - if (pathSegment.length == 1) { - path.append(getRemovableStorageRootPath(context, paths[0])); - } else { - String rootPath = getRemovableStorageRootPath(context, paths[0]); - path.append(rootPath).append(File.separator).append(pathSegment[1]); - } - - return path.toString(); - } - } - } - return null; - } - - private static String getRemovableStorageRootPath(Context context, String storageId) { - StringBuilder rootPath = new StringBuilder(); - File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null); - for (File fileDir : externalFilesDirs) { - if (fileDir.getPath().contains(storageId)) { - String[] pathSegment = fileDir.getPath().split(File.separator); - for (String segment : pathSegment) { - if (segment.equals(storageId)) { - rootPath.append(storageId); - break; - } - rootPath.append(segment).append(File.separator); - } - //rootPath.append(fileDir.getPath().split("/Android")[0]); // faster - break; - } - } - return rootPath.toString(); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - public static List getListRemovableStorage(Context context) { - - List paths = new ArrayList<>(); - - File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null); - for (File fileDir : externalFilesDirs) { - if (Environment.isExternalStorageRemovable(fileDir)) { - String path = fileDir.getPath(); - if (path.contains("/Android")) { - paths.add(path.substring(0, path.indexOf("/Android"))); - } - } - } - - return paths; - } - - //https://github.com/rcketscientist/DocumentActivity/blob/master/library/src/main/java/com/anthonymandra/framework/DocumentUtil.java#L56 - /** - * Extract the via {@link DocumentsContract.Document#COLUMN_DOCUMENT_ID} from the given URI. - * From {@link DocumentsContract} but return null instead of throw - */ - public static String getTreeDocumentId(Uri uri) { - final List paths = uri.getPathSegments(); - if (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))) { - return paths.get(1); - } - return null; - } - - public static boolean isTreeUri(Uri uri) { - final List paths = uri.getPathSegments(); - return (paths.size() == 2 && PATH_TREE.equals(paths.get(0))); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GlideImageGetter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GlideImageGetter.java deleted file mode 100644 index 00f940a0..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/GlideImageGetter.java +++ /dev/null @@ -1,173 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -import android.app.Activity; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.text.Html; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.bumptech.glide.Glide; -import com.bumptech.glide.request.Request; -import com.bumptech.glide.request.target.SizeReadyCallback; -import com.bumptech.glide.request.target.Target; -import com.bumptech.glide.request.transition.Transition; - -import java.lang.ref.WeakReference; - -public class GlideImageGetter implements Html.ImageGetter { - - private WeakReference container; - private boolean matchParentWidth; - private boolean enlargeImage; - private HtmlImagesHandler imagesHandler; - private float density = 1.0f; - private float textSize; - - public GlideImageGetter(TextView textView, boolean enlargeImage) { - this(textView, false, false, null); - this.enlargeImage = enlargeImage; - } - - public GlideImageGetter(TextView textView, boolean matchParentWidth, HtmlImagesHandler imagesHandler) { - this(textView, matchParentWidth, false, imagesHandler); - } - - public GlideImageGetter(TextView textView, boolean matchParentWidth, boolean densityAware, - @Nullable HtmlImagesHandler imagesHandler) { - this.container = new WeakReference<>(textView); - this.matchParentWidth = matchParentWidth; - this.imagesHandler = imagesHandler; - if (densityAware) { - density = container.get().getResources().getDisplayMetrics().density; - } - textSize = container.get().getTextSize(); - } - - @Override - public Drawable getDrawable(String source) { - if (imagesHandler != null) { - imagesHandler.addImage(source); - } - - BitmapDrawablePlaceholder drawable = new BitmapDrawablePlaceholder(textSize); - - Context context = container.get().getContext(); - if (!(context instanceof Activity && (((Activity) context).isFinishing() || ((Activity) context).isDestroyed()))) { - container.get().post(() -> Glide.with(context) - .asBitmap() - .load(source) - .into(drawable)); - } - - return drawable; - } - - private class BitmapDrawablePlaceholder extends BitmapDrawable implements Target { - - protected Drawable drawable; - - BitmapDrawablePlaceholder(float textSize) { - super(container.get().getResources(), - Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)); - } - - @Override - public void draw(final Canvas canvas) { - if (drawable != null) { - drawable.draw(canvas); - } - } - - private void setDrawable(Drawable drawable) { - this.drawable = drawable; - int drawableWidth = (int) (drawable.getIntrinsicWidth() * density); - int drawableHeight = (int) (drawable.getIntrinsicHeight() * density); - float ratio = (float) drawableWidth / (float) drawableHeight; - drawableHeight = enlargeImage ? (int) (textSize * 1.5) : (int) textSize; - drawableWidth = (int) (drawableHeight * ratio); - int maxWidth = container.get().getMeasuredWidth(); - if ((maxWidth > 0 && (drawableWidth > maxWidth)) || matchParentWidth) { - int calculatedHeight = maxWidth * drawableHeight / drawableWidth; - drawable.setBounds(0, 0, maxWidth, calculatedHeight); - setBounds(0, 0, maxWidth, calculatedHeight); - } else { - drawable.setBounds(0, 0, drawableWidth, drawableHeight); - setBounds(0, 0, drawableWidth, drawableHeight); - } - - container.get().setText(container.get().getText()); - } - - @Override - public void onLoadStarted(@Nullable Drawable placeholderDrawable) { - if(placeholderDrawable != null) { - setDrawable(placeholderDrawable); - } - } - - @Override - public void onLoadFailed(@Nullable Drawable errorDrawable) { - if (errorDrawable != null) { - setDrawable(errorDrawable); - } - } - - @Override - public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition transition) { - if (container != null) { - TextView textView = container.get(); - if (textView != null) { - Resources resources = textView.getResources(); - if (resources != null) { - setDrawable(new BitmapDrawable(resources, bitmap)); - } - } - } - } - - @Override - public void onLoadCleared(@Nullable Drawable placeholderDrawable) { - if(placeholderDrawable != null) { - setDrawable(placeholderDrawable); - } - } - - @Override - public void getSize(@NonNull SizeReadyCallback cb) { - cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL); - } - - @Override - public void removeCallback(@NonNull SizeReadyCallback cb) {} - - @Override - public void setRequest(@Nullable Request request) {} - - @Nullable - @Override - public Request getRequest() { - return null; - } - - @Override - public void onStart() {} - - @Override - public void onStop() {} - - @Override - public void onDestroy() {} - - } - - public interface HtmlImagesHandler { - void addImage(String uri); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java deleted file mode 100644 index 2b1ff97b..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java +++ /dev/null @@ -1,133 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -/** - * Created by alex on 2/25/18. - */ - -public class JSONUtils { - public static final String KIND_KEY = "kind"; - public static final String DATA_KEY = "data"; - public static final String AFTER_KEY = "after"; - public static final String CHILDREN_KEY = "children"; - public static final String COUNT_KEY = "count"; - public static final String TITLE_KEY = "title"; - public static final String NAME_KEY = "name"; - public static final String SUBREDDIT_NAME_PREFIX_KEY = "subreddit_name_prefixed"; - public static final String SELFTEXT_KEY = "selftext"; - public static final String SELFTEXT_HTML_KEY = "selftext_html"; - public static final String AUTHOR_KEY = "author"; - public static final String AUTHOR_FLAIR_RICHTEXT_KEY = "author_flair_richtext"; - public static final String AUTHOR_FLAIR_TEXT_KEY = "author_flair_text"; - public static final String E_KEY = "e"; - public static final String T_KEY = "t"; - public static final String U_KEY = "u"; - public static final String LINK_KEY = "link"; - public static final String LINK_AUTHOR_KEY = "link_author"; - public static final String LINK_FLAIR_TEXT_KEY = "link_flair_text"; - public static final String LINK_FLAIR_RICHTEXT_KEY = "link_flair_richtext"; - public static final String SCORE_KEY = "score"; - public static final String LIKES_KEY = "likes"; - public static final String NSFW_KEY = "over_18"; - public static final String PERMALINK_KEY = "permalink"; - public static final String CREATED_UTC_KEY = "created_utc"; - public static final String PREVIEW_KEY = "preview"; - public static final String IMAGES_KEY = "images"; - public static final String WIDTH_KEY = "width"; - public static final String HEIGHT_KEY = "height"; - public static final String SOURCE_KEY = "source"; - public static final String URL_KEY = "url"; - public static final String MEDIA_KEY = "media"; - public static final String REDDIT_VIDEO_KEY = "reddit_video"; - public static final String HLS_URL_KEY = "hls_url"; - public static final String FALLBACK_URL_KEY = "fallback_url"; - public static final String IS_VIDEO_KEY = "is_video"; - public static final String CROSSPOST_PARENT_LIST = "crosspost_parent_list"; - public static final String REDDIT_VIDEO_PREVIEW_KEY = "reddit_video_preview"; - public static final String STICKIED_KEY = "stickied"; - public static final String BODY_KEY = "body"; - public static final String BODY_HTML_KEY = "body_html"; - public static final String COLLAPSED_KEY = "collapsed"; - public static final String IS_SUBMITTER_KEY = "is_submitter"; - public static final String REPLIES_KEY = "replies"; - public static final String DEPTH_KEY = "depth"; - public static final String ID_KEY = "id"; - public static final String SCORE_HIDDEN_KEY = "score_hidden"; - public static final String SUBREDDIT_KEY = "subreddit"; - public static final String BANNER_IMG_KEY = "banner_img"; - public static final String BANNER_BACKGROUND_IMAGE_KEY = "banner_background_image"; - public static final String ICON_IMG_KEY = "icon_img"; - public static final String ICON_URL_KEY = "icon_url"; - public static final String COMMUNITY_ICON_KEY = "community_icon"; - public static final String LINK_KARMA_KEY = "link_karma"; - public static final String COMMENT_KARMA_KEY = "comment_karma"; - public static final String DISPLAY_NAME_KEY = "display_name"; - public static final String SUBREDDIT_TYPE_KEY = "subreddit_type"; - public static final String SUBREDDIT_TYPE_VALUE_USER = "user"; - public static final String SUBSCRIBERS_KEY = "subscribers"; - public static final String PUBLIC_DESCRIPTION_KEY = "public_description"; - public static final String ACTIVE_USER_COUNT_KEY = "active_user_count"; - public static final String IS_GOLD_KEY = "is_gold"; - public static final String IS_FRIEND_KEY = "is_friend"; - public static final String JSON_KEY = "json"; - public static final String PARENT_ID_KEY = "parent_id"; - public static final String LINK_ID_KEY = "link_id"; - public static final String LINK_TITLE_KEY = "link_title"; - public static final String ERRORS_KEY = "errors"; - public static final String ARGS_KEY = "args"; - public static final String FIELDS_KEY = "fields"; - public static final String VALUE_KEY = "value"; - public static final String TEXT_KEY = "text"; - public static final String SPOILER_KEY = "spoiler"; - public static final String RULES_KEY = "rules"; - public static final String SHORT_NAME_KEY = "short_name"; - public static final String DESCRIPTION_KEY = "description"; - public static final String DESCRIPTION_HTML_KEY = "description_html"; - public static final String DESCRIPTION_MD_KEY = "description_md"; - public static final String ARCHIVED_KEY = "archived"; - public static final String LOCKEC_KEY = "locked"; - public static final String SAVED_KEY = "saved"; - public static final String TEXT_EDITABLE_KEY = "text_editable"; - public static final String SUBJECT_KEY = "subject"; - public static final String CONTEXT_KEY = "context"; - public static final String DISTINGUISHED_KEY = "distinguished"; - public static final String WAS_COMMENT_KEY = "was_comment"; - public static final String NEW_KEY = "new"; - public static final String NUM_COMMENTS_KEY = "num_comments"; - public static final String HIDDEN_KEY = "hidden"; - public static final String USER_HAS_FAVORITED_KEY = "user_has_favorited"; - public static final String RESOLUTIONS_KEY = "resolutions"; - public static final String NUM_SUBSCRIBERS_KEY = "num_subscribers"; - public static final String COPIED_FROM_KEY = "copied_from"; - public static final String VISIBILITY_KEY = "visibility"; - public static final String OVER_18_KEY = "over_18"; - public static final String OWNER_KEY = "owner"; - public static final String IS_SUBSCRIBER_KEY = "is_subscriber"; - public static final String IS_FAVORITED_KEY = "is_favorited"; - public static final String SUBREDDITS_KEY = "subreddits"; - public static final String PATH_KEY = "path"; - public static final String ALL_AWARDINGS_KEY = "all_awardings"; - public static final String RESIZED_ICONS_KEY = "resized_icons"; - public static final String GFY_ITEM_KEY = "gfyItem"; - public static final String MP4_URL_KEY = "mp4Url"; - public static final String WEBM_URL_KEY = "webmUrl"; - public static final String TYPE_KEY = "type"; - public static final String MP4_KEY = "mp4"; - public static final String THINGS_KEY = "things"; - public static final String MEDIA_METADATA_KEY = "media_metadata"; - public static final String GALLERY_DATA_KEY = "gallery_data"; - public static final String ITEMS_KEY = "items"; - public static final String M_KEY = "m"; - public static final String MEDIA_ID_KEY = "media_id"; - public static final String S_KEY = "s"; - public static final String X_KEY = "x"; - public static final String Y_KEY = "y"; - public static final String DEST_KEY = "dest"; - public static final String GIF_KEY = "gif"; - public static final String MAX_EMOJIS_KEY = "max_emojis"; - public static final String RICHTEXT_KEY = "richtext"; - public static final String SUGGESTED_COMMENT_SORT_KEY = "suggested_comment_sort"; - public static final String OVER18_KEY = "over18"; - public static final String TOTAL_KARMA_KEY = "total_karma"; - public static final String AWARDER_KARMA_KEY = "awarder_karma"; - public static final String AWARDEE_KARMA_KEY = "awardee_karma"; -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/NotificationUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/NotificationUtils.java deleted file mode 100644 index 1d5a3f6f..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/NotificationUtils.java +++ /dev/null @@ -1,91 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -import android.app.NotificationChannel; -import android.app.NotificationManager; -import android.content.Context; - -import androidx.core.app.NotificationCompat; -import androidx.core.app.NotificationManagerCompat; - -import ml.docilealligator.infinityforreddit.R; - -public class NotificationUtils { - public static final String CHANNEL_SUBMIT_POST = "Submit Post"; - public static final String CHANNEL_ID_NEW_MESSAGES = "new_messages"; - public static final String CHANNEL_NEW_MESSAGES = "New Messages"; - public static final String CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO = "download_reddit_video"; - public static final String CHANNEL_DOWNLOAD_REDDIT_VIDEO = "Download Reddit Video"; - public static final String CHANNEL_ID_DOWNLOAD_VIDEO = "download_video"; - public static final String CHANNEL_DOWNLOAD_VIDEO = "Download Video"; - public static final String CHANNEL_ID_DOWNLOAD_IMAGE = "download_image"; - public static final String CHANNEL_DOWNLOAD_IMAGE = "Download Image"; - public static final String CHANNEL_ID_DOWNLOAD_GIF = "download_gif"; - public static final String CHANNEL_DOWNLOAD_GIF = "Download Gif"; - public static final int SUBMIT_POST_SERVICE_NOTIFICATION_ID = 10000; - public static final int DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID = 20000; - public static final int DOWNLOAD_VIDEO_NOTIFICATION_ID = 30000; - public static final int DOWNLOAD_IMAGE_NOTIFICATION_ID = 40000; - public static final int DOWNLOAD_GIF_NOTIFICATION_ID = 50000; - public static final int PULL_NOTIFICATION_ALARM_RECEIVER_REQUEST_CODE = 12; - - private static final int SUMMARY_BASE_ID_UNREAD_MESSAGE = 0; - private static final int NOTIFICATION_BASE_ID_UNREAD_MESSAGE = 1; - - private static final String GROUP_USER_BASE = "ml.docilealligator.infinityforreddit."; - - public static NotificationCompat.Builder buildNotification(NotificationManagerCompat notificationManager, - Context context, String title, String content, - String summary, String channelId, String channelName, - String group, int color) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); - notificationManager.createNotificationChannel(channel); - } - - return new NotificationCompat.Builder(context.getApplicationContext(), channelId) - .setContentTitle(title) - .setContentText(content) - .setSmallIcon(R.drawable.ic_notification) - .setColor(color) - .setStyle(new NotificationCompat.BigTextStyle() - .setSummaryText(summary) - .bigText(content)) - .setGroup(group) - .setAutoCancel(true); - } - - public static NotificationCompat.Builder buildSummaryNotification(Context context, NotificationManagerCompat notificationManager, - String title, String content, String channelId, - String channelName, String group, int color) { - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { - NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); - notificationManager.createNotificationChannel(channel); - } - - return new NotificationCompat.Builder(context, channelId) - .setContentTitle(title) - //set content text to support devices running API level < 24 - .setContentText(content) - .setSmallIcon(R.drawable.ic_notification) - .setColor(color) - .setGroup(group) - .setGroupSummary(true) - .setAutoCancel(true); - } - - public static NotificationManagerCompat getNotificationManager(Context context) { - return NotificationManagerCompat.from(context); - } - - public static String getAccountGroupName(String accountName) { - return GROUP_USER_BASE + accountName; - } - - public static int getSummaryIdUnreadMessage(int accountIndex) { - return SUMMARY_BASE_ID_UNREAD_MESSAGE + accountIndex * 1000; - } - - public static int getNotificationIdUnreadMessage(int accountIndex, int messageIndex) { - return NOTIFICATION_BASE_ID_UNREAD_MESSAGE + accountIndex * 1000 + messageIndex; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java deleted file mode 100644 index 6b441e27..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/SharedPreferencesUtils.java +++ /dev/null @@ -1,235 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -/** - * Created by alex on 2/23/18. - */ - -public class SharedPreferencesUtils { - public static final String ENABLE_NOTIFICATION_KEY = "enable_notification"; - public static final String NOTIFICATION_INTERVAL_KEY = "notificaiton_interval"; - public static final String LAZY_MODE_INTERVAL_KEY = "lazy_mode_interval"; - public static final String THEME_KEY = "theme"; - public static final String ICON_FOREGROUND_KEY = "icon_foreground"; - public static final String ICON_BACKGROUND_KEY = "icon_background"; - public static final String ERROR_IMAGE_KEY = "error_image"; - public static final String GILDED_ICON_KEY = "gilded_icon"; - public static final String CROSSPOST_ICON_KEY = "crosspost_icon"; - public static final String THUMBTACK_ICON_KEY = "thumbtack_icon"; - public static final String BEST_ROCKET_ICON_KEY = "best_rocket_icon"; - public static final String MATERIAL_ICONS_KEY = "material_icons"; - public static final String OPEN_SOURCE_KEY = "open_source"; - public static final String RATE_KEY = "rate"; - public static final String F_DROID_KEY = "f-droid"; - public static final String EMAIL_KEY = "email"; - public static final String REDDIT_ACCOUNT_KEY = "reddit_account"; - public static final String SUBREDDIT_KEY = "subreddit"; - public static final String SHARE_KEY = "share"; - public static final String VERSION_KEY = "version"; - public static final String FONT_SIZE_KEY = "font_size"; - public static final String TITLE_FONT_SIZE_KEY = "title_font_size"; - public static final String CONTENT_FONT_SIZE_KEY = "content_font_size"; - public static final String FONT_FAMILY_KEY = "font_family"; - public static final String TITLE_FONT_FAMILY_KEY = "title_font_family"; - public static final String CONTENT_FONT_FAMILY_KEY = "content_font_family"; - public static final String AMOLED_DARK_KEY = "amoled_dark"; - public static final String IMMERSIVE_INTERFACE_ENTRY_KEY = "immersive_interface_entry"; - public static final String IMMERSIVE_INTERFACE_KEY = "immersive_interface"; - public static final String IMMERSIVE_INTERFACE_IGNORE_NAV_BAR_KEY = "immersive_interface_ignore_nav_bar"; - public static final String BOTTOM_APP_BAR_KEY = "bottom_app_bar"; - public static final String VOTE_BUTTONS_ON_THE_RIGHT_KEY = "vote_buttons_on_the_right"; - - public static final String SORT_TYPE_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.sort_type"; - public static final String SORT_TYPE_BEST_POST = "sort_type_best_post"; - public static final String SORT_TIME_BEST_POST = "sort_time_best_post"; - public static final String SORT_TYPE_SEARCH_POST = "sort_type_search_post"; - public static final String SORT_TIME_SEARCH_POST = "sort_time_search_post"; - public static final String SORT_TYPE_SUBREDDIT_POST_BASE = "sort_type_subreddit_post_"; - public static final String SORT_TIME_SUBREDDIT_POST_BASE = "sort_time_subreddit_post_"; - public static final String SORT_TYPE_MULTI_REDDIT_POST_BASE = "sort_type_multi_reddit_post_"; - public static final String SORT_TIME_MULTI_REDDIT_POST_BASE = "sort_time_multi_reddit_post_"; - public static final String SORT_TYPE_USER_POST_BASE = "sort_type_user_post_"; - public static final String SORT_TIME_USER_POST_BASE = "sort_time_user_post_"; - public static final String SORT_TYPE_USER_COMMENT = "sort_type_user_comment"; - public static final String SORT_TIME_USER_COMMENT = "sort_time_user_comment"; - public static final String SORT_TYPE_SEARCH_SUBREDDIT = "sort_type_search_subreddit"; - public static final String SORT_TYPE_SEARCH_USER = "sort_type_search_user"; - public static final String SORT_TYPE_POST_COMMENT = "sort_type_post_comment"; - - public static final String POST_LAYOUT_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.post_layout"; - public static final String POST_LAYOUT_FRONT_PAGE_POST = "post_layout_best_post"; - public static final String POST_LAYOUT_SUBREDDIT_POST_BASE = "post_layout_subreddit_post_"; - public static final String POST_LAYOUT_MULTI_REDDIT_POST_BASE = "post_layout_multi_reddit_post_"; - public static final String POST_LAYOUT_USER_POST_BASE = "post_layout_user_post_"; - public static final String POST_LAYOUT_SEARCH_POST = "post_layout_search_post"; - public static final int POST_LAYOUT_CARD = 0; - public static final int POST_LAYOUT_COMPACT = 1; - - public static final String FRONT_PAGE_SCROLLED_POSITION_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.front_page_scrolled_position"; - public static final String FRONT_PAGE_SCROLLED_POSITION_FRONT_PAGE_BASE = "_front_page"; - public static final String FRONT_PAGE_SCROLLED_POSITION_ANONYMOUS = ".anonymous"; - - public static final String PULL_NOTIFICATION_TIME = "pull_notification_time"; - public static final String SHOW_ELAPSED_TIME_KEY = "show_elapsed_time"; - public static final String TIME_FORMAT_KEY = "time_format"; - public static final String TIME_FORMAT_DEFAULT_VALUE = "MMM d, yyyy, HH:mm"; - public static final String DEFAULT_POST_LAYOUT_KEY = "default_post_layout"; - public static final String SHOW_DIVIDER_IN_COMPACT_LAYOUT = "show_divider_in_compact_layout"; - public static final String SHOW_THUMBNAIL_ON_THE_LEFT_IN_COMPACT_LAYOUT = "show_thumbnail_on_the_left_in_compact_layout"; - public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT = "number_of_columns_in_post_feed_portrait"; - public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE = "number_of_columns_in_post_feed_landscape"; - public static final String SWIPE_RIGHT_TO_GO_BACK = "swipe_to_go_back_from_post_detail"; - public static final String VOLUME_KEYS_NAVIGATE_COMMENTS = "volume_keys_navigate_comments"; - public static final String VOLUME_KEYS_NAVIGATE_POSTS = "volume_keys_navigate_posts"; - public static final String MUTE_VIDEO = "mute_video"; - public static final String OPEN_LINK_IN_APP = "open_link_in_app"; - public static final String VIDEO_AUTOPLAY = "video_autoplay"; - public static final String VIDEO_AUTOPLAY_VALUE_ALWAYS_ON = "2"; - public static final String VIDEO_AUTOPLAY_VALUE_ON_WIFI = "1"; - public static final String VIDEO_AUTOPLAY_VALUE_NEVER = "0"; - public static final String MUTE_AUTOPLAYING_VIDEOS = "mute_autoplaying_videos"; - public static final String AUTOPLAY_NSFW_VIDEOS = "autoplay_nsfw_videos"; - public static final String AUTOMATICALLY_TRY_REDGIFS = "automatically_try_redgifs"; - public static final String LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON = "lock_jump_to_next_top_level_comment_button"; - public static final String SWAP_TAP_AND_LONG_COMMENTS = "swap_tap_and_long_in_comments"; - public static final String SWIPE_UP_TO_HIDE_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON = "swipe_up_to_hide_jump_to_next_top_level_comments_button"; - public static final String SHOW_TOP_LEVEL_COMMENTS_FIRST = "show_top_level_comments_first"; - public static final String CONFIRM_TO_EXIT = "confirm_to_exit"; - public static final String LOCK_BOTTOM_APP_BAR = "lock_bottom_app_bar"; - public static final String COMMENT_TOOLBAR_HIDDEN = "comment_toolbar_hidden"; - public static final String COMMENT_TOOLBAR_HIDE_ON_CLICK = "comment_toolbar_hide_on_click"; - public static final String FULLY_COLLAPSE_COMMENT = "fully_collapse_comment"; - public static final String SHOW_COMMENT_DIVIDER = "show_comment_divider"; - public static final String SHOW_ABSOLUTE_NUMBER_OF_VOTES = "show_absolute_number_of_votes"; - public static final String CUSTOMIZE_LIGHT_THEME = "customize_light_theme"; - public static final String CUSTOMIZE_DARK_THEME = "customize_dark_theme"; - public static final String CUSTOMIZE_AMOLED_THEME = "customize_amoled_theme"; - public static final String MANAGE_THEMES = "manage_themes"; - public static final String DELETE_ALL_SUBREDDITS_DATA_IN_DATABASE = "delete_all_subreddits_data_in_database"; - public static final String DELETE_ALL_USERS_DATA_IN_DATABASE = "delete_all_users_data_in_database"; - public static final String DELETE_ALL_SORT_TYPE_DATA_IN_DATABASE = "delete_all_sort_type_data_in_database"; - public static final String DELETE_ALL_POST_LAYOUT_DATA_IN_DATABASE = "delete_all_post_layout_data_in_database"; - public static final String DELETE_ALL_THEMES_IN_DATABASE = "delete_all_themes_in_database"; - public static final String DELETE_FRONT_PAGE_SCROLLED_POSITIONS_IN_DATABASE = "delete_front_page_scrolled_positions_in_database"; - public static final String DELETE_ALL_LEGACY_SETTINGS = "delete_all_legacy_settings"; - public static final String RESET_ALL_SETTINGS = "reset_all_settings"; - public static final String IMAGE_DOWNLOAD_LOCATION = "image_download_location"; - public static final String GIF_DOWNLOAD_LOCATION = "gif_download_location"; - public static final String VIDEO_DOWNLOAD_LOCATION = "video_download_location"; - public static final String SEPARATE_FOLDER_FOR_EACH_SUBREDDIT = "separate_folder_for_each_subreddit"; - public static final String VIBRATE_WHEN_ACTION_TRIGGERED = "vibrate_when_action_triggered"; - public static final String DISABLE_SWIPING_BETWEEN_TABS = "disable_swiping_between_tabs"; - public static final String ENABLE_SWIPE_ACTION = "enable_swipe_action"; - public static final String SWIPE_ACTION_THRESHOLD = "swipe_action_threshold"; - public static final String PULL_TO_REFRESH = "pull_to_refresh"; - public static final String REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER = "require_auth_to_account_section"; - public static final String LONG_PRESS_TO_HIDE_TOOLBAR_IN_COMPACT_LAYOUT = "long_press_to_hide_toolbar_in_compact_layout"; - public static final String POST_COMPACT_LAYOUT_TOOLBAR_HIDDEN_BY_DEFAULT = "post_compact_layout_toolbar_hidden_by_default"; - public static final String SECURITY = "security"; - public static final String START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT = "start_autoplay_visible_area_offset_portrait"; - public static final String START_AUTOPLAY_VISIBLE_AREA_OFFSET_LANDSCAPE = "start_autoplay_visible_area_offset_landscape"; - public static final String MUTE_NSFW_VIDEO = "mute_nsfw_video"; - public static final String VIDEO_PLAYER_IGNORE_NAV_BAR = "video_player_ignore_nav_bar"; - public static final String SAVE_FRONT_PAGE_SCROLLED_POSITION = "save_front_page_scrolled_position"; - public static final String DATA_SAVING_MODE = "data_saving_mode"; - public static final String DATA_SAVING_MODE_OFF = "0"; - public static final String DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA = "1"; - public static final String DATA_SAVING_MODE_ALWAYS = "2"; - public static final String NATIONAL_FLAGS = "national_flags"; - public static final String RESPECT_SUBREDDIT_RECOMMENDED_COMMENT_SORT_TYPE = "respect_subreddit_recommended_comment_sort_type"; - public static final String SUBREDDIT_FILTER_POPULAR_AND_ALL = "subreddit_filter_popular_and_all"; - public static final String UFO_CAPTURING_ANIMATION = "ufo_capturing_animation"; - public static final String HIDE_SUBREDDIT_DESCRIPTION = "hide_subreddit_description"; - public static final String DISABLE_IMAGE_PREVIEW = "disable_image_preview"; - public static final String SWIPE_LEFT_ACTION = "swipe_left_action"; - public static final String SWIPE_RIGHT_ACTION = "swipe_right_action"; - public static final int SWIPE_ACITON_UPVOTE = 0; - public static final int SWIPE_ACITON_DOWNVOTE = 1; - - public static final String MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.main_page_tabs"; - public static final String MAIN_PAGE_TAB_COUNT = "_main_page_tab_count"; - public static final String MAIN_PAGE_SHOW_TAB_NAMES = "_main_page_show_tab_names"; - public static final String MAIN_PAGE_TAB_1_TITLE = "_main_page_tab_1_title"; - public static final String MAIN_PAGE_TAB_2_TITLE = "_main_page_tab_2_title"; - public static final String MAIN_PAGE_TAB_3_TITLE = "_main_page_tab_3_title"; - public static final String MAIN_PAGE_TAB_1_POST_TYPE = "_main_page_tab_1_post_type"; - public static final String MAIN_PAGE_TAB_2_POST_TYPE = "_main_page_tab_2_post_type"; - public static final String MAIN_PAGE_TAB_3_POST_TYPE = "_main_page_tab_3_post_type"; - public static final String MAIN_PAGE_TAB_1_NAME = "_main_page_tab_1_name"; - public static final String MAIN_PAGE_TAB_2_NAME = "_main_page_tab_2_name"; - public static final String MAIN_PAGE_TAB_3_NAME = "_main_page_tab_3_name"; - public static final int MAIN_PAGE_TAB_POST_TYPE_HOME = 0; - public static final int MAIN_PAGE_TAB_POST_TYPE_POPULAR = 1; - public static final int MAIN_PAGE_TAB_POST_TYPE_ALL = 2; - public static final int MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT = 3; - public static final int MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT = 4; - public static final int MAIN_PAGE_TAB_POST_TYPE_USER = 5; - public static final String MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS = "_main_page_show_subscribed_subreddits"; - public static final String MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS = "_main_page_show_favorite_subscribed_subreddits"; - - public static final String BOTTOM_APP_BAR_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.bottom_app_bar"; - public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT = "main_activity_bottom_app_bar_option_count"; - public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1 = "main_activity_bottom_app_bar_option_1"; - public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2 = "main_activity_bottom_app_bar_option_2"; - public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3 = "main_activity_bottom_app_bar_option_3"; - public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4 = "main_activity_bottom_app_bar_option_4"; - public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB = "main_activity_bottom_app_bar_fab"; - public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT = "other_activities_bottom_app_bar_option_count"; - public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1 = "other_activities_bottom_app_bar_option_1"; - public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2 = "other_activities_bottom_app_bar_option_2"; - public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3 = "other_activities_bottom_app_bar_option_3"; - public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4 = "other_activities_bottom_app_bar_option_4"; - public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB = "other_activities_bottom_app_bar_fab"; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS = 0; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS = 1; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX = 2; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_PROFILE = 3; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS = 0; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_REFRESH = 1; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE = 2; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT = 3; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SEARCH = 4; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT = 5; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_USER = 6; - public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_RANDOM = 7; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME = 0; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS = 1; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX = 2; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE = 3; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_MULTIREDDITS = 4; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS = 0; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_REFRESH = 1; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE = 2; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT = 3; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SEARCH = 4; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT = 5; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_USER = 6; - public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_RANDOM = 7; - - public static final String NSFW_AND_SPOILER_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.nsfw_and_spoiler"; - public static final String NSFW_BASE = "_nsfw"; - public static final String BLUR_NSFW_BASE = "_blur_nsfw"; - public static final String BLUR_SPOILER_BASE = "_blur_spoiler"; - - //Legacy Settings - public static final String MAIN_PAGE_TAB_1_TITLE_LEGACY = "main_page_tab_1_title"; - public static final String MAIN_PAGE_TAB_2_TITLE_LEGACY = "main_page_tab_2_title"; - public static final String MAIN_PAGE_TAB_3_TITLE_LEGACY = "main_page_tab_3_title"; - public static final String MAIN_PAGE_TAB_1_POST_TYPE_LEGACY = "main_page_tab_1_post_type"; - public static final String MAIN_PAGE_TAB_2_POST_TYPE_LEGACY = "main_page_tab_2_post_type"; - public static final String MAIN_PAGE_TAB_3_POST_TYPE_LEGACY = "main_page_tab_3_post_type"; - public static final String MAIN_PAGE_TAB_1_NAME_LEGACY = "main_page_tab_1_name"; - public static final String MAIN_PAGE_TAB_2_NAME_LEGACY = "main_page_tab_2_name"; - public static final String MAIN_PAGE_TAB_3_NAME_LEGACY = "main_page_tab_3_name"; - - public static final String SORT_TYPE_ALL_POST_LEGACY = "sort_type_all_post"; - public static final String SORT_TIME_ALL_POST_LEGACY = "sort_time_all_post"; - public static final String SORT_TYPE_POPULAR_POST_LEGACY = "sort_type_popular_post"; - public static final String SORT_TIME_POPULAR_POST_LEGACY = "sort_time_popular_post"; - - public static final String POST_LAYOUT_POPULAR_POST_LEGACY = "post_layout_popular_post"; - public static final String POST_LAYOUT_ALL_POST_LEGACY = "post_layout_all_post"; - - public static final String NSFW_KEY_LEGACY = "nsfw"; - public static final String BLUR_NSFW_KEY_LEGACY = "blur_nsfw"; - public static final String BLUR_SPOILER_KEY_LEGACY = "blur_spoiler"; -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/Utils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/Utils.java deleted file mode 100644 index d277e8df..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/Utils.java +++ /dev/null @@ -1,266 +0,0 @@ -package ml.docilealligator.infinityforreddit.Utils; - -import android.app.Activity; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.net.ConnectivityManager; -import android.net.Network; -import android.net.NetworkCapabilities; -import android.net.NetworkInfo; -import android.os.Build; -import android.text.Html; -import android.text.Spannable; -import android.util.DisplayMetrics; -import android.view.inputmethod.InputMethodManager; -import android.widget.TextView; - -import androidx.annotation.Nullable; -import androidx.appcompat.widget.Toolbar; -import androidx.core.graphics.drawable.DrawableCompat; - -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Locale; - -import ml.docilealligator.infinityforreddit.R; -import ml.docilealligator.infinityforreddit.SortType; - -public class Utils { - public static final int NETWORK_TYPE_OTHER = -1; - public static final int NETWORK_TYPE_WIFI = 0; - public static final int NETWORK_TYPE_CELLULAR = 1; - private static final long SECOND_MILLIS = 1000; - private static final long MINUTE_MILLIS = 60 * SECOND_MILLIS; - private static final long HOUR_MILLIS = 60 * MINUTE_MILLIS; - private static final long DAY_MILLIS = 24 * HOUR_MILLIS; - private static final long MONTH_MILLIS = 30 * DAY_MILLIS; - private static final long YEAR_MILLIS = 12 * MONTH_MILLIS; - - public static String modifyMarkdown(String markdown) { - StringBuilder regexed = new StringBuilder(markdown.replaceAll("((?<=[\\s])|^)/[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com$0)").replaceAll("((?<=[\\s])|^)[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com/$0)")); - - /*int startIndex = 0; - - Pattern pattern = Pattern.compile("\\^.+"); - Matcher matcher = pattern.matcher(regexed); - // Check all occurrences - while (matcher.find(startIndex)) { - int count = 0; - Pattern pattern2 = Pattern.compile("(\\^\\([^)]+\\))"); - Matcher matcher2 = pattern2.matcher(matcher.group()); - if (matcher2.find()) { - regexed.setCharAt(matcher2.end() + matcher.start() - 1, '^'); - regexed.deleteCharAt(matcher2.start() + matcher.start() + 1); - - startIndex = matcher.start() + matcher2.end(); - String substring = regexed.substring(matcher.start() + matcher2.start() + 1, matcher.start() + matcher2.end() - 2); - String trimmedSubstring = substring.trim(); - regexed.replace(matcher.start() + matcher2.start() + 1, matcher.start() + matcher2.end() - 2, trimmedSubstring); - startIndex -= (substring.length() - trimmedSubstring.length()); - continue; - } - - regexed.insert(matcher.end(), '^'); - - for (int i = matcher.end() - 1; i >= matcher.start() + 1; i--) { - if (regexed.charAt(i) == '^') { - regexed.deleteCharAt(i); - count++; - } - } - startIndex = matcher.end() - count; - }*/ - return regexed.toString(); - } - - public static CharSequence trimTrailingWhitespace(CharSequence source) { - - if(source == null) - return ""; - - int i = source.length(); - - // loop back to the first non-whitespace character - do { - i--; - } while (i >= 0 && Character.isWhitespace(source.charAt(i))); - - return source.subSequence(0, i+1); - } - - public static String getFormattedTime(Locale locale, long time, String pattern) { - Calendar postTimeCalendar = Calendar.getInstance(); - postTimeCalendar.setTimeInMillis(time); - return new SimpleDateFormat(pattern, locale).format(postTimeCalendar.getTime()); - } - - public static String getElapsedTime(Context context, long time) { - long now = System.currentTimeMillis(); - long diff = now - time; - - if (diff < MINUTE_MILLIS) { - return context.getString(R.string.elapsed_time_just_now); - } else if (diff < 2 * MINUTE_MILLIS) { - return context.getString(R.string.elapsed_time_a_minute_ago); - } else if (diff < 50 * MINUTE_MILLIS) { - return context.getString(R.string.elapsed_time_minutes_ago, diff / MINUTE_MILLIS); - } else if (diff < 120 * MINUTE_MILLIS) { - return context.getString(R.string.elapsed_time_an_hour_ago); - } else if (diff < 24 * HOUR_MILLIS) { - return context.getString(R.string.elapsed_time_hours_ago, diff / HOUR_MILLIS); - } else if (diff < 48 * HOUR_MILLIS) { - return context.getString(R.string.elapsed_time_yesterday); - } else if (diff < MONTH_MILLIS) { - return context.getString(R.string.elapsed_time_days_ago, diff / DAY_MILLIS); - } else if (diff < 2 * MONTH_MILLIS) { - return context.getString(R.string.elapsed_time_a_month_ago); - } else if (diff < YEAR_MILLIS) { - return context.getString(R.string.elapsed_time_months_ago, diff / MONTH_MILLIS); - } else if (diff < 2 * YEAR_MILLIS) { - return context.getString(R.string.elapsed_time_a_year_ago); - } else { - return context.getString(R.string.elapsed_time_years_ago, diff / YEAR_MILLIS); - } - } - - public static String getNVotes(boolean showAbsoluteNumberOfVotes, int votes) { - if (showAbsoluteNumberOfVotes) { - return Integer.toString(votes); - } else { - if (Math.abs(votes) < 1000) { - return Integer.toString(votes); - } - return String.format(Locale.US, "%.1f", (float) votes / 1000) + "K"; - } - } - - public static void setHTMLWithImageToTextView(TextView textView, String content, boolean enlargeImage) { - Spannable html; - GlideImageGetter glideImageGetter = new GlideImageGetter(textView, enlargeImage); - if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { - html = (Spannable) Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY, glideImageGetter, null); - } else { - html = (Spannable) Html.fromHtml(content, glideImageGetter, null); - } - textView.setText(html); - } - - public static int getConnectedNetwork(Context context) { - ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (connMgr != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Network nw = connMgr.getActiveNetwork(); - if (nw == null) return NETWORK_TYPE_OTHER; - NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); - if (actNw != null) { - if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { - return NETWORK_TYPE_WIFI; - } - if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { - return NETWORK_TYPE_CELLULAR; - } - } - return NETWORK_TYPE_OTHER; - } else { - boolean isWifi = false; - boolean isCellular = false; - for (Network network : connMgr.getAllNetworks()) { - NetworkInfo networkInfo = connMgr.getNetworkInfo(network); - if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { - isWifi = true; - } - if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) { - isCellular = true; - } - } - - if (isWifi) { - return NETWORK_TYPE_WIFI; - } - - if (isCellular) { - return NETWORK_TYPE_CELLULAR; - } - - return NETWORK_TYPE_OTHER; - } - } - - return NETWORK_TYPE_OTHER; - } - - public static boolean isConnectedToWifi(Context context) { - ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (connMgr != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Network nw = connMgr.getActiveNetwork(); - if (nw == null) return false; - NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); - return actNw != null && actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI); - } else { - for (Network network : connMgr.getAllNetworks()) { - NetworkInfo networkInfo = connMgr.getNetworkInfo(network); - if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { - return networkInfo.isConnected(); - } - } - } - } - - return false; - } - - public static boolean isConnectedToCellularData(Context context) { - ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - if (connMgr != null) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - Network nw = connMgr.getActiveNetwork(); - if (nw == null) return false; - NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); - return actNw != null && actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); - } else { - for (Network network : connMgr.getAllNetworks()) { - NetworkInfo networkInfo = connMgr.getNetworkInfo(network); - if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) { - return networkInfo.isConnected(); - } - } - } - } - - return false; - } - - public static void displaySortTypeInToolbar(SortType sortType, Toolbar toolbar) { - if (sortType != null) { - if (sortType.getTime() != null) { - toolbar.setSubtitle(sortType.getType().fullName + ": " + sortType.getTime().fullName); - } else { - toolbar.setSubtitle(sortType.getType().fullName); - } - } - } - - public static void hideKeyboard(Activity activity) { - InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); - if (inputMethodManager != null && activity.getCurrentFocus() != null) { - inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); - } - } - - public static float convertDpToPixel(float dp, Context context){ - return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT); - } - - @Nullable - public static Drawable getTintedDrawable(Context context, int drawableId, int color) { - Drawable drawable = context.getDrawable(drawableId); - if (drawable != null) { - Drawable wrappedDrawable = DrawableCompat.wrap(drawable).mutate(); - DrawableCompat.setTint(wrappedDrawable, color); - return wrappedDrawable; - } - - return null; - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/VoteThing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/VoteThing.java index bb0264bf..9fb23c86 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/VoteThing.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/VoteThing.java @@ -8,8 +8,8 @@ import androidx.annotation.NonNull; import java.util.HashMap; import java.util.Map; -import ml.docilealligator.infinityforreddit.API.RedditAPI; -import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Retrofit; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/WallpaperSetter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/WallpaperSetter.java index f1407bab..e121ffcb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/WallpaperSetter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/WallpaperSetter.java @@ -14,7 +14,7 @@ import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; -import ml.docilealligator.infinityforreddit.AsyncTask.SetAsWallpaperAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SetAsWallpaperAsyncTask; public class WallpaperSetter { public static final int HOME_SCREEN = 0; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java b/app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java new file mode 100644 index 00000000..200faaab --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/account/Account.java @@ -0,0 +1,76 @@ +package ml.docilealligator.infinityforreddit.account; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "accounts") +public class Account { + @PrimaryKey + @NonNull + @ColumnInfo(name = "username") + private String username; + @ColumnInfo(name = "profile_image_url") + private String profileImageUrl; + @ColumnInfo(name = "banner_image_url") + private String bannerImageUrl; + @ColumnInfo(name = "karma") + private int karma; + @ColumnInfo(name = "access_token") + private String accessToken; + @ColumnInfo(name = "refresh_token") + private String refreshToken; + @ColumnInfo(name = "code") + private String code; + @ColumnInfo(name = "is_current_user") + private boolean isCurrentUser; + + public Account(@NonNull String username, String accessToken, String refreshToken, String code, + String profileImageUrl, String bannerImageUrl, int karma, boolean isCurrentUser) { + this.username = username; + this.accessToken = accessToken; + this.refreshToken = refreshToken; + this.code = code; + this.profileImageUrl = profileImageUrl; + this.bannerImageUrl = bannerImageUrl; + this.karma = karma; + this.isCurrentUser = isCurrentUser; + } + + public String getUsername() { + return username; + } + + public String getProfileImageUrl() { + return profileImageUrl; + } + + public String getBannerImageUrl() { + return bannerImageUrl; + } + + public int getKarma() { + return karma; + } + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public String getRefreshToken() { + return refreshToken; + } + + public String getCode() { + return code; + } + + public boolean isCurrentUser() { + return isCurrentUser; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java new file mode 100644 index 00000000..076f76f1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountDao.java @@ -0,0 +1,55 @@ +package ml.docilealligator.infinityforreddit.account; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface AccountDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(Account account); + + @Query("SELECT * FROM accounts") + List getAllAccounts(); + + @Query("SELECT * FROM accounts WHERE is_current_user = 0") + List getAllNonCurrentAccounts(); + + @Query("UPDATE accounts SET is_current_user = 0 WHERE is_current_user = 1") + void markAllAccountsNonCurrent(); + + @Query("DELETE FROM accounts WHERE is_current_user = 1") + void deleteCurrentAccount(); + + @Query("DELETE FROM accounts") + void deleteAllAccounts(); + + @Query("SELECT * FROM accounts WHERE username = :username COLLATE NOCASE LIMIT 1") + LiveData getAccountLiveData(String username); + + @Query("SELECT * FROM accounts WHERE username = :username COLLATE NOCASE LIMIT 1") + Account getAccountData(String username); + + @Query("SELECT * FROM accounts WHERE is_current_user = 1 LIMIT 1") + Account getCurrentAccount(); + + @Query("SELECT * FROM accounts WHERE is_current_user = 1 LIMIT 1") + LiveData getCurrentAccountLiveData(); + + @Query("UPDATE accounts SET profile_image_url = :profileImageUrl, banner_image_url = :bannerImageUrl, " + + "karma = :karma WHERE username = :username") + void updateAccountInfo(String username, String profileImageUrl, String bannerImageUrl, int karma); + + @Query("SELECT * FROM accounts WHERE is_current_user = 0 ORDER BY username COLLATE NOCASE ASC") + LiveData> getAccountsExceptCurrentAccountLiveData(); + + @Query("UPDATE accounts SET is_current_user = 1 WHERE username = :username") + void markAccountCurrent(String username); + + @Query("UPDATE accounts SET access_token = :accessToken WHERE username = :username") + void changeAccessToken(String username, String accessToken); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountRepository.java new file mode 100644 index 00000000..933d8d74 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountRepository.java @@ -0,0 +1,48 @@ +package ml.docilealligator.infinityforreddit.account; + +import android.os.AsyncTask; + +import androidx.lifecycle.LiveData; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class AccountRepository { + private AccountDao mAccountDao; + private LiveData> mAccountsExceptCurrentAccountLiveData; + private LiveData mCurrentAccountLiveData; + + AccountRepository(RedditDataRoomDatabase redditDataRoomDatabase, String username) { + mAccountDao = redditDataRoomDatabase.accountDao(); + mAccountsExceptCurrentAccountLiveData = mAccountDao.getAccountsExceptCurrentAccountLiveData(); + mCurrentAccountLiveData = mAccountDao.getCurrentAccountLiveData(); + } + + public LiveData> getAccountsExceptCurrentAccountLiveData() { + return mAccountsExceptCurrentAccountLiveData; + } + + public LiveData getCurrentAccountLiveData() { + return mCurrentAccountLiveData; + } + + public void insert(Account Account) { + new InsertAsyncTask(mAccountDao).execute(Account); + } + + private static class InsertAsyncTask extends AsyncTask { + + private AccountDao mAsyncTaskDao; + + InsertAsyncTask(AccountDao dao) { + mAsyncTaskDao = dao; + } + + @Override + protected Void doInBackground(final Account... params) { + mAsyncTaskDao.insert(params[0]); + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountViewModel.java new file mode 100644 index 00000000..195f6e39 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/account/AccountViewModel.java @@ -0,0 +1,58 @@ +package ml.docilealligator.infinityforreddit.account; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class AccountViewModel extends AndroidViewModel { + private AccountRepository mAccountRepository; + private LiveData> mAccountsExceptCurrentAccountLiveData; + private LiveData mCurrentAccountLiveData; + + public AccountViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String id) { + super(application); + mAccountRepository = new AccountRepository(redditDataRoomDatabase, id); + mAccountsExceptCurrentAccountLiveData = mAccountRepository.getAccountsExceptCurrentAccountLiveData(); + mCurrentAccountLiveData = mAccountRepository.getCurrentAccountLiveData(); + } + + public LiveData> getAccountsExceptCurrentAccountLiveData() { + return mAccountsExceptCurrentAccountLiveData; + } + + public LiveData getCurrentAccountLiveData() { + return mCurrentAccountLiveData; + } + + public void insert(Account userData) { + mAccountRepository.insert(userData); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + + @NonNull + private final Application mApplication; + private final RedditDataRoomDatabase mRedditDataRoomDatabase; + private final String mUsername; + + public Factory(@NonNull Application application, RedditDataRoomDatabase redditDataRoomDatabase, String username) { + mApplication = application; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mUsername = username; + } + + @Override + public T create(Class modelClass) { + //noinspection unchecked + return (T) new AccountViewModel(mApplication, mRedditDataRoomDatabase, mUsername); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountPostsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountPostsActivity.java new file mode 100644 index 00000000..74cf5393 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountPostsActivity.java @@ -0,0 +1,314 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class AccountPostsActivity extends BaseActivity implements SortTypeSelectionCallback, + PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { + + static final String EXTRA_USER_WHERE = "EUW"; + + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String FRAGMENT_OUT_STATE = "FOS"; + + @BindView(R.id.coordinator_layout_account_posts_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.collapsing_toolbar_layout_account_posts_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.appbar_layout_account_posts_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_account_posts_activity) + Toolbar toolbar; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean isInLazyMode = false; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String mUserWhere; + private Fragment mFragment; + private Menu mMenu; + private AppBarLayout.LayoutParams params; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_account_posts); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + mUserWhere = getIntent().getExtras().getString(EXTRA_USER_WHERE); + if (mUserWhere.equals(PostDataSource.USER_WHERE_UPVOTED)) { + toolbar.setTitle(R.string.upvoted); + } else if (mUserWhere.equals(PostDataSource.USER_WHERE_DOWNVOTED)) { + toolbar.setTitle(R.string.downvoted); + } else if (mUserWhere.equals(PostDataSource.USER_WHERE_HIDDEN)) { + toolbar.setTitle(R.string.hidden); + } else if (mUserWhere.equals(PostDataSource.USER_WHERE_GILDED)) { + toolbar.setTitle(R.string.gilded); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); + + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_account_posts_activity, mFragment).commit(); + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndInitializeFragment(); + } + } else { + getCurrentAccountAndInitializeFragment(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mFragment != null) { + return ((FragmentCommunicator) mFragment).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()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + private void getCurrentAccountAndInitializeFragment() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + initializeFragment(); + }).execute(); + } + + private void initializeFragment() { + mFragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); + bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountName); + bundle.putString(PostFragment.EXTRA_USER_WHERE, mUserWhere); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + mFragment.setArguments(bundle); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_account_posts_activity, mFragment).commit(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.account_posts_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_posts_activity); + if (isInLazyMode) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } else { + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.action_refresh_account_posts_activity: + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_account_posts_activity).setTitle(R.string.action_start_lazy_mode); + } + if (mFragment != null) { + ((PostFragment) mFragment).refresh(); + } + return true; + case R.id.action_lazy_mode_account_posts_activity: + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_posts_activity); + if (isInLazyMode) { + ((FragmentCommunicator) mFragment).stopLazyMode(); + isInLazyMode = false; + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } else { + if (((FragmentCommunicator) mFragment).startLazyMode()) { + isInLazyMode = true; + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } + } + return true; + case R.id.action_change_post_layout_account_posts_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + case android.R.id.home: + finish(); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + public void sortTypeSelected(SortType sortType) { + if (mFragment != null) { + ((PostFragment) mFragment).changeSortType(sortType); + } + } + + @Override + public void sortTypeSelected(String sortType) { + + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { + ((FragmentCommunicator) mFragment).changeNSFW(changeNSFWEvent.nsfw); + } + + @Override + public void postLayoutSelected(int postLayout) { + if (mFragment != null) { + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + mAccountName, postLayout).apply(); + ((FragmentCommunicator) mFragment).changePostLayout(postLayout); + } + } + + @Override + public void onLongPress() { + if (mFragment != null) { + ((PostFragment) mFragment).goBackToTop(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java new file mode 100644 index 00000000..46b474fc --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java @@ -0,0 +1,440 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class AccountSavedThingActivity extends BaseActivity implements ActivityToolbarInterface, + PostLayoutBottomSheetFragment.PostLayoutSelectionCallback { + + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + + @BindView(R.id.coordinator_layout_account_saved_thing_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.collapsing_toolbar_layout_account_saved_thing_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.appbar_layout_account_saved_thing_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_account_saved_thing_activity) + Toolbar toolbar; + @BindView(R.id.tab_layout_tab_layout_account_saved_thing_activity_activity) + TabLayout tabLayout; + @BindView(R.id.view_pager_account_saved_thing_activity) + ViewPager2 viewPager2; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private FragmentManager fragmentManager; + private SectionsPagerAdapter sectionsPagerAdapter; + private SlidrInterface mSlidrInterface; + private Menu mMenu; + private AppBarLayout.LayoutParams params; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private boolean isInLazyMode = false; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_account_saved_thing); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); + + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + + fragmentManager = getSupportFragmentManager(); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndInitializeViewPager(); + } else { + initializeViewPager(); + } + } else { + getCurrentAccountAndInitializeViewPager(); + } + } + + @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()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + applyTabLayoutTheme(tabLayout); + } + + private void getCurrentAccountAndInitializeViewPager() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + initializeViewPager(); + }).execute(); + } + + private void initializeViewPager() { + sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(2); + viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); + new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { + switch (position) { + case 0: + tab.setText(R.string.posts); + break; + case 1: + tab.setText(R.string.comments); + 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.account_saved_thing_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity); + if (isInLazyMode) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } else { + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_refresh_account_saved_thing_activity: + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity).setTitle(R.string.action_start_lazy_mode); + } + sectionsPagerAdapter.refresh(); + return true; + case R.id.action_lazy_mode_account_saved_thing_activity: + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_account_saved_thing_activity); + if (isInLazyMode) { + isInLazyMode = false; + sectionsPagerAdapter.stopLazyMode(); + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = true; + if (sectionsPagerAdapter.startLazyMode()) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + appBarLayout.setExpanded(false); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = false; + } + } + return true; + case R.id.action_change_post_layout_account_saved_thing_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + } + + @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(); + } + } + + private void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + private void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + + @Override + public void postLayoutSelected(int postLayout) { + if (sectionsPagerAdapter != null) { + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + mAccountName, postLayout).apply(); + sectionsPagerAdapter.changePostLayout(postLayout); + } + } + + private class SectionsPagerAdapter extends FragmentStateAdapter { + + SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { + super(fm, lifecycle); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + if (position == 0) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); + bundle.putString(PostFragment.EXTRA_USER_NAME, mAccountName); + bundle.putString(PostFragment.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SAVED); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + CommentsListingFragment fragment = new CommentsListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(CommentsListingFragment.EXTRA_USERNAME, mAccountName); + bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, true); + 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(); + } + } + + boolean startLazyMode() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof FragmentCommunicator) { + return ((FragmentCommunicator) fragment).startLazyMode(); + } + return false; + } + + void stopLazyMode() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) fragment).stopLazyMode(); + } + } + + public void changeNSFW(boolean nsfw) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeNSFW(nsfw); + } + } + + public void changePostLayout(int postLayout) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changePostLayout(postLayout); + } + } + + + public void goBackToTop() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).goBackToTop(); + } else if (fragment instanceof CommentsListingFragment) { + ((CommentsListingFragment) fragment).goBackToTop(); + } + } + + @Override + public int getItemCount() { + return 2; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/BaseActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/BaseActivity.java new file mode 100644 index 00000000..e01c0430 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/BaseActivity.java @@ -0,0 +1,326 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.annotation.SuppressLint; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.view.menu.MenuItemImpl; +import androidx.appcompat.widget.Toolbar; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager2.widget.ViewPager2; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.tabs.TabLayout; + +import java.lang.reflect.Field; + +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.ContentFontStyle; +import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.FontStyle; +import ml.docilealligator.infinityforreddit.font.TitleFontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontStyle; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; + +public abstract class BaseActivity extends AppCompatActivity { + private boolean immersiveInterface; + private boolean changeStatusBarIconColor; + private boolean transparentStatusBarAfterToolbarCollapsed; + private boolean hasDrawerLayout = false; + private boolean isImmersiveInterfaceApplicable = true; + private int systemVisibilityToolbarExpanded = 0; + private int systemVisibilityToolbarCollapsed = 0; + private CustomThemeWrapper customThemeWrapper; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + customThemeWrapper = getCustomThemeWrapper(); + + SharedPreferences mSharedPreferences = getDefaultSharedPreferences(); + boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; + int systemThemeType = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.THEME_KEY, "2")); + immersiveInterface = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && + mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true); + switch (systemThemeType) { + case 0: + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); + getTheme().applyStyle(R.style.Theme_Normal, true); + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); + break; + case 1: + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); + if(mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { + getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); + } else { + getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); + } + break; + case 2: + if (systemDefault) { + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM); + } else { + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_AUTO_BATTERY); + } + if((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) { + getTheme().applyStyle(R.style.Theme_Normal, true); + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); + } else { + if(mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { + getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); + } else { + getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); + } + } + } + + boolean userDefinedChangeSatusBarIconColorInImmersiveInterface = + customThemeWrapper.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface(); + if (immersiveInterface && isImmersiveInterfaceApplicable) { + changeStatusBarIconColor = userDefinedChangeSatusBarIconColorInImmersiveInterface; + } else { + changeStatusBarIconColor = false; + } + + getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(TitleFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); + + Window window = getWindow(); + View decorView = window.getDecorView(); + boolean isLightStatusbar = customThemeWrapper.isLightStatusBar(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + boolean isLightNavBar = customThemeWrapper.isLightNavBar(); + if (isLightStatusbar) { + if (isLightNavBar) { + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + if (changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + } else { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + } + } else { + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + if (!changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + } + } else { + if (isLightNavBar) { + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + if (changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + } + } else { + if (changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + } + } + decorView.setSystemUiVisibility(systemVisibilityToolbarExpanded); + if (!(immersiveInterface && isImmersiveInterfaceApplicable)) { + window.setNavigationBarColor(customThemeWrapper.getNavBarColor()); + if (!hasDrawerLayout) { + window.setStatusBarColor(customThemeWrapper.getColorPrimaryDark()); + } + } else { + window.setNavigationBarColor(Color.TRANSPARENT); + window.setStatusBarColor(Color.TRANSPARENT); + } + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (isLightStatusbar) { + decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + if (!changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + } else if (changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + } + } + + protected abstract SharedPreferences getDefaultSharedPreferences(); + + protected abstract CustomThemeWrapper getCustomThemeWrapper(); + + protected abstract void applyCustomTheme(); + + protected boolean isChangeStatusBarIconColor() { + return changeStatusBarIconColor; + } + + protected int getSystemVisibilityToolbarExpanded() { + return systemVisibilityToolbarExpanded; + } + + protected int getSystemVisibilityToolbarCollapsed() { + return systemVisibilityToolbarCollapsed; + } + + public boolean isImmersiveInterface() { + return immersiveInterface; + } + + protected void setToolbarGoToTop(Toolbar toolbar) { + toolbar.setOnLongClickListener(view -> { + if (BaseActivity.this instanceof ActivityToolbarInterface) { + ((ActivityToolbarInterface) BaseActivity.this).onLongPress(); + } + return true; + }); + } + + protected void adjustToolbar(Toolbar toolbar) { + int statusBarResourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (statusBarResourceId > 0) { + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); + params.topMargin = getResources().getDimensionPixelSize(statusBarResourceId); + toolbar.setLayoutParams(params); + } + } + + protected void addOnOffsetChangedListener(AppBarLayout appBarLayout) { + View decorView = getWindow().getDecorView(); + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { + if (state == State.COLLAPSED) { + decorView.setSystemUiVisibility(getSystemVisibilityToolbarCollapsed()); + } else if (state == State.EXPANDED) { + decorView.setSystemUiVisibility(getSystemVisibilityToolbarExpanded()); + } + } + }); + } + + public int getNavBarHeight() { + if (isImmersiveInterfaceApplicable && immersiveInterface && getDefaultSharedPreferences().getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_IGNORE_NAV_BAR_KEY, false)) { + return 0; + } + + Resources resources = getResources(); + int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); + if (navBarResourceId > 0) { + return resources.getDimensionPixelSize(navBarResourceId); + } + return 0; + } + + protected void setTransparentStatusBarAfterToolbarCollapsed() { + this.transparentStatusBarAfterToolbarCollapsed = true; + } + + protected void setHasDrawerLayout() { + hasDrawerLayout = true; + } + + public void setImmersiveModeNotApplicable() { + isImmersiveInterfaceApplicable = false; + } + + protected void applyAppBarLayoutAndToolbarTheme(AppBarLayout appBarLayout, Toolbar toolbar) { + appBarLayout.setBackgroundColor(customThemeWrapper.getColorPrimary()); + toolbar.setTitleTextColor(customThemeWrapper.getToolbarPrimaryTextAndIconColor()); + toolbar.setSubtitleTextColor(customThemeWrapper.getToolbarSecondaryTextColor()); + if (toolbar.getNavigationIcon() != null) { + toolbar.getNavigationIcon().setColorFilter(customThemeWrapper.getToolbarPrimaryTextAndIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); + } + if (toolbar.getOverflowIcon() != null) { + toolbar.getOverflowIcon().setColorFilter(customThemeWrapper.getToolbarPrimaryTextAndIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); + } + } + + @SuppressLint("RestrictedApi") + protected boolean applyMenuItemTheme(Menu menu) { + if (customThemeWrapper != null) { + int size = Math.min(menu.size(), 2); + for (int i = 0; i < size; i++) { + MenuItem item = menu.getItem(i); + if (((MenuItemImpl) item).requestsActionButton()) { + Drawable drawable = item.getIcon(); + if (drawable != null) { + DrawableCompat.setTint(drawable, customThemeWrapper.getToolbarPrimaryTextAndIconColor()); + item.setIcon(drawable); + } + } + } + } + return true; + } + + protected void applyTabLayoutTheme(TabLayout tabLayout) { + int toolbarAndTabBackgroundColor = customThemeWrapper.getColorPrimary(); + tabLayout.setBackgroundColor(toolbarAndTabBackgroundColor); + tabLayout.setSelectedTabIndicatorColor(customThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabIndicator()); + tabLayout.setTabTextColors(customThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor(), + customThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor()); + } + + protected void applyFABTheme(FloatingActionButton fab) { + fab.setBackgroundTintList(ColorStateList.valueOf(customThemeWrapper.getColorPrimaryLightTheme())); + fab.setImageTintList(ColorStateList.valueOf(customThemeWrapper.getFABIconColor())); + } + + protected void fixViewPager2Sensitivity(ViewPager2 viewPager2) { + try { + Field recyclerViewField = ViewPager2.class.getDeclaredField("mRecyclerView"); + recyclerViewField.setAccessible(true); + + RecyclerView recyclerView = (RecyclerView) recyclerViewField.get(viewPager2); + + Field touchSlopField = RecyclerView.class.getDeclaredField("mTouchSlop"); + touchSlopField.setAccessible(true); + + Object touchSlopBox = touchSlopField.get(recyclerView); + if (touchSlopBox != null) { + int touchSlop = (int) touchSlopBox; + touchSlopField.set(recyclerView, touchSlop * 4); + } + } catch (NoSuchFieldException | IllegalAccessException ignore) {} + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java new file mode 100644 index 00000000..c12403de --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CommentActivity.java @@ -0,0 +1,433 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.Spanned; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; + +import org.commonmark.ext.gfm.tables.TableBlock; +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 io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.recycler.MarkwonAdapter; +import io.noties.markwon.recycler.table.TableEntry; +import io.noties.markwon.recycler.table.TableEntryPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomSheetFragment; +import ml.docilealligator.infinityforreddit.comment.Comment; +import ml.docilealligator.infinityforreddit.comment.SendComment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + +public class CommentActivity extends BaseActivity { + + public static final String EXTRA_COMMENT_PARENT_TEXT_KEY = "ECPTK"; + public static final String EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY = "ECPTMK"; + public static final String EXTRA_COMMENT_PARENT_BODY_KEY = "ECPBK"; + public static final String EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY = "ECPBMK"; + public static final String EXTRA_PARENT_FULLNAME_KEY = "EPFK"; + public static final String EXTRA_PARENT_DEPTH_KEY = "EPDK"; + public static final String EXTRA_PARENT_POSITION_KEY = "EPPK"; + public static final String EXTRA_IS_REPLYING_KEY = "EIRK"; + public static final String RETURN_EXTRA_COMMENT_DATA_KEY = "RECDK"; + public static final int WRITE_COMMENT_REQUEST_CODE = 1; + + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + + @BindView(R.id.coordinator_layout_comment_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_comment_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_comment_activity) + Toolbar toolbar; + @BindView(R.id.comment_parent_markwon_view_comment_activity) + TextView commentParentMarkwonView; + @BindView(R.id.divider_comment_activity) + View divider; + @BindView(R.id.content_markdown_view_comment_activity) + RecyclerView contentMarkdownRecyclerView; + @BindView(R.id.comment_edit_text_comment_activity) + EditText commentEditText; + @BindView(R.id.markdown_bottom_bar_recycler_view_comment_activity) + RecyclerView markdownBottomBarRecyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String parentFullname; + private int parentDepth; + private int parentPosition; + private boolean isSubmitting = false; + private boolean isReplying; + private int markdownColor; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_comment); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (savedInstanceState == null) { + getCurrentAccount(); + } else { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + } + + Intent intent = getIntent(); + String parentTextMarkdown = intent.getStringExtra(EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY); + String parentText = intent.getStringExtra(EXTRA_COMMENT_PARENT_TEXT_KEY); + CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); + + int linkColor = mCustomThemeWrapper.getLinkColor(); + Markwon markwon = Markwon.builder(this) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(CommentActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .build(); + if (parentTextMarkdown != null) { + commentParentMarkwonView.setOnLongClickListener(view -> { + Utils.hideKeyboard(CommentActivity.this); + Bundle bundle = new Bundle(); + if (parentText == null) { + bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, parentTextMarkdown); + } else { + bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, parentText); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, parentTextMarkdown); + } + copyTextBottomSheetFragment.setArguments(bundle); + copyTextBottomSheetFragment.show(getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); + return true; + }); + markwon.setMarkdown(commentParentMarkwonView, parentTextMarkdown); + } + String parentBodyMarkdown = intent.getStringExtra(EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY); + String parentBody = intent.getStringExtra(EXTRA_COMMENT_PARENT_BODY_KEY); + if (parentBodyMarkdown != null && !parentBodyMarkdown.equals("")) { + contentMarkdownRecyclerView.setVisibility(View.VISIBLE); + contentMarkdownRecyclerView.setNestedScrollingEnabled(false); + Markwon postBodyMarkwon = Markwon.builder(this) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + textView.setTextColor(markdownColor); + textView.setOnLongClickListener(view -> { + Utils.hideKeyboard(CommentActivity.this); + Bundle bundle = new Bundle(); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, parentBody); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, parentBodyMarkdown); + copyTextBottomSheetFragment.setArguments(bundle); + copyTextBottomSheetFragment.show(getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); + return true; + }); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(CommentActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .usePlugin(TableEntryPlugin.create(this)) + .build(); + MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) + .include(TableBlock.class, TableEntry.create(builder -> builder + .tableLayout(R.layout.adapter_table_block, R.id.table_layout) + .textLayoutIsRoot(R.layout.view_table_entry_cell))) + .build(); + contentMarkdownRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + contentMarkdownRecyclerView.setAdapter(markwonAdapter); + markwonAdapter.setMarkdown(postBodyMarkwon, parentBodyMarkdown); + markwonAdapter.notifyDataSetChanged(); + } + parentFullname = intent.getStringExtra(EXTRA_PARENT_FULLNAME_KEY); + parentDepth = intent.getExtras().getInt(EXTRA_PARENT_DEPTH_KEY); + parentPosition = intent.getExtras().getInt(EXTRA_PARENT_POSITION_KEY); + isReplying = intent.getExtras().getBoolean(EXTRA_IS_REPLYING_KEY); + if (isReplying) { + toolbar.setTitle(getString(R.string.comment_activity_label_is_replying)); + } + + setSupportActionBar(toolbar); + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, commentEditText, item); + }); + + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, + LinearLayoutManager.HORIZONTAL, false)); + markdownBottomBarRecyclerView.setAdapter(adapter); + + commentEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + commentParentMarkwonView.setTextColor(mCustomThemeWrapper.getCommentColor()); + divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); + commentEditText.setTextColor(mCustomThemeWrapper.getCommentColor()); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + commentEditText.setHintTextColor(secondaryTextColor); + markdownColor = secondaryTextColor; + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + }).execute(); + } + + @Override + protected void onPause() { + super.onPause(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.hideSoftInputFromWindow(commentEditText.getWindowToken(), 0); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.comment_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + onBackPressed(); + return true; + } else if (itemId == R.id.action_preview_comment_activity) { + Intent intent = new Intent(this, FullMarkdownActivity.class); + intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, commentEditText.getText().toString()); + startActivity(intent); + } else if (itemId == R.id.action_send_comment_activity) { + if (!isSubmitting) { + isSubmitting = true; + if (commentEditText.getText() == null || commentEditText.getText().toString().equals("")) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.comment_content_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + item.setEnabled(false); + item.getIcon().setAlpha(130); + Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_comment, Snackbar.LENGTH_INDEFINITE); + sendingSnackbar.show(); + + SendComment.sendComment(commentEditText.getText().toString(), parentFullname, parentDepth, + getResources().getConfiguration().locale, mOauthRetrofit, + mAccessToken, + new SendComment.SendCommentListener() { + @Override + public void sendCommentSuccess(Comment comment) { + isSubmitting = false; + item.setEnabled(true); + item.getIcon().setAlpha(255); + Toast.makeText(CommentActivity.this, R.string.send_comment_success, Toast.LENGTH_SHORT).show(); + Intent returnIntent = new Intent(); + returnIntent.putExtra(RETURN_EXTRA_COMMENT_DATA_KEY, comment); + returnIntent.putExtra(EXTRA_PARENT_FULLNAME_KEY, parentFullname); + if (isReplying) { + returnIntent.putExtra(EXTRA_PARENT_POSITION_KEY, parentPosition); + } + setResult(RESULT_OK, returnIntent); + finish(); + } + + @Override + public void sendCommentFailed(@Nullable String errorMessage) { + isSubmitting = false; + sendingSnackbar.dismiss(); + item.setEnabled(true); + item.getIcon().setAlpha(255); + + if (errorMessage == null || !errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.send_comment_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); + } + } + }); + } + return true; + } + + return false; + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + } + + @Override + public void onBackPressed() { + if (isSubmitting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_comment_detail); + } else { + if (commentEditText.getText().toString().equals("")) { + finish(); + } else { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CreateMultiRedditActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CreateMultiRedditActivity.java new file mode 100644 index 00000000..f44f34d3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CreateMultiRedditActivity.java @@ -0,0 +1,241 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.snackbar.Snackbar; +import com.r0adkll.slidr.Slidr; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.multireddit.CreateMultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.MultiRedditJSONModel; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class CreateMultiRedditActivity extends BaseActivity { + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 1; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String SELECTED_SUBREDDITS_STATE = "SSS"; + @BindView(R.id.coordinator_layout_create_multi_reddit_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_create_multi_reddit_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_create_multi_reddit_activity) + Toolbar toolbar; + @BindView(R.id.multi_reddit_name_edit_text_create_multi_reddit_activity) + EditText nameEditText; + @BindView(R.id.divider_1_create_multi_reddit_activity) + View divider1; + @BindView(R.id.description_edit_text_create_multi_reddit_activity) + EditText descriptionEditText; + @BindView(R.id.divider_2_create_multi_reddit_activity) + View divider2; + @BindView(R.id.visibility_wrapper_linear_layout_create_multi_reddit_activity) + LinearLayout visibilityLinearLayout; + @BindView(R.id.visibility_text_view_create_multi_reddit_activity) + TextView visibilityTextView; + @BindView(R.id.visibility_switch_create_multi_reddit_activity) + Switch visibilitySwitch; + @BindView(R.id.select_subreddit_text_view_create_multi_reddit_activity) + TextView selectSubredditTextView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private ArrayList mSubreddits; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_create_multi_reddit); + + ButterKnife.bind(this); + + 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); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + mSubreddits = savedInstanceState.getStringArrayList(SELECTED_SUBREDDITS_STATE); + + if (!mNullAccessToken && mAccountName == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + mSubreddits = new ArrayList<>(); + getCurrentAccountAndBindView(); + } + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + Toast.makeText(this, R.string.logged_out, Toast.LENGTH_SHORT).show(); + finish(); + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + bindView(); + } + }).execute(); + } + + private void bindView() { + selectSubredditTextView.setOnClickListener(view -> { + Intent intent = new Intent(CreateMultiRedditActivity.this, SelectedSubredditsActivity.class); + intent.putStringArrayListExtra(SelectedSubredditsActivity.EXTRA_SELECTED_SUBREDDITS, mSubreddits); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.create_multi_reddit_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_save_create_multi_reddit_activity: + if (mAccountName == null || mAccessToken == null) { + Snackbar.make(coordinatorLayout, R.string.something_went_wrong, Snackbar.LENGTH_SHORT).show(); + return true; + } + if (nameEditText.getText() == null || nameEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.no_multi_reddit_name, Snackbar.LENGTH_SHORT).show(); + return true; + } + + String jsonModel = new MultiRedditJSONModel(nameEditText.getText().toString(), descriptionEditText.getText().toString(), + visibilitySwitch.isChecked(), mSubreddits).createJSONModel(); + CreateMultiReddit.createMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, + "/user/" + mAccountName + "/m/" + nameEditText.getText().toString(), + jsonModel, new CreateMultiReddit.CreateMultiRedditListener() { + @Override + public void success() { + finish(); + } + + @Override + public void failed(int errorCode) { + if (errorCode == 409) { + Snackbar.make(coordinatorLayout, R.string.duplicate_multi_reddit, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, R.string.create_multi_reddit_failed, Snackbar.LENGTH_SHORT).show(); + } + } + }); + } + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE && resultCode == RESULT_OK) { + if (data != null) { + mSubreddits = data.getStringArrayListExtra( + SubredditMultiselectionActivity.EXTRA_RETURN_SELECTED_SUBREDDITS); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putStringArrayList(SELECTED_SUBREDDITS_STATE, mSubreddits); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + nameEditText.setTextColor(primaryTextColor); + nameEditText.setHintTextColor(secondaryTextColor); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + descriptionEditText.setTextColor(primaryTextColor); + descriptionEditText.setHintTextColor(secondaryTextColor); + visibilityTextView.setTextColor(primaryTextColor); + selectSubredditTextView.setTextColor(primaryTextColor); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java new file mode 100644 index 00000000..c30cc188 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemeListingActivity.java @@ -0,0 +1,331 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.CustomThemeListingRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.ChangeThemeNameAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.DeleteThemeAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.GetCustomThemeAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.InsertCustomThemeAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CreateThemeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CustomThemeOptionsBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeViewModel; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; + +import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN; + +public class CustomThemeListingActivity extends BaseActivity implements + CustomThemeOptionsBottomSheetFragment.CustomThemeOptionsBottomSheetFragmentListener, + CreateThemeBottomSheetFragment.SelectBaseThemeBottomSheetFragmentListener { + + @BindView(R.id.coordinator_layout_custom_theme_listing_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_customize_theme_listing_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_customize_theme_listing_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_customize_theme_listing_activity) + RecyclerView recyclerView; + @BindView(R.id.fab_custom_theme_listing_activity) + FloatingActionButton fab; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + @Inject + @Named("light_theme") + SharedPreferences lightThemeSharedPreferences; + @Inject + @Named("dark_theme") + SharedPreferences darkThemeSharedPreferences; + @Inject + @Named("amoled_theme") + SharedPreferences amoledThemeSharedPreferences; + public CustomThemeViewModel customThemeViewModel; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_custom_theme_listing); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + CustomThemeListingRecyclerViewAdapter adapter = new CustomThemeListingRecyclerViewAdapter(this, + CustomThemeWrapper.getPredefinedThemes(this)); + recyclerView.setAdapter(adapter); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + fab.hide(); + } else if (dy < 0) { + fab.show(); + } + } + }); + + customThemeViewModel = new ViewModelProvider(this, + new CustomThemeViewModel.Factory(redditDataRoomDatabase)) + .get(CustomThemeViewModel.class); + customThemeViewModel.getAllCustomThemes().observe(this, adapter::setUserThemes); + + fab.setOnClickListener(view -> { + CreateThemeBottomSheetFragment createThemeBottomSheetFragment = new CreateThemeBottomSheetFragment(); + createThemeBottomSheetFragment.show(getSupportFragmentManager(), createThemeBottomSheetFragment.getTag()); + }); + } + + @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() { + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + @Override + public void changeName(String oldThemeName) { + View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); + EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); + themeNameEditText.setText(oldThemeName); + themeNameEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.edit_theme_name) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); + } + new ChangeThemeNameAsyncTask(redditDataRoomDatabase, oldThemeName, themeNameEditText.getText().toString()).execute(); + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); + } + }) + .show(); + } + + @Override + public void shareTheme(String themeName) { + new GetCustomThemeAsyncTask(redditDataRoomDatabase, themeName, customTheme -> { + if (customTheme != null) { + String jsonModel = customTheme.getJSONModel(); + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + ClipData clip = ClipData.newPlainText("simple text", jsonModel); + clipboard.setPrimaryClip(clip); + Snackbar.make(coordinatorLayout, R.string.theme_copied, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, R.string.copy_theme_faied, Snackbar.LENGTH_SHORT).show(); + } + } else { + Snackbar.make(coordinatorLayout, R.string.cannot_find_theme, Snackbar.LENGTH_SHORT).show(); + } + }).execute(); + } + + @Override + public void delete(String themeName) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete_theme) + .setMessage(getString(R.string.delete_theme_dialog_message, themeName)) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> new DeleteThemeAsyncTask(redditDataRoomDatabase, themeName, (isLightTheme, isDarkTheme, isAmoledTheme) -> { + if (isLightTheme) { + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences( + CustomThemeWrapper.getIndigo(CustomThemeListingActivity.this), lightThemeSharedPreferences); + } + if (isDarkTheme) { + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences( + CustomThemeWrapper.getIndigoDark(CustomThemeListingActivity.this), darkThemeSharedPreferences); + } + if (isAmoledTheme) { + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences( + CustomThemeWrapper.getIndigoAmoled(CustomThemeListingActivity.this), amoledThemeSharedPreferences); + } + EventBus.getDefault().post(new RecreateActivityEvent()); + }).execute()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + public void shareTheme(CustomTheme customTheme) { + if (customTheme != null) { + String jsonModel = customTheme.getJSONModel(); + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + ClipData clip = ClipData.newPlainText("simple text", jsonModel); + clipboard.setPrimaryClip(clip); + Snackbar.make(coordinatorLayout, R.string.theme_copied, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, R.string.copy_theme_faied, Snackbar.LENGTH_SHORT).show(); + } + } else { + Snackbar.make(coordinatorLayout, R.string.cannot_find_theme, Snackbar.LENGTH_SHORT).show(); + } + } + + @Subscribe + public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { + recreate(); + } + + @Override + public void importTheme() { + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + // If it does contain data, decide if you can handle the data. + if (!clipboard.hasPrimaryClip()) { + Snackbar.make(coordinatorLayout, R.string.no_data_in_clipboard, Snackbar.LENGTH_SHORT).show(); + } else if (clipboard.getPrimaryClipDescription() != null && + !clipboard.getPrimaryClipDescription().hasMimeType(MIMETYPE_TEXT_PLAIN)) { + // since the clipboard has data but it is not plain text + Snackbar.make(coordinatorLayout, R.string.no_data_in_clipboard, Snackbar.LENGTH_SHORT).show(); + } else if (clipboard.getPrimaryClip() != null) { + ClipData.Item item = clipboard.getPrimaryClip().getItemAt(0); + String json = item.getText().toString(); + try { + CustomTheme customTheme = new Gson().fromJson(json, CustomTheme.class); + checkDuplicateAndImportTheme(customTheme, true); + } catch (JsonSyntaxException e) { + Snackbar.make(coordinatorLayout, R.string.parse_theme_failed, Snackbar.LENGTH_SHORT).show(); + } + } + } + } + + private void checkDuplicateAndImportTheme(CustomTheme customTheme, boolean checkDuplicate) { + new InsertCustomThemeAsyncTask(redditDataRoomDatabase, lightThemeSharedPreferences, + darkThemeSharedPreferences, amoledThemeSharedPreferences, customTheme, checkDuplicate, + new InsertCustomThemeAsyncTask.InsertCustomThemeAsyncTaskListener() { + @Override + public void success() { + Toast.makeText(CustomThemeListingActivity.this, R.string.import_theme_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new RecreateActivityEvent()); + } + + @Override + public void duplicate() { + new MaterialAlertDialogBuilder(CustomThemeListingActivity.this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.duplicate_theme_name_dialog_title) + .setMessage(getString(R.string.duplicate_theme_name_dialog_message, customTheme.name)) + .setPositiveButton(R.string.rename, (dialogInterface, i) + -> { + View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); + EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); + themeNameEditText.setText(customTheme.name); + themeNameEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(CustomThemeListingActivity.this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.edit_theme_name) + .setView(dialogView) + .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); + } + if (!themeNameEditText.getText().toString().equals("")) { + customTheme.name = themeNameEditText.getText().toString(); + } + checkDuplicateAndImportTheme(customTheme, true); + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(editTextDialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); + } + }) + .show(); + }) + .setNegativeButton(R.string.override, (dialogInterface, i) -> { + checkDuplicateAndImportTheme(customTheme, false); + }) + .show(); + } + }).execute(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java new file mode 100644 index 00000000..dbd40c31 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomThemePreviewActivity.java @@ -0,0 +1,473 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.os.Build; +import android.os.Bundle; +import android.util.TypedValue; +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 androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.chip.Chip; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.tabs.TabLayout; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeSettingsItem; +import ml.docilealligator.infinityforreddit.font.ContentFontStyle; +import ml.docilealligator.infinityforreddit.font.FontStyle; +import ml.docilealligator.infinityforreddit.font.TitleFontStyle; +import ml.docilealligator.infinityforreddit.fragments.ThemePreviewCommentsFragment; +import ml.docilealligator.infinityforreddit.fragments.ThemePreviewPostsFragment; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; + +public class CustomThemePreviewActivity extends AppCompatActivity { + + public static final String EXTRA_CUSTOM_THEME_SETTINGS_ITEMS = "ECTSI"; + + @BindView(R.id.coordinator_layout_theme_preview_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.view_pager_theme_preview_activity) + ViewPager viewPager; + @BindView(R.id.appbar_layout_theme_preview_activity) + AppBarLayout appBarLayout; + @BindView(R.id.collapsing_toolbar_layout_theme_preview_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.toolbar_linear_layout_theme_preview_activity) + LinearLayout linearLayout; + @BindView(R.id.subreddit_name_text_view_theme_preview_activity) + TextView subredditNameTextView; + @BindView(R.id.user_name_text_view_theme_preview_activity) + TextView usernameTextView; + @BindView(R.id.subscribe_subreddit_chip_theme_preview_activity) + Chip subscribeSubredditChip; + @BindView(R.id.primary_text_text_view_theme_preview_activity) + TextView primaryTextView; + @BindView(R.id.secondary_text_text_view_theme_preview_activity) + TextView secondaryTextView; + @BindView(R.id.toolbar) + Toolbar toolbar; + @BindView(R.id.tab_layout_theme_preview_activity) + TabLayout tabLayout; + @BindView(R.id.bottom_navigation_theme_preview_activity) + BottomAppBar bottomNavigationView; + @BindView(R.id.linear_layout_bottom_app_bar_theme_preview_activity) + LinearLayout linearLayoutBottomAppBar; + @BindView(R.id.subscriptions_bottom_app_bar_theme_preview_activity) + ImageView subscriptionsBottomAppBar; + @BindView(R.id.multi_reddit_bottom_app_bar_theme_preview_activity) + ImageView multiRedditBottomAppBar; + @BindView(R.id.message_bottom_app_bar_theme_preview_activity) + ImageView messageBottomAppBar; + @BindView(R.id.profile_bottom_app_bar_theme_preview_activity) + ImageView profileBottomAppBar; + @BindView(R.id.fab_theme_preview_activity) + FloatingActionButton fab; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + private ArrayList customThemeSettingsItems; + private CustomTheme customTheme; + private int expandedTabTextColor; + private int expandedTabBackgroundColor; + private int expandedTabIndicatorColor; + private int collapsedTabTextColor; + private int collapsedTabBackgroundColor; + private int collapsedTabIndicatorColor; + private int unsubscribedColor; + private int subscribedColor; + private int systemVisibilityToolbarExpanded = 0; + private int systemVisibilityToolbarCollapsed = 0; + private SlidrInterface mSlidrInterface; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ((Infinity) getApplication()).getAppComponent().inject(this); + + customThemeSettingsItems = getIntent().getParcelableArrayListExtra(EXTRA_CUSTOM_THEME_SETTINGS_ITEMS); + customTheme = CustomTheme.convertSettingsItemsToCustomTheme(customThemeSettingsItems, "ThemePreview"); + + boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; + int systemThemeType = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.THEME_KEY, "2")); + switch (systemThemeType) { + case 0: + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); + getTheme().applyStyle(R.style.Theme_Normal, true); + break; + case 1: + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { + getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); + } else { + getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); + } + break; + case 2: + if (systemDefault) { + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM); + } else { + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_AUTO_BATTERY); + } + if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) { + getTheme().applyStyle(R.style.Theme_Normal, true); + } else { + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { + getTheme().applyStyle(R.style.Theme_Normal_AmoledDark, true); + } else { + getTheme().applyStyle(R.style.Theme_Normal_NormalDark, true); + } + } + } + + boolean immersiveInterface = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && + mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true); + boolean changeStatusBarIconColor = false; + if (immersiveInterface) { + changeStatusBarIconColor = customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface; + } + boolean isLightStatusbar = customTheme.isLightStatusBar; + Window window = getWindow(); + View decorView = window.getDecorView(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + boolean isLightNavBar = customTheme.isLightNavBar; + if (isLightStatusbar) { + if (isLightNavBar) { + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + if (changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + } else { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + } + } else { + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + if (!changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + } + } else { + if (isLightNavBar) { + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + if (changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR; + } + } else { + if (changeStatusBarIconColor) { + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + } + } + decorView.setSystemUiVisibility(systemVisibilityToolbarExpanded); + window.setNavigationBarColor(customTheme.navBarColor); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (isLightStatusbar) { + decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); + systemVisibilityToolbarExpanded = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + systemVisibilityToolbarCollapsed = View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR; + } + } + + getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); + + setContentView(R.layout.activity_theme_preview); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (immersiveInterface) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + + Resources resources = getResources(); + int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); + if (navBarResourceId > 0) { + int navBarHeight = resources.getDimensionPixelSize(navBarResourceId); + if (navBarHeight > 0) { + CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); + params.bottomMargin = navBarHeight; + fab.setLayoutParams(params); + linearLayoutBottomAppBar.setPadding(0, + (int) (6 * getResources().getDisplayMetrics().density), 0, navBarHeight); + } + } + } + + if (changeStatusBarIconColor) { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { + if (state == State.COLLAPSED) { + decorView.setSystemUiVisibility(systemVisibilityToolbarCollapsed); + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } else if (state == State.EXPANDED) { + decorView.setSystemUiVisibility(systemVisibilityToolbarExpanded); + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } + } + }); + } else { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { + if (state == State.COLLAPSED) { + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } else if (state == State.EXPANDED) { + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } + } + }); + } + } else { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + if (state == State.EXPANDED) { + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } else if (state == State.COLLAPSED) { + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } + } + }); + } + + adjustToolbar(toolbar); + setSupportActionBar(toolbar); + + subscribeSubredditChip.setOnClickListener(view -> { + if (subscribeSubredditChip.getText().equals(getResources().getString(R.string.subscribe))) { + subscribeSubredditChip.setText(R.string.unsubscribe); + subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); + } else { + subscribeSubredditChip.setText(R.string.subscribe); + subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); + } + }); + + SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + viewPager.setAdapter(sectionsPagerAdapter); + viewPager.setOffscreenPageLimit(2); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + if (position == 0) { + unlockSwipeRightToGoBack(); + } else { + lockSwipeRightToGoBack(); + } + } + }); + tabLayout.setupWithViewPager(viewPager); + } + + private void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(customTheme.backgroundColor); + collapsingToolbarLayout.setContentScrimColor(customTheme.colorPrimary); + subscribeSubredditChip.setTextColor(customTheme.chipTextColor); + subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(customTheme.unsubscribed)); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + expandedTabTextColor = customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor; + expandedTabIndicatorColor = customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator; + expandedTabBackgroundColor = customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground; + collapsedTabTextColor = customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor; + collapsedTabIndicatorColor = customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator; + collapsedTabBackgroundColor = customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground; + linearLayout.setBackgroundColor(customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground); + subredditNameTextView.setTextColor(customTheme.subreddit); + usernameTextView.setTextColor(customTheme.username); + subscribeSubredditChip.setTextColor(customTheme.chipTextColor); + primaryTextView.setTextColor(customTheme.primaryTextColor); + secondaryTextView.setTextColor(customTheme.secondaryTextColor); + bottomNavigationView.setBackgroundTint(ColorStateList.valueOf(customTheme.bottomAppBarBackgroundColor)); + int bottomAppBarIconColor = customTheme.bottomAppBarIconColor; + subscriptionsBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + multiRedditBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + messageBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + profileBottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + applyTabLayoutTheme(tabLayout); + applyFABTheme(fab); + unsubscribedColor = customTheme.unsubscribed; + subscribedColor = customTheme.subscribed; + } + + protected void applyAppBarLayoutAndToolbarTheme(AppBarLayout appBarLayout, Toolbar toolbar) { + appBarLayout.setBackgroundColor(customTheme.colorPrimary); + toolbar.setTitleTextColor(customTheme.toolbarPrimaryTextAndIconColor); + toolbar.setSubtitleTextColor(customTheme.toolbarSecondaryTextColor); + if (toolbar.getNavigationIcon() != null) { + toolbar.getNavigationIcon().setColorFilter(customTheme.toolbarPrimaryTextAndIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + if (toolbar.getOverflowIcon() != null) { + toolbar.getOverflowIcon().setColorFilter(customTheme.toolbarPrimaryTextAndIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + } + + private void adjustToolbar(Toolbar toolbar) { + int statusBarResourceId = getResources().getIdentifier("status_bar_height", "dimen", "android"); + if (statusBarResourceId > 0) { + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams(); + int statusBarHeight = getResources().getDimensionPixelSize(statusBarResourceId); + params.topMargin = statusBarHeight; + toolbar.setLayoutParams(params); + TypedValue tv = new TypedValue(); + if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { + ((ViewGroup.MarginLayoutParams) linearLayout.getLayoutParams()).setMargins(0, + TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()) + statusBarHeight, 0, 0); + } + } + } + + protected void applyTabLayoutTheme(TabLayout tabLayout) { + int toolbarAndTabBackgroundColor = customTheme.colorPrimary; + tabLayout.setBackgroundColor(toolbarAndTabBackgroundColor); + tabLayout.setSelectedTabIndicatorColor(customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator); + tabLayout.setTabTextColors(customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor, + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor); + } + + protected void applyFABTheme(FloatingActionButton fab) { + fab.setBackgroundTintList(ColorStateList.valueOf(customTheme.colorPrimaryLightTheme)); + fab.setImageTintList(ColorStateList.valueOf(customTheme.fabIconColor)); + } + + public CustomTheme getCustomTheme() { + return customTheme; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + private void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + private void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + + private class SectionsPagerAdapter extends FragmentPagerAdapter { + private ThemePreviewPostsFragment themePreviewPostsFragment; + private ThemePreviewCommentsFragment themePreviewCommentsFragment; + + SectionsPagerAdapter(FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + } + + @NonNull + @Override + public Fragment getItem(int position) { + if (position == 0) { + return new ThemePreviewPostsFragment(); + } + return new ThemePreviewCommentsFragment(); + } + + @Override + public int getCount() { + return 2; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return "Posts"; + case 1: + return "Comments"; + } + return null; + } + + @NonNull + @Override + public Object instantiateItem(@NonNull ViewGroup container, int position) { + Fragment fragment = (Fragment) super.instantiateItem(container, position); + switch (position) { + case 0: + themePreviewPostsFragment = (ThemePreviewPostsFragment) fragment; + break; + case 1: + themePreviewCommentsFragment = (ThemePreviewCommentsFragment) fragment; + } + return fragment; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java new file mode 100644 index 00000000..a0b41cc2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/CustomizeThemeActivity.java @@ -0,0 +1,247 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.snackbar.Snackbar; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.CustomizeThemeRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCustomThemeAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.InsertCustomThemeAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeSettingsItem; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; + +public class CustomizeThemeActivity extends BaseActivity { + + public static final String EXTRA_THEME_TYPE = "ETT"; + public static final int EXTRA_LIGHT_THEME = CustomThemeSharedPreferencesUtils.LIGHT; + public static final int EXTRA_DARK_THEME = CustomThemeSharedPreferencesUtils.DARK; + public static final int EXTRA_AMOLED_THEME = CustomThemeSharedPreferencesUtils.AMOLED; + public static final String EXTRA_THEME_NAME = "ETN"; + public static final String EXTRA_IS_PREDEFIINED_THEME = "EIPT"; + public static final String EXTRA_CREATE_THEME = "ECT"; + private static final String CUSTOM_THEME_SETTINGS_ITEMS_STATE = "CTSIS"; + private static final String THEME_NAME_STATE = "TNS"; + + @BindView(R.id.coordinator_customize_theme_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_customize_theme_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_customize_theme_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_customize_theme_activity) + RecyclerView recyclerView; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + @Named("light_theme") + SharedPreferences lightThemeSharedPreferences; + @Inject + @Named("dark_theme") + SharedPreferences darkThemeSharedPreferences; + @Inject + @Named("amoled_theme") + SharedPreferences amoledThemeSharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + + private String themeName; + private boolean isPredefinedTheme; + private ArrayList customThemeSettingsItems; + private CustomizeThemeRecyclerViewAdapter adapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_customize_theme); + + ButterKnife.bind(this); + + applyCustomTheme(); + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (getIntent().getBooleanExtra(EXTRA_CREATE_THEME, false)) { + setTitle(R.string.customize_theme_activity_create_theme_label); + } + + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + + if (savedInstanceState != null) { + customThemeSettingsItems = savedInstanceState.getParcelableArrayList(CUSTOM_THEME_SETTINGS_ITEMS_STATE); + themeName = savedInstanceState.getString(THEME_NAME_STATE); + } + + int androidVersion = Build.VERSION.SDK_INT; + + if (customThemeSettingsItems == null) { + if (getIntent().hasExtra(EXTRA_THEME_TYPE)) { + int themeType = getIntent().getIntExtra(EXTRA_THEME_TYPE, EXTRA_LIGHT_THEME); + + new GetCustomThemeAsyncTask(redditDataRoomDatabase, themeType, customTheme -> { + if (customTheme == null) { + isPredefinedTheme = true; + switch (themeType) { + case EXTRA_DARK_THEME: + customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( + CustomizeThemeActivity.this, + CustomThemeWrapper.getIndigoDark(CustomizeThemeActivity.this), + androidVersion); + themeName = getString(R.string.theme_name_indigo_dark); + break; + case EXTRA_AMOLED_THEME: + customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( + CustomizeThemeActivity.this, + CustomThemeWrapper.getIndigoAmoled(CustomizeThemeActivity.this), + androidVersion); + themeName = getString(R.string.theme_name_indigo_amoled); + break; + default: + customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( + CustomizeThemeActivity.this, + CustomThemeWrapper.getIndigo(CustomizeThemeActivity.this), + androidVersion); + themeName = getString(R.string.theme_name_indigo); + } + } else { + customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( + CustomizeThemeActivity.this, customTheme, androidVersion); + themeName = customTheme.name; + } + + adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); + recyclerView.setAdapter(adapter); + adapter.setCustomThemeSettingsItem(customThemeSettingsItems); + }).execute(); + } else { + isPredefinedTheme = getIntent().getBooleanExtra(EXTRA_IS_PREDEFIINED_THEME, false); + themeName = getIntent().getStringExtra(EXTRA_THEME_NAME); + adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); + recyclerView.setAdapter(adapter); + if (isPredefinedTheme) { + customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( + CustomizeThemeActivity.this, + CustomThemeWrapper.getPredefinedCustomTheme(this, themeName), + androidVersion); + + adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); + recyclerView.setAdapter(adapter); + adapter.setCustomThemeSettingsItem(customThemeSettingsItems); + } else { + new GetCustomThemeAsyncTask(redditDataRoomDatabase, themeName, + customTheme -> { + customThemeSettingsItems = CustomThemeSettingsItem.convertCustomThemeToSettingsItem( + CustomizeThemeActivity.this, customTheme, androidVersion); + + adapter.setCustomThemeSettingsItem(customThemeSettingsItems); + }).execute(); + } + } + } else { + adapter = new CustomizeThemeRecyclerViewAdapter(this, themeName, isPredefinedTheme); + recyclerView.setAdapter(adapter); + adapter.setCustomThemeSettingsItem(customThemeSettingsItems); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.customize_theme_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_preview_customize_theme_activity: + Intent intent = new Intent(this, CustomThemePreviewActivity.class); + intent.putParcelableArrayListExtra(CustomThemePreviewActivity.EXTRA_CUSTOM_THEME_SETTINGS_ITEMS, customThemeSettingsItems); + startActivity(intent); + + return true; + case R.id.action_save_customize_theme_activity: + if (adapter != null) { + themeName = adapter.getThemeName(); + if (themeName.equals("")) { + Snackbar.make(coordinatorLayout, R.string.no_theme_name, Snackbar.LENGTH_SHORT).show(); + return true; + } + CustomTheme customTheme = CustomTheme.convertSettingsItemsToCustomTheme(customThemeSettingsItems, themeName); + new InsertCustomThemeAsyncTask(redditDataRoomDatabase, lightThemeSharedPreferences, + darkThemeSharedPreferences, amoledThemeSharedPreferences, customTheme, + false, () -> { + Toast.makeText(CustomizeThemeActivity.this, R.string.saved, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new RecreateActivityEvent()); + finish(); + }).execute(); + } + + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + if (adapter != null) { + outState.putParcelableArrayList(CUSTOM_THEME_SETTINGS_ITEMS_STATE, customThemeSettingsItems); + outState.putString(THEME_NAME_STATE, adapter.getThemeName()); + } + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return sharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return customThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java new file mode 100644 index 00000000..dd57f763 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditCommentActivity.java @@ -0,0 +1,244 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class EditCommentActivity extends BaseActivity { + + public static final String EXTRA_CONTENT = "EC"; + public static final String EXTRA_FULLNAME = "EF"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_POSITION = "EP"; + + static final String EXTRA_EDITED_COMMENT_CONTENT = "EECC"; + static final String EXTRA_EDITED_COMMENT_POSITION = "EECP"; + + @BindView(R.id.coordinator_layout_edit_comment_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_edit_comment_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_edit_comment_activity) + Toolbar toolbar; + @BindView(R.id.comment_edit_text_edit_comment_activity) + EditText contentEditText; + @BindView(R.id.markdown_bottom_bar_recycler_view_edit_comment_activity) + RecyclerView markdownBottomBarRecyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String mFullName; + private String mAccessToken; + private String mCommentContent; + private boolean isSubmitting = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_edit_comment); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); + mAccessToken = getIntent().getStringExtra(EXTRA_ACCESS_TOKEN); + mCommentContent = getIntent().getStringExtra(EXTRA_CONTENT); + contentEditText.setText(mCommentContent); + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); + }); + + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, + LinearLayoutManager.HORIZONTAL, false)); + markdownBottomBarRecyclerView.setAdapter(adapter); + + contentEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + contentEditText.setTextColor(mCustomThemeWrapper.getCommentColor()); + } + + @Override + protected void onPause() { + super.onPause(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.hideSoftInputFromWindow(contentEditText.getWindowToken(), 0); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.edit_comment_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_preview_edit_comment_activity) { + Intent intent = new Intent(this, FullMarkdownActivity.class); + intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); + startActivity(intent); + } else if (item.getItemId() == R.id.action_send_edit_comment_activity) { + if (!isSubmitting) { + isSubmitting = true; + + Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); + + String content = contentEditText.getText().toString(); + + Map params = new HashMap<>(); + params.put(APIUtils.THING_ID_KEY, mFullName); + params.put(APIUtils.TEXT_KEY, content); + + mOauthRetrofit.create(RedditAPI.class) + .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + isSubmitting = false; + if (response.isSuccessful()) { + Toast.makeText(EditCommentActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); + + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_EDITED_COMMENT_CONTENT, Utils.modifyMarkdown(content)); + returnIntent.putExtra(EXTRA_EDITED_COMMENT_POSITION, getIntent().getExtras().getInt(EXTRA_POSITION)); + setResult(RESULT_OK, returnIntent); + + finish(); + } else { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + }); + + } + return true; + } else if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } + return false; + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public void onBackPressed() { + if (isSubmitting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_comment_detail); + } else { + if (contentEditText.getText().toString().equals(mCommentContent)) { + finish(); + } else { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditMultiRedditActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditMultiRedditActivity.java new file mode 100644 index 00000000..ab3ddfd3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditMultiRedditActivity.java @@ -0,0 +1,271 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.snackbar.Snackbar; +import com.r0adkll.slidr.Slidr; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.multireddit.EditMultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.FetchMultiRedditInfo; +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.MultiRedditJSONModel; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class EditMultiRedditActivity extends BaseActivity { + public static final String EXTRA_MULTI_PATH = "EMP"; + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 1; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String MULTI_REDDIT_STATE = "MRS"; + private static final String MULTI_PATH_STATE = "MPS"; + @BindView(R.id.coordinator_layout_edit_multi_reddit_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_edit_multi_reddit_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_edit_multi_reddit_activity) + Toolbar toolbar; + @BindView(R.id.progress_bar_edit_multi_reddit_activity) + ProgressBar progressBar; + @BindView(R.id.linear_layout_edit_multi_reddit_activity) + LinearLayout linearLayout; + @BindView(R.id.multi_reddit_name_edit_text_edit_multi_reddit_activity) + EditText nameEditText; + @BindView(R.id.divider_1_edit_multi_reddit_activity) + View divider1; + @BindView(R.id.description_edit_text_edit_multi_reddit_activity) + EditText descriptionEditText; + @BindView(R.id.divider_2_edit_multi_reddit_activity) + View divider2; + @BindView(R.id.visibility_wrapper_linear_layout_edit_multi_reddit_activity) + LinearLayout visibilityLinearLayout; + @BindView(R.id.visibility_text_view_edit_multi_reddit_activity) + TextView visibilityTextView; + @BindView(R.id.visibility_switch_edit_multi_reddit_activity) + Switch visibilitySwitch; + @BindView(R.id.select_subreddit_text_view_edit_multi_reddit_activity) + TextView selectSubredditTextView; + @Inject + @Named("oauth") + Retrofit mRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private MultiReddit multiReddit; + private String multipath; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_edit_multi_reddit); + + ButterKnife.bind(this); + + 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); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + multiReddit = savedInstanceState.getParcelable(MULTI_REDDIT_STATE); + multipath = savedInstanceState.getString(MULTI_PATH_STATE); + + if (!mNullAccessToken && mAccountName == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + multipath = getIntent().getStringExtra(EXTRA_MULTI_PATH); + getCurrentAccountAndBindView(); + } + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + Toast.makeText(this, R.string.logged_out, Toast.LENGTH_SHORT).show(); + finish(); + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + bindView(); + } + }).execute(); + } + + private void bindView() { + if (multiReddit == null) { + FetchMultiRedditInfo.fetchMultiRedditInfo(mRetrofit, mAccessToken, multipath, new FetchMultiRedditInfo.FetchMultiRedditInfoListener() { + @Override + public void success(MultiReddit multiReddit) { + EditMultiRedditActivity.this.multiReddit = multiReddit; + progressBar.setVisibility(View.GONE); + linearLayout.setVisibility(View.VISIBLE); + nameEditText.setText(multiReddit.getDisplayName()); + descriptionEditText.setText(multiReddit.getDescription()); + visibilitySwitch.setChecked(!multiReddit.getVisibility().equals("public")); + } + + @Override + public void failed() { + Snackbar.make(coordinatorLayout, R.string.cannot_fetch_multireddit, Snackbar.LENGTH_SHORT).show(); + } + }); + } else { + progressBar.setVisibility(View.GONE); + linearLayout.setVisibility(View.VISIBLE); + nameEditText.setText(multiReddit.getDisplayName()); + descriptionEditText.setText(multiReddit.getDescription()); + visibilitySwitch.setChecked(!multiReddit.getVisibility().equals("public")); + } + + selectSubredditTextView.setOnClickListener(view -> { + Intent intent = new Intent(EditMultiRedditActivity.this, SelectedSubredditsActivity.class); + if (multiReddit.getSubreddits() != null) { + intent.putStringArrayListExtra(SelectedSubredditsActivity.EXTRA_SELECTED_SUBREDDITS, multiReddit.getSubreddits()); + } + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.edit_multi_reddit_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_save_edit_multi_reddit_activity: + if (mAccountName == null || mAccessToken == null) { + Snackbar.make(coordinatorLayout, R.string.something_went_wrong, Snackbar.LENGTH_SHORT).show(); + return true; + } + if (nameEditText.getText() == null || nameEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.no_multi_reddit_name, Snackbar.LENGTH_SHORT).show(); + return true; + } + + String jsonModel = new MultiRedditJSONModel(nameEditText.getText().toString(), descriptionEditText.getText().toString(), + visibilitySwitch.isChecked(), multiReddit.getSubreddits()).createJSONModel(); + EditMultiReddit.editMultiReddit(mRetrofit, mAccessToken, multiReddit.getPath(), + jsonModel, new EditMultiReddit.EditMultiRedditListener() { + @Override + public void success() { + finish(); + } + + @Override + public void failed() { + Snackbar.make(coordinatorLayout, R.string.edit_multi_reddit_failed, Snackbar.LENGTH_SHORT).show(); + } + }); + } + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE && resultCode == RESULT_OK) { + if (data != null) { + multiReddit.setSubreddits(data.getStringArrayListExtra( + SelectedSubredditsActivity.EXTRA_RETURN_SELECTED_SUBREDDITS)); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putParcelable(MULTI_REDDIT_STATE, multiReddit); + outState.putString(MULTI_PATH_STATE, multipath); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorAccent())); + int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + nameEditText.setTextColor(primaryTextColor); + nameEditText.setHintTextColor(secondaryTextColor); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + descriptionEditText.setTextColor(primaryTextColor); + descriptionEditText.setHintTextColor(secondaryTextColor); + visibilityTextView.setTextColor(primaryTextColor); + selectSubredditTextView.setTextColor(primaryTextColor); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java new file mode 100644 index 00000000..4be61c75 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/EditPostActivity.java @@ -0,0 +1,245 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class EditPostActivity extends BaseActivity { + + static final String EXTRA_TITLE = "ET"; + static final String EXTRA_CONTENT = "EC"; + static final String EXTRA_FULLNAME = "EF"; + static final String EXTRA_ACCESS_TOKEN = "EAT"; + + @BindView(R.id.coordinator_layout_edit_post_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_edit_post_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_edit_post_activity) + Toolbar toolbar; + @BindView(R.id.post_title_text_view_edit_post_activity) + TextView titleTextView; + @BindView(R.id.divider_edit_post_activity) + View divider; + @BindView(R.id.post_text_content_edit_text_edit_post_activity) + EditText contentEditText; + @BindView(R.id.markdown_bottom_bar_recycler_view_edit_post_activity) + RecyclerView markdownBottomBarRecyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String mFullName; + private String mAccessToken; + private String mPostContent; + private boolean isSubmitting = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_edit_post); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + 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); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mFullName = getIntent().getStringExtra(EXTRA_FULLNAME); + mAccessToken = getIntent().getStringExtra(EXTRA_ACCESS_TOKEN); + titleTextView.setText(getIntent().getStringExtra(EXTRA_TITLE)); + mPostContent = getIntent().getStringExtra(EXTRA_CONTENT); + contentEditText.setText(mPostContent); + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); + }); + + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, + LinearLayoutManager.HORIZONTAL, false)); + markdownBottomBarRecyclerView.setAdapter(adapter); + + contentEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + titleTextView.setTextColor(mCustomThemeWrapper.getPostTitleColor()); + divider.setBackgroundColor(mCustomThemeWrapper.getPostTitleColor()); + contentEditText.setTextColor(mCustomThemeWrapper.getPostContentColor()); + } + + @Override + protected void onPause() { + super.onPause(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.hideSoftInputFromWindow(contentEditText.getWindowToken(), 0); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.edit_post_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_preview_edit_post_activity) { + Intent intent = new Intent(this, FullMarkdownActivity.class); + intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); + startActivity(intent); + } else if (item.getItemId() == R.id.action_send_edit_post_activity) { + if (!isSubmitting) { + isSubmitting = true; + + Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); + + Map params = new HashMap<>(); + params.put(APIUtils.THING_ID_KEY, mFullName); + params.put(APIUtils.TEXT_KEY, contentEditText.getText().toString()); + + mOauthRetrofit.create(RedditAPI.class) + .editPostOrComment(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + isSubmitting = false; + Toast.makeText(EditPostActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); + Intent returnIntent = new Intent(); + setResult(RESULT_OK, returnIntent); + finish(); + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + }); + + } + return true; + } else if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } + return false; + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public void onBackPressed() { + if (isSubmitting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_edit_post_detail); + } else { + if (contentEditText.getText().toString().equals(mPostContent)) { + finish(); + } else { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } + } + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java new file mode 100644 index 00000000..ab1722f2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FetchRandomSubredditOrPostActivity.java @@ -0,0 +1,104 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.widget.RelativeLayout; +import android.widget.Toast; + +import com.airbnb.lottie.LottieAnimationView; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.RandomBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.FetchPost; +import ml.docilealligator.infinityforreddit.R; +import retrofit2.Retrofit; + +public class FetchRandomSubredditOrPostActivity extends BaseActivity { + + public static final String EXTRA_RANDOM_OPTION = "ERO"; + + @BindView(R.id.relative_layout_fetch_random_subreddit_or_post_activity) + RelativeLayout relativeLayout; + @BindView(R.id.lottie_animation_view_fetch_random_subreddit_or_post_activity) + LottieAnimationView lottieAnimationView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean isCanceled = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplicationContext()).getAppComponent().inject(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_fetch_random_subreddit_or_post); + + ButterKnife.bind(this); + + int option = getIntent().getIntExtra(EXTRA_RANDOM_OPTION, RandomBottomSheetFragment.RANDOM_SUBREDDIT); + + FetchPost.fetchRandomPost(mRetrofit, option == RandomBottomSheetFragment.RANDOM_NSFW_SUBREDDIT + || option == RandomBottomSheetFragment.RANDOM_NSFW_POST, new FetchPost.FetchRandomPostListener() { + @Override + public void fetchRandomPostSuccess(String postId, String subredditName) { + if (!isCanceled) { + switch (option) { + case RandomBottomSheetFragment.RANDOM_SUBREDDIT: + case RandomBottomSheetFragment.RANDOM_NSFW_SUBREDDIT: { + Intent intent = new Intent(FetchRandomSubredditOrPostActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); + startActivity(intent); + } + break; + case RandomBottomSheetFragment.RANDOM_POST: + case RandomBottomSheetFragment.RANDOM_NSFW_POST: + Intent intent = new Intent(FetchRandomSubredditOrPostActivity.this, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, postId); + startActivity(intent); + break; + } + + finish(); + } + } + + @Override + public void fetchRandomPostFailed() { + Toast.makeText(FetchRandomSubredditOrPostActivity.this, R.string.fetch_random_thing_failed, Toast.LENGTH_SHORT).show(); + finish(); + } + }); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + isCanceled = true; + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + relativeLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredThingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredThingActivity.java new file mode 100644 index 00000000..42a366e9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredThingActivity.java @@ -0,0 +1,461 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SearchPostSortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UserThingSortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class FilteredThingActivity extends BaseActivity implements SortTypeSelectionCallback, + PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { + + public static final String EXTRA_NAME = "ESN"; + public static final String EXTRA_QUERY = "EQ"; + public static final String EXTRA_FILTER = "EF"; + public static final String EXTRA_POST_TYPE = "EPT"; + public static final String EXTRA_USER_WHERE = "EUW"; + + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String FRAGMENT_OUT_STATE = "FOS"; + + @BindView(R.id.coordinator_layout_filtered_thing_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_filtered_posts_activity) + AppBarLayout appBarLayout; + @BindView(R.id.collapsing_toolbar_layout_filtered_posts_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.toolbar_filtered_posts_activity) + Toolbar toolbar; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean isInLazyMode = false; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String name; + private String userWhere; + private int postType; + private Fragment mFragment; + private Menu mMenu; + private AppBarLayout.LayoutParams params; + private SortTypeBottomSheetFragment bestSortTypeBottomSheetFragment; + private SortTypeBottomSheetFragment popularAndAllSortTypeBottomSheetFragment; + private SortTypeBottomSheetFragment subredditSortTypeBottomSheetFragment; + private SortTypeBottomSheetFragment multiRedditSortTypeBottomSheetFragment; + private UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment; + private SearchPostSortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment; + private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_filtered_thing); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); + + name = getIntent().getStringExtra(EXTRA_NAME); + postType = getIntent().getIntExtra(EXTRA_POST_TYPE, PostDataSource.TYPE_FRONT_PAGE); + int filter = getIntent().getIntExtra(EXTRA_FILTER, Post.TEXT_TYPE); + + if (postType == PostDataSource.TYPE_USER) { + userWhere = getIntent().getStringExtra(EXTRA_USER_WHERE); + if (userWhere != null && !PostDataSource.USER_WHERE_SUBMITTED.equals(userWhere) && mMenu != null) { + mMenu.findItem(R.id.action_sort_filtered_thing_activity).setVisible(false); + } + } + + if (savedInstanceState != null) { + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + + mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_filtered_posts_activity, mFragment).commit(); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(filter); + } else { + bindView(filter, false); + } + } else { + getCurrentAccountAndBindView(filter); + } + + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mFragment != null) { + return ((FragmentCommunicator) mFragment).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()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + private void getCurrentAccountAndBindView(int filter) { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + bindView(filter, true); + }).execute(); + } + + private void bindView(int filter, boolean initializeFragment) { + switch (postType) { + case PostDataSource.TYPE_FRONT_PAGE: + getSupportActionBar().setTitle(name); + + bestSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle bestBundle = new Bundle(); + bestBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, false); + bestSortTypeBottomSheetFragment.setArguments(bestBundle); + break; + case PostDataSource.TYPE_SEARCH: + getSupportActionBar().setTitle(R.string.search); + + searchPostSortTypeBottomSheetFragment = new SearchPostSortTypeBottomSheetFragment(); + Bundle searchBundle = new Bundle(); + searchPostSortTypeBottomSheetFragment.setArguments(searchBundle); + break; + case PostDataSource.TYPE_SUBREDDIT: + if (name.equals("popular") || name.equals("all")) { + getSupportActionBar().setTitle(name.substring(0, 1).toUpperCase() + name.substring(1)); + + popularAndAllSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle popularBundle = new Bundle(); + popularBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + popularAndAllSortTypeBottomSheetFragment.setArguments(popularBundle); + } else { + String subredditNamePrefixed = "r/" + name; + getSupportActionBar().setTitle(subredditNamePrefixed); + + subredditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle subredditSheetBundle = new Bundle(); + subredditSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + subredditSortTypeBottomSheetFragment.setArguments(subredditSheetBundle); + } + break; + case PostDataSource.TYPE_MULTI_REDDIT: + String multiRedditName; + if (name.endsWith("/")) { + multiRedditName = name.substring(0, name.length() - 1); + multiRedditName = multiRedditName.substring(multiRedditName.lastIndexOf("/") + 1); + } else { + multiRedditName = name.substring(name.lastIndexOf("/") + 1); + } + getSupportActionBar().setTitle(multiRedditName); + + multiRedditSortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle multiRedditBundle = new Bundle(); + multiRedditBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + multiRedditSortTypeBottomSheetFragment.setArguments(multiRedditBundle); + break; + case PostDataSource.TYPE_USER: + String usernamePrefixed = "u/" + name; + getSupportActionBar().setTitle(usernamePrefixed); + + userThingSortTypeBottomSheetFragment = new UserThingSortTypeBottomSheetFragment(); + break; + } + + sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); + + switch (filter) { + case Post.NSFW_TYPE: + toolbar.setSubtitle(R.string.nsfw); + break; + case Post.TEXT_TYPE: + toolbar.setSubtitle(R.string.text); + break; + case Post.LINK_TYPE: + case Post.NO_PREVIEW_LINK_TYPE: + toolbar.setSubtitle(R.string.link); + break; + case Post.IMAGE_TYPE: + toolbar.setSubtitle(R.string.image); + break; + case Post.VIDEO_TYPE: + toolbar.setSubtitle(R.string.video); + break; + case Post.GIF_TYPE: + toolbar.setSubtitle(R.string.gif); + break; + case Post.GALLERY_TYPE: + toolbar.setSubtitle(R.string.gallery); + } + + if (initializeFragment) { + mFragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, postType); + bundle.putInt(PostFragment.EXTRA_FILTER, filter); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + if (postType == PostDataSource.TYPE_USER) { + bundle.putString(PostFragment.EXTRA_USER_NAME, name); + bundle.putString(PostFragment.EXTRA_USER_WHERE, userWhere); + } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { + bundle.putString(PostFragment.EXTRA_NAME, name); + } else if (postType == PostDataSource.TYPE_SEARCH) { + bundle.putString(PostFragment.EXTRA_NAME, name); + bundle.putString(PostFragment.EXTRA_QUERY, getIntent().getStringExtra(EXTRA_QUERY)); + } + mFragment.setArguments(bundle); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_filtered_posts_activity, mFragment).commit(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.filtered_posts_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity); + if (isInLazyMode) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } else { + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } + + if (userWhere != null && !PostDataSource.USER_WHERE_SUBMITTED.equals(userWhere)) { + mMenu.findItem(R.id.action_sort_filtered_thing_activity).setVisible(false); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_sort_filtered_thing_activity: + switch (postType) { + case PostDataSource.TYPE_FRONT_PAGE: + bestSortTypeBottomSheetFragment.show(getSupportFragmentManager(), bestSortTypeBottomSheetFragment.getTag()); + break; + case PostDataSource.TYPE_SEARCH: + searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag()); + break; + case PostDataSource.TYPE_SUBREDDIT: + if (name.equals("popular") || name.equals("all")) { + popularAndAllSortTypeBottomSheetFragment.show(getSupportFragmentManager(), popularAndAllSortTypeBottomSheetFragment.getTag()); + } else { + subredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), subredditSortTypeBottomSheetFragment.getTag()); + } + break; + case PostDataSource.TYPE_MULTI_REDDIT: + multiRedditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), multiRedditSortTypeBottomSheetFragment.getTag()); + break; + case PostDataSource.TYPE_USER: + userThingSortTypeBottomSheetFragment.show(getSupportFragmentManager(), userThingSortTypeBottomSheetFragment.getTag()); + } + return true; + case R.id.action_refresh_filtered_thing_activity: + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity).setTitle(R.string.action_start_lazy_mode); + } + if (mFragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) mFragment).refresh(); + } + return true; + case R.id.action_lazy_mode_filtered_thing_activity: + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_filtered_thing_activity); + if (isInLazyMode) { + ((FragmentCommunicator) mFragment).stopLazyMode(); + isInLazyMode = false; + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } else { + if (((FragmentCommunicator) mFragment).startLazyMode()) { + isInLazyMode = true; + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } + } + return true; + case R.id.action_change_post_layout_filtered_post_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + public void sortTypeSelected(SortType sortType) { + ((PostFragment) mFragment).changeSortType(sortType); + } + + @Override + public void postLayoutSelected(int postLayout) { + if (mFragment != null) { + switch (postType) { + case PostDataSource.TYPE_FRONT_PAGE: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, postLayout).apply(); + break; + case PostDataSource.TYPE_SUBREDDIT: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + name, postLayout).apply(); + break; + case PostDataSource.TYPE_USER: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + name, postLayout).apply(); + break; + case PostDataSource.TYPE_SEARCH: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST, postLayout).apply(); + } + ((FragmentCommunicator) mFragment).changePostLayout(postLayout); + } + } + + @Override + public void sortTypeSelected(String sortType) { + Bundle bundle = new Bundle(); + bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); + sortTimeBottomSheetFragment.setArguments(bundle); + sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Override + public void onLongPress() { + if (mFragment != null) { + ((PostFragment) mFragment).goBackToTop(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java new file mode 100644 index 00000000..f874244c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FullMarkdownActivity.java @@ -0,0 +1,266 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.style.ClickableSpan; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.commonmark.ext.gfm.tables.TableBlock; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.recycler.MarkwonAdapter; +import io.noties.markwon.recycler.table.TableEntry; +import io.noties.markwon.recycler.table.TableEntryPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class FullMarkdownActivity extends BaseActivity { + + public static final String EXTRA_COMMENT_MARKDOWN = "ECM"; + public static final String EXTRA_IS_NSFW = "EIN"; + + @BindView(R.id.coordinator_layout_comment_full_markdown_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_comment_full_markdown_activity) + AppBarLayout appBarLayout; + @BindView(R.id.collapsing_toolbar_layout_comment_full_markdown_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.toolbar_comment_full_markdown_activity) + Toolbar toolbar; + @BindView(R.id.content_markdown_view_comment_full_markdown_activity) + RecyclerView markdownRecyclerView; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private SlidrInterface mSlidrInterface; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_comment_full_markdown); + + ButterKnife.bind(this); + + applyCustomTheme(); + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + setTitle(" "); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + markdownRecyclerView.setPadding(0, 0, 0, getNavBarHeight()); + } + } + + String commentMarkdown = getIntent().getStringExtra(EXTRA_COMMENT_MARKDOWN); + boolean isNsfw = getIntent().getBooleanExtra(EXTRA_IS_NSFW, false); + int markdownColor = mCustomThemeWrapper.getCommentColor(); + int spoilerBackgroundColor = markdownColor | 0xFF000000; + int linkColor = mCustomThemeWrapper.getLinkColor(); + Markwon markwon = Markwon.builder(this) + .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + StringBuilder markdownStringBuilder = new StringBuilder(markdown); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + while (matcher.find()) { + markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); + } + return super.processMarkdown(markdownStringBuilder.toString()); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + textView.setHighlightColor(Color.TRANSPARENT); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + ClickableSpan clickableSpan = new ClickableSpan() { + private boolean isShowing = false; + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + ds.setColor(markdownColor); + } else { + ds.bgColor = spoilerBackgroundColor; + ds.setColor(markdownColor); + } + ds.setUnderlineText(false); + } + + @Override + public void onClick(@NonNull View view) { + isShowing = !isShowing; + view.invalidate(); + } + }; + markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcher.end() - 4; + } + if (find) { + textView.setText(markdownStringBuilder); + } + } + + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + textView.setTextColor(markdownColor); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(FullMarkdownActivity.this, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, isNsfw); + startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .usePlugin(TableEntryPlugin.create(this)) + .build(); + + MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) + .include(TableBlock.class, TableEntry.create(builder -> builder + .tableLayout(R.layout.adapter_table_block, R.id.table_layout) + .textLayoutIsRoot(R.layout.view_table_entry_cell))) + .build(); + LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(this, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { + @Override + public void onScrolledLeft() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + @Override + public void onScrolledRight() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + }); + markdownRecyclerView.setLayoutManager(linearLayoutManager); + markdownRecyclerView.setAdapter(markwonAdapter); + markwonAdapter.setMarkdown(markwon, commentMarkdown); + markwonAdapter.notifyDataSetChanged(); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java new file mode 100644 index 00000000..50e4eb8e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/GiveAwardActivity.java @@ -0,0 +1,210 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.switchmaterial.SwitchMaterial; +import com.r0adkll.slidr.Slidr; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.AwardRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.award.GiveAward; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class GiveAwardActivity extends BaseActivity { + + public static final String EXTRA_THING_FULLNAME = "ETF"; + public static final String EXTRA_ITEM_POSITION = "EIP"; + public static final String EXTRA_RETURN_ITEM_POSITION = "ERIP"; + public static final String EXTRA_RETURN_NEW_AWARDS = "ERNA"; + public static final String EXTRA_RETURN_NEW_AWARDS_COUNT = "ERNAC"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + + @BindView(R.id.coordinator_layout_give_award_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_give_award_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_give_award_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_give_award_activity) + RecyclerView recyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String thingFullname; + private int itemPosition; + private boolean mNullAccessToken = false; + private String mAccessToken; + private AwardRecyclerViewAdapter adapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_give_award); + + ButterKnife.bind(this); + + applyCustomTheme(); + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + } + + thingFullname = getIntent().getStringExtra(EXTRA_THING_FULLNAME); + itemPosition = getIntent().getIntExtra(EXTRA_ITEM_POSITION, 0); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + getCurrentAccountAndBindView(); + } + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + bindView(); + }).execute(); + } + + private void bindView() { + adapter = new AwardRecyclerViewAdapter(Glide.with(this), mCustomThemeWrapper, award -> { + LayoutInflater inflater = getLayoutInflater(); + View layout = inflater.inflate(R.layout.dialog_give_award, null); + SwitchMaterial switchMaterial = layout.findViewById(R.id.switch_material_give_award_dialog); + new MaterialAlertDialogBuilder(this) + .setTitle(R.string.give_award_dialog_title) + .setView(layout) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> { + boolean isAnonymous = switchMaterial.isChecked(); + + GiveAward.giveAwardV2(mOauthRetrofit, mAccessToken, thingFullname, award.getId(), + isAnonymous, new GiveAward.GiveAwardListener() { + @Override + public void success(String awardsHTML, int awardCount) { + Intent data = new Intent(); + data.putExtra(EXTRA_RETURN_ITEM_POSITION, itemPosition); + data.putExtra(EXTRA_RETURN_NEW_AWARDS, awardsHTML); + data.putExtra(EXTRA_RETURN_NEW_AWARDS_COUNT, awardCount); + setResult(RESULT_OK, data); + finish(); + } + + @Override + public void failed(int code, String message) { + View layout = inflater.inflate(R.layout.copy_text_material_dialog, null); + TextView textView = layout.findViewById(R.id.text_view_copy_text_material_dialog); + String text = getString(R.string.give_award_error_message, code, message == null ? "" : message); + textView.setText(text); + new MaterialAlertDialogBuilder(GiveAwardActivity.this, R.style.CopyTextMaterialAlertDialogTheme) + .setTitle(R.string.give_award_failed) + .setView(layout) + .setPositiveButton(R.string.copy_all, (dialogInterface, i) -> { + ClipboardManager clipboard = (ClipboardManager) GiveAwardActivity.this.getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + ClipData clip = ClipData.newPlainText("simple text", text); + clipboard.setPrimaryClip(clip); + Toast.makeText(GiveAwardActivity.this, R.string.copy_success, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(GiveAwardActivity.this, R.string.copy_failed, Toast.LENGTH_SHORT).show(); + } + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } + }); + }) + .setNegativeButton(R.string.no, null) + .show(); + }); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(adapter); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java new file mode 100644 index 00000000..f378e1c0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/InboxActivity.java @@ -0,0 +1,353 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Toast; + +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.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.tabs.TabLayout; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.InboxFragment; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.FetchMessage; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class InboxActivity extends BaseActivity implements ActivityToolbarInterface { + + public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; + public static final String EXTRA_VIEW_MESSAGE = "EVM"; + + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; + + @BindView(R.id.coordinator_layout_inbox_activity) + CoordinatorLayout mCoordinatorLayout; + @BindView(R.id.collapsing_toolbar_layout_inbox_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.appbar_layout_inbox_activity) + AppBarLayout mAppBarLayout; + @BindView(R.id.toolbar_inbox_activity) + Toolbar mToolbar; + @BindView(R.id.tab_layout_inbox_activity) + TabLayout tabLayout; + @BindView(R.id.view_pager_inbox_activity) + ViewPager viewPager; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private SlidrInterface mSlidrInterface; + private SectionsPagerAdapter sectionsPagerAdapter; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mNewAccountName; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_inbox); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(mAppBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + mCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(mToolbar); + } + } + + mToolbar.setTitle(R.string.inbox); + setSupportActionBar(mToolbar); + setToolbarGoToTop(mToolbar); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndFetchMessage(savedInstanceState); + } else { + bindView(savedInstanceState); + } + } else { + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); + getCurrentAccountAndFetchMessage(savedInstanceState); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); + applyTabLayoutTheme(tabLayout); + } + + private void getCurrentAccountAndFetchMessage(Bundle savedInstanceState) { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (mNewAccountName != null) { + if (account == null || !account.getUsername().equals(mNewAccountName)) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { + EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); + Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); + + mNewAccountName = null; + if (newAccount == null) { + mNullAccessToken = true; + } else { + mAccessToken = newAccount.getAccessToken(); + } + + bindView(savedInstanceState); + }).execute(); + } else { + mAccessToken = account.getAccessToken(); + bindView(savedInstanceState); + } + } else { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + + bindView(savedInstanceState); + } + }).execute(); + } + + private void bindView(Bundle savedInstanceState) { + sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + if (position == 0) { + unlockSwipeRightToGoBack(); + } else { + lockSwipeRightToGoBack(); + } + } + }); + viewPager.setAdapter(sectionsPagerAdapter); + viewPager.setOffscreenPageLimit(2); + tabLayout.setupWithViewPager(viewPager); + if (savedInstanceState == null && getIntent().getBooleanExtra(EXTRA_VIEW_MESSAGE, false)) { + viewPager.setCurrentItem(1); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.inbox_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_refresh_inbox_activity) { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.refresh(); + } + return true; + } else if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + if (!getClass().getName().equals(event.excludeActivityClassName)) { + finish(); + } + } + + @Override + public void onLongPress() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.goBackToTop(); + } + } + + private void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + private void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + + private class SectionsPagerAdapter extends FragmentPagerAdapter { + private InboxFragment tab1; + private InboxFragment tab2; + + public SectionsPagerAdapter(@NonNull FragmentManager fm) { + super(fm, FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + } + + @NonNull + @Override + public Fragment getItem(int position) { + if (position == 0) { + InboxFragment fragment = new InboxFragment(); + Bundle bundle = new Bundle(); + bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); + fragment.setArguments(bundle); + return fragment; + } else { + InboxFragment fragment = new InboxFragment(); + Bundle bundle = new Bundle(); + bundle.putString(InboxFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(InboxFragment.EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_MESSAGES); + fragment.setArguments(bundle); + return fragment; + } + } + + @Override + public int getCount() { + return 2; + } + + @Nullable + @Override + public CharSequence getPageTitle(int position) { + if (position == 0) { + return getString(R.string.notifications); + } + + return getString(R.string.messages); + } + + @NonNull + @Override + public Object instantiateItem(@NonNull ViewGroup container, int position) { + Fragment fragment = (Fragment) super.instantiateItem(container, position); + if (position == 0) { + tab1 = (InboxFragment) fragment; + } else if (position == 1) { + tab2 = (InboxFragment) fragment; + } + + return fragment; + } + + void refresh() { + if (viewPager.getCurrentItem() == 0) { + if (tab1 != null) { + tab1.refresh(); + } + } else if (viewPager.getCurrentItem() == 1 && tab2 != null) { + tab2.refresh(); + } + } + + void goBackToTop() { + if (viewPager.getCurrentItem() == 0) { + if (tab1 != null) { + tab1.goBackToTop(); + } + } else if (viewPager.getCurrentItem() == 1) { + if (tab2 != null) { + tab2.goBackToTop(); + } + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java new file mode 100644 index 00000000..a01a69ec --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LinkResolverActivity.java @@ -0,0 +1,327 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.net.Uri; +import android.os.Bundle; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.browser.customtabs.CustomTabsIntent; + +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +import static androidx.browser.customtabs.CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION; + +public class LinkResolverActivity extends AppCompatActivity { + + public static final String EXTRA_MESSAGE_FULLNAME = "ENF"; + public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; + public static final String EXTRA_IS_NSFW = "EIN"; + + private static final String POST_PATTERN = "/r/\\w+/comments/\\w+/?\\w+/?"; + private static final String COMMENT_PATTERN = "/(r|u|U|user)/\\w+/comments/\\w+/?\\w+/\\w+/?"; + private static final String SUBREDDIT_PATTERN = "/[rR]/[\\w-]+/?"; + private static final String USER_PATTERN = "/(u|U|user)/[\\w-]+/?"; + private static final String SIDEBAR_PATTERN = "/[rR]/\\w+/about/sidebar"; + private static final String MULTIREDDIT_PATTERN = "/user/\\w+/m/\\w+/?"; + private static final String MULTIREDDIT_PATTERN_2 = "/[rR]/(\\w+\\+?)+/?"; + private static final String REDD_IT_POST_PATTERN = "/\\w+/?"; + private static final String GFYCAT_PATTERN = "(/ifr)?/[\\w-]+$"; + private static final String REDGIFS_PATTERN = "/watch/[\\w-]+$"; + private static final String IMGUR_GALLERY_PATTERN = "/gallery/\\w+/?"; + private static final String IMGUR_ALBUM_PATTERN = "/(album|a)/\\w+/?"; + private static final String IMGUR_IMAGE_PATTERN = "/\\w+/?"; + + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + + public static Uri getRedditUriByPath(String path) { + return Uri.parse("https://www.reddit.com" + path); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ((Infinity) getApplication()).getAppComponent().inject(this); + + Uri uri = getIntent().getData(); + handleUri(uri); + } + + private void handleUri(Uri uri) { + if (uri == null) { + Toast.makeText(this, R.string.no_link_available, Toast.LENGTH_SHORT).show(); + finish(); + } else { + String path = uri.getPath(); + if (path == null) { + deepLinkError(uri); + } else { + if (path.endsWith("/")) { + path = path.substring(0, path.length() - 1); + } + + if (path.endsWith("jpg") || path.endsWith("png")) { + Intent intent = new Intent(this, ViewImageOrGifActivity.class); + String url = uri.toString(); + String fileName = url.substring(url.lastIndexOf('/') + 1); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, url); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, fileName); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, fileName); + startActivity(intent); + } else if (path.endsWith("gif")) { + Intent intent = new Intent(this, ViewImageOrGifActivity.class); + String url = uri.toString(); + String fileName = url.substring(url.lastIndexOf('/') + 1); + intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, url); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, fileName); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, fileName); + startActivity(intent); + } else if (path.endsWith("mp4")) { + Intent intent = new Intent(this, ViewVideoActivity.class); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_DIRECT); + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, getIntent().getBooleanExtra(EXTRA_IS_NSFW, false)); + intent.setData(uri); + startActivity(intent); + } else { + String messageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); + String newAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); + + String authority = uri.getAuthority(); + List segments = uri.getPathSegments(); + + if (authority != null) { + if (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app")) { + if (authority.equals("reddit.app.link") && path.isEmpty()) { + String redirect = uri.getQueryParameter("$og_redirect"); + handleUri(Uri.parse(redirect)); + } else if (path.isEmpty()) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + } else if (path.matches(POST_PATTERN)) { + int commentsIndex = segments.lastIndexOf("comments"); + if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) { + Intent intent = new Intent(this, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); + intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); + intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); + startActivity(intent); + } else { + deepLinkError(uri); + } + } else if (path.matches(COMMENT_PATTERN)) { + int commentsIndex = segments.lastIndexOf("comments"); + if (commentsIndex >= 0 && commentsIndex < segments.size() - 1) { + Intent intent = new Intent(this, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, segments.get(commentsIndex + 1)); + intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, segments.get(segments.size() - 1)); + intent.putExtra(ViewPostDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); + intent.putExtra(ViewPostDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); + startActivity(intent); + } else { + deepLinkError(uri); + } + } else if (path.matches(SUBREDDIT_PATTERN)) { + String subredditName = path.substring(3); + if (subredditName.equals("popular") || subredditName.equals("all")) { + Intent intent = new Intent(this, MainActivity.class); + intent.putExtra(MainActivity.EXTRA_POST_TYPE, subredditName); + intent.putExtra(MainActivity.EXTRA_MESSSAGE_FULLNAME, messageFullname); + intent.putExtra(MainActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); + startActivity(intent); + } else { + Intent intent = new Intent(this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3)); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); + startActivity(intent); + } + } else if (path.matches(USER_PATTERN)) { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, segments.get(1)); + intent.putExtra(ViewUserDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); + intent.putExtra(ViewUserDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); + startActivity(intent); + } else if (path.matches(SIDEBAR_PATTERN)) { + Intent intent = new Intent(this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, path.substring(3, path.length() - 14)); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_VIEW_SIDEBAR, true); + startActivity(intent); + } else if (path.matches(MULTIREDDIT_PATTERN)) { + Intent intent = new Intent(this, ViewMultiRedditDetailActivity.class); + intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_PATH, path); + startActivity(intent); + } else if (path.matches(MULTIREDDIT_PATTERN_2)) { + String subredditName = path.substring(3); + Intent intent = new Intent(this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_MESSAGE_FULLNAME, messageFullname); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_NEW_ACCOUNT_NAME, newAccountName); + startActivity(intent); + } else if (authority.equals("redd.it") && path.matches(REDD_IT_POST_PATTERN)) { + Intent intent = new Intent(this, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, path.substring(1)); + startActivity(intent); + } else { + deepLinkError(uri); + } + } else if (authority.contains("gfycat.com")) { + if (path.matches(GFYCAT_PATTERN)) { + Intent intent = new Intent(this, ViewVideoActivity.class); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, path.substring(path.lastIndexOf("/") + 1)); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, getIntent().getBooleanExtra(EXTRA_IS_NSFW, false)); + startActivity(intent); + } else { + deepLinkError(uri); + } + } else if (authority.contains("redgifs.com")) { + if (path.matches(REDGIFS_PATTERN)) { + Intent intent = new Intent(this, ViewVideoActivity.class); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, path.substring(path.lastIndexOf("/") + 1)); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, true); + startActivity(intent); + } else { + deepLinkError(uri); + } + } else if (authority.contains("imgur.com")) { + if (path.matches(IMGUR_GALLERY_PATTERN)) { + Intent intent = new Intent(this, ViewImgurMediaActivity.class); + intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_TYPE, ViewImgurMediaActivity.IMGUR_TYPE_GALLERY); + intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_ID, segments.get(1)); + startActivity(intent); + } else if (path.matches(IMGUR_ALBUM_PATTERN)) { + Intent intent = new Intent(this, ViewImgurMediaActivity.class); + intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_TYPE, ViewImgurMediaActivity.IMGUR_TYPE_ALBUM); + intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_ID, segments.get(1)); + startActivity(intent); + } else if (path.matches(IMGUR_IMAGE_PATTERN)) { + Intent intent = new Intent(this, ViewImgurMediaActivity.class); + intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_TYPE, ViewImgurMediaActivity.IMGUR_TYPE_IMAGE); + intent.putExtra(ViewImgurMediaActivity.EXTRA_IMGUR_ID, path.substring(1)); + startActivity(intent); + } else if (path.endsWith("gifv")) { + String url = uri.toString(); + url = url.substring(0, url.length() - 5) + ".mp4"; + Intent intent = new Intent(this, ViewVideoActivity.class); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_DIRECT); + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, getIntent().getBooleanExtra(EXTRA_IS_NSFW, false)); + intent.setData(Uri.parse(url)); + startActivity(intent); + } else { + deepLinkError(uri); + } + } else { + deepLinkError(uri); + } + } else { + deepLinkError(uri); + } + } + } + + finish(); + } + } + + private void deepLinkError(Uri uri) { + PackageManager pm = getPackageManager(); + + String authority = uri.getAuthority(); + if(authority != null && (authority.contains("reddit.com") || authority.contains("redd.it") || authority.contains("reddit.app.link"))) { + openInCustomTabs(uri, pm, false); + return; + } + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.OPEN_LINK_IN_APP, false)) { + openInCustomTabs(uri, pm, true); + } else { + openInBrowser(uri, pm, true); + } + } + + private void openInBrowser(Uri uri, PackageManager pm, boolean handleError) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(uri); + + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + if (handleError) { + openInCustomTabs(uri, pm, false); + } else { + Toast.makeText(this, R.string.no_browser_found, Toast.LENGTH_SHORT).show(); + } + } + } + + private ArrayList getCustomTabsPackages(PackageManager pm) { + // Get default VIEW intent handler. + Intent activityIntent = new Intent() + .setAction(Intent.ACTION_VIEW) + .addCategory(Intent.CATEGORY_BROWSABLE) + .setData(Uri.fromParts("http", "", null)); + + // Get all apps that can handle VIEW intents. + List resolvedActivityList = pm.queryIntentActivities(activityIntent, 0); + ArrayList packagesSupportingCustomTabs = new ArrayList<>(); + for (ResolveInfo info : resolvedActivityList) { + Intent serviceIntent = new Intent(); + serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION); + serviceIntent.setPackage(info.activityInfo.packageName); + // Check if this package also resolves the Custom Tabs service. + if (pm.resolveService(serviceIntent, 0) != null) { + packagesSupportingCustomTabs.add(info); + } + } + return packagesSupportingCustomTabs; + } + + private void openInCustomTabs(Uri uri, PackageManager pm, boolean handleError) { + ArrayList resolveInfos = getCustomTabsPackages(pm); + if (!resolveInfos.isEmpty()) { + CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(); + // add share action to menu list + builder.addDefaultShareMenuItem(); + builder.setToolbarColor(mCustomThemeWrapper.getColorPrimary()); + CustomTabsIntent customTabsIntent = builder.build(); + customTabsIntent.intent.setPackage(resolveInfos.get(0).activityInfo.packageName); + if (uri.getScheme() == null) { + uri = Uri.parse("http://" + uri.toString()); + } + try { + customTabsIntent.launchUrl(this, uri); + } catch (ActivityNotFoundException e) { + if (handleError) { + openInBrowser(uri, pm, false); + } else { + Toast.makeText(this, R.string.no_browser_found, Toast.LENGTH_SHORT).show(); + } + } + } else { + if (handleError) { + openInBrowser(uri, pm, false); + } else { + Toast.makeText(this, R.string.no_browser_found, Toast.LENGTH_SHORT).show(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java new file mode 100644 index 00000000..50866ce4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/LoginActivity.java @@ -0,0 +1,251 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.util.Log; +import android.view.InflateException; +import android.view.MenuItem; +import android.webkit.CookieManager; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +import com.google.android.material.appbar.AppBarLayout; +import com.r0adkll.slidr.Slidr; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.asynctasks.ParseAndInsertNewAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FetchMyInfo; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class LoginActivity extends BaseActivity { + + @BindView(R.id.coordinator_layout_login_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_login_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_login_activity) + Toolbar toolbar; + @BindView(R.id.two_fa_infO_text_view_login_activity) + TextView twoFAInfoTextView; + @BindView(R.id.webview_login_activity) + WebView webView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String authCode; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + try { + setContentView(R.layout.activity_login); + } catch (InflateException ie) { + Log.e("LoginActivity", "Failed to inflate LoginActivity: " + ie.getMessage()); + Toast.makeText(LoginActivity.this, R.string.no_system_webview_error, Toast.LENGTH_SHORT).show(); + finish(); + return; + } + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + setSupportActionBar(toolbar); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + webView.getSettings().setJavaScriptEnabled(true); + + Uri baseUri = Uri.parse(APIUtils.OAUTH_URL); + Uri.Builder uriBuilder = baseUri.buildUpon(); + uriBuilder.appendQueryParameter(APIUtils.CLIENT_ID_KEY, APIUtils.CLIENT_ID); + uriBuilder.appendQueryParameter(APIUtils.RESPONSE_TYPE_KEY, APIUtils.RESPONSE_TYPE); + uriBuilder.appendQueryParameter(APIUtils.STATE_KEY, APIUtils.STATE); + uriBuilder.appendQueryParameter(APIUtils.REDIRECT_URI_KEY, APIUtils.REDIRECT_URI); + uriBuilder.appendQueryParameter(APIUtils.DURATION_KEY, APIUtils.DURATION); + uriBuilder.appendQueryParameter(APIUtils.SCOPE_KEY, APIUtils.SCOPE); + + String url = uriBuilder.toString(); + + CookieManager.getInstance().removeAllCookies(aBoolean -> { + }); + + webView.loadUrl(url); + webView.setWebViewClient(new WebViewClient() { + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + if (url.contains("&code=") || url.contains("?code=")) { + Uri uri = Uri.parse(url); + String state = uri.getQueryParameter("state"); + if (state.equals(APIUtils.STATE)) { + authCode = uri.getQueryParameter("code"); + + Map params = new HashMap<>(); + params.put(APIUtils.GRANT_TYPE_KEY, "authorization_code"); + params.put("code", authCode); + params.put("redirect_uri", APIUtils.REDIRECT_URI); + + RedditAPI api = mRetrofit.create(RedditAPI.class); + Call accessTokenCall = api.getAccessToken(APIUtils.getHttpBasicAuthHeader(), params); + accessTokenCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + try { + String accountResponse = response.body(); + if (accountResponse == null) { + //Handle error + return; + } + + JSONObject responseJSON = new JSONObject(accountResponse); + String accessToken = responseJSON.getString(APIUtils.ACCESS_TOKEN_KEY); + String refreshToken = responseJSON.getString(APIUtils.REFRESH_TOKEN_KEY); + + FetchMyInfo.fetchAccountInfo(mOauthRetrofit, mRedditDataRoomDatabase, + accessToken, new FetchMyInfo.FetchMyInfoListener() { + @Override + public void onFetchMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) { + new ParseAndInsertNewAccountAsyncTask(name, accessToken, refreshToken, profileImageUrl, bannerImageUrl, + karma, authCode, mRedditDataRoomDatabase.accountDao(), + () -> { + Intent resultIntent = new Intent(); + setResult(Activity.RESULT_OK, resultIntent); + finish(); + }).execute(); + } + + @Override + public void onFetchMyInfoFailed(boolean parseFailed) { + if (parseFailed) { + Toast.makeText(LoginActivity.this, R.string.parse_user_info_error, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(LoginActivity.this, R.string.cannot_fetch_user_info, Toast.LENGTH_SHORT).show(); + } + + finish(); + } + }); + } catch (JSONException e) { + e.printStackTrace(); + Toast.makeText(LoginActivity.this, R.string.parse_json_response_error, Toast.LENGTH_SHORT).show(); + finish(); + } + } else { + Toast.makeText(LoginActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show(); + finish(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + Toast.makeText(LoginActivity.this, R.string.retrieve_token_error, Toast.LENGTH_SHORT).show(); + finish(); + } + }); + } else { + Toast.makeText(LoginActivity.this, R.string.something_went_wrong, Toast.LENGTH_SHORT).show(); + finish(); + } + + } else if (url.contains("error=access_denied")) { + Toast.makeText(LoginActivity.this, R.string.access_denied, Toast.LENGTH_SHORT).show(); + finish(); + } else { + view.loadUrl(url); + } + + return true; + } + + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + super.onPageStarted(view, url, favicon); + } + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + } + }); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + twoFAInfoTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); + Drawable infoDrawable = Utils.getTintedDrawable(this, R.drawable.ic_info_preference_24dp, mCustomThemeWrapper.getPrimaryIconColor()); + twoFAInfoTextView.setCompoundDrawablesWithIntrinsicBounds(infoDrawable, null, null, null); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java new file mode 100644 index 00000000..15eb3be1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java @@ -0,0 +1,1528 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.os.Build; +import android.os.Bundle; +import android.view.Gravity; +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 android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.view.GravityCompat; +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; +import androidx.work.Constraints; +import androidx.work.ExistingPeriodicWorkPolicy; +import androidx.work.NetworkType; +import androidx.work.PeriodicWorkRequest; +import androidx.work.WorkManager; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.navigation.NavigationView; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.account.AccountViewModel; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.adapters.NavigationDrawerRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.InsertSubscribedThingsAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SwitchToAnonymousAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FABMoreOptionsBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.RandomBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.ChangeConfirmToExitEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDisableSwipingBetweenTabsEvent; +import ml.docilealligator.infinityforreddit.events.ChangeLockBottomAppBarEvent; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.ChangeRequireAuthToAccountSectionEvent; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.FetchMyInfo; +import ml.docilealligator.infinityforreddit.FetchSubscribedThing; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.PullNotificationWorker; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditViewModel; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; + +public class MainActivity extends BaseActivity implements SortTypeSelectionCallback, + PostTypeBottomSheetFragment.PostTypeSelectionCallback, PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, + ActivityToolbarInterface, FABMoreOptionsBottomSheetFragment.FABOptionSelectionCallback, RandomBottomSheetFragment.RandomOptionSelectionCallback { + + static final String EXTRA_POST_TYPE = "EPT"; + static final String EXTRA_MESSSAGE_FULLNAME = "ENF"; + static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; + + private static final String FETCH_USER_INFO_STATE = "FUIS"; + private static final String FETCH_SUBSCRIPTIONS_STATE = "FSS"; + private static final String DRAWER_ON_ACCOUNT_SWITCH_STATE = "DOASS"; + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String ACCOUNT_PROFILE_IMAGE_URL_STATE = "APIUS"; + private static final String ACCOUNT_BANNER_IMAGE_URL_STATE = "ABIUS"; + private static final String ACCOUNT_KARMA_STATE = "AKS"; + private static final String MESSAGE_FULLNAME_STATE = "MFS"; + private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; + + private static final int LOGIN_ACTIVITY_REQUEST_CODE = 0; + + @BindView(R.id.drawer_layout) + DrawerLayout drawer; + @BindView(R.id.navigation_view_main_activity) + NavigationView navigationView; + @BindView(R.id.coordinator_layout_main_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_main_activity) + AppBarLayout appBarLayout; + @BindView(R.id.view_pager_main_activity) + ViewPager2 viewPager2; + @BindView(R.id.collapsing_toolbar_layout_main_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.toolbar) + Toolbar toolbar; + @BindView(R.id.nav_drawer_recycler_view_main_activity) + RecyclerView navDrawerRecyclerView; + @BindView(R.id.tab_layout_main_activity) + TabLayout tabLayout; + @BindView(R.id.bottom_app_bar_main_activity) + BottomAppBar bottomAppBar; + @BindView(R.id.linear_layout_bottom_app_bar_main_activity) + LinearLayout linearLayoutBottomAppBar; + @BindView(R.id.option_1_bottom_app_bar_main_activity) + ImageView option1BottomAppBar; + @BindView(R.id.option_2_bottom_app_bar_main_activity) + ImageView option2BottomAppBar; + @BindView(R.id.option_3_bottom_app_bar_main_activity) + ImageView option3BottomAppBar; + @BindView(R.id.option_4_bottom_app_bar_main_activity) + ImageView option4BottomAppBar; + @BindView(R.id.fab_main_activity) + FloatingActionButton fab; + SubscribedSubredditViewModel subscribedSubredditViewModel; + AccountViewModel accountViewModel; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("main_activity_tabs") + SharedPreferences mMainActivityTabsSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + @Named("bottom_app_bar") + SharedPreferences bottomAppBarSharedPreference; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private FragmentManager fragmentManager; + private SectionsPagerAdapter sectionsPagerAdapter; + private AppBarLayout.LayoutParams params; + private PostTypeBottomSheetFragment postTypeBottomSheetFragment; + private SortTypeBottomSheetFragment sortTypeBottomSheetFragment; + private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + private FABMoreOptionsBottomSheetFragment fabMoreOptionsBottomSheetFragment; + private NavigationDrawerRecyclerViewAdapter adapter; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String mProfileImageUrl; + private String mBannerImageUrl; + private int mKarma; + private boolean mFetchUserInfoSuccess = false; + private boolean mFetchSubscriptionsSuccess = false; + private boolean mDrawerOnAccountSwitch = false; + private String mMessageFullname; + private String mNewAccountName; + private Menu mMenu; + private boolean isInLazyMode = false; + private boolean showBottomAppBar; + private boolean mConfirmToExit; + private boolean mLockBottomAppBar; + private boolean mDisableSwipingBetweenTabs; + private boolean mShowFavoriteSubscribedSubreddits; + private boolean mShowSubscribedSubreddits; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setTheme(R.style.AppTheme_NoActionBarWithTransparentStatusBar); + + setHasDrawerLayout(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_main); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + drawer.setStatusBarBackgroundColor(Color.TRANSPARENT); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + drawer.setFitsSystemWindows(false); + drawer.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + + int navBarHeight = getNavBarHeight(); + if (navBarHeight > 0) { + CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); + params.bottomMargin += navBarHeight; + fab.setLayoutParams(params); + linearLayoutBottomAppBar.setPadding(0, + linearLayoutBottomAppBar.getPaddingTop(), 0, navBarHeight); + navDrawerRecyclerView.setPadding(0, 0, 0, navBarHeight); + } + } else { + drawer.setStatusBarBackgroundColor(mCustomThemeWrapper.getColorPrimaryDark()); + } + } + + postTypeBottomSheetFragment = new PostTypeBottomSheetFragment(); + sortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + fabMoreOptionsBottomSheetFragment = new FABMoreOptionsBottomSheetFragment(); + + setSupportActionBar(toolbar); + setToolbarGoToTop(toolbar); + + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + toggle.getDrawerArrowDrawable().setColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); + drawer.addDrawerListener(toggle); + drawer.addDrawerListener(new DrawerLayout.SimpleDrawerListener() { + @Override + public void onDrawerClosed(View drawerView) { + if (adapter != null) { + if (adapter.closeAccountSectionWithoutChangeIconResource(true)) { + adapter.notifyItemChanged(0); + } + } + } + }); + toggle.syncState(); + + params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); + + showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); + mConfirmToExit = mSharedPreferences.getBoolean(SharedPreferencesUtils.CONFIRM_TO_EXIT, false); + mLockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); + mDisableSwipingBetweenTabs = mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false); + + fragmentManager = getSupportFragmentManager(); + + if (savedInstanceState != null) { + mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE); + mFetchSubscriptionsSuccess = savedInstanceState.getBoolean(FETCH_SUBSCRIPTIONS_STATE); + mDrawerOnAccountSwitch = savedInstanceState.getBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE); + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + mProfileImageUrl = savedInstanceState.getString(ACCOUNT_PROFILE_IMAGE_URL_STATE); + mBannerImageUrl = savedInstanceState.getString(ACCOUNT_BANNER_IMAGE_URL_STATE); + mKarma = savedInstanceState.getInt(ACCOUNT_KARMA_STATE); + mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); + mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + mMessageFullname = getIntent().getStringExtra(EXTRA_MESSSAGE_FULLNAME); + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); + getCurrentAccountAndBindView(); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + int backgroundColor = mCustomThemeWrapper.getBackgroundColor(); + drawer.setBackgroundColor(backgroundColor); + int bottomAppBarIconColor = mCustomThemeWrapper.getBottomAppBarIconColor(); + option1BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option2BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option3BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option4BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + navigationView.setBackgroundColor(backgroundColor); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + applyTabLayoutTheme(tabLayout); + bottomAppBar.setBackgroundTint(ColorStateList.valueOf(mCustomThemeWrapper.getBottomAppBarBackgroundColor())); + applyFABTheme(fab); + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + boolean enableNotification = mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_NOTIFICATION_KEY, true); + long notificationInterval = Long.parseLong(mSharedPreferences.getString(SharedPreferencesUtils.NOTIFICATION_INTERVAL_KEY, "1")); + TimeUnit timeUnit = (notificationInterval == 15 || notificationInterval == 30) ? TimeUnit.MINUTES : TimeUnit.HOURS; + + WorkManager workManager = WorkManager.getInstance(this); + + if (mNewAccountName != null) { + if (account == null || !account.getUsername().equals(mNewAccountName)) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { + EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); + Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); + + mNewAccountName = null; + if (newAccount == null) { + mNullAccessToken = true; + } else { + mAccessToken = newAccount.getAccessToken(); + mAccountName = newAccount.getUsername(); + mProfileImageUrl = newAccount.getProfileImageUrl(); + mBannerImageUrl = newAccount.getBannerImageUrl(); + mKarma = newAccount.getKarma(); + } + + if (enableNotification) { + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + PeriodicWorkRequest pullNotificationRequest = + new PeriodicWorkRequest.Builder(PullNotificationWorker.class, + notificationInterval, timeUnit) + .setConstraints(constraints) + .build(); + + workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, + ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); + } else { + workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); + } + + bindView(); + }).execute(); + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + mProfileImageUrl = account.getProfileImageUrl(); + mBannerImageUrl = account.getBannerImageUrl(); + mKarma = account.getKarma(); + + if (enableNotification) { + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + PeriodicWorkRequest pullNotificationRequest = + new PeriodicWorkRequest.Builder(PullNotificationWorker.class, + notificationInterval, timeUnit) + .setConstraints(constraints) + .build(); + + workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, + ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); + } else { + workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); + } + + bindView(); + } + } else { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + mProfileImageUrl = account.getProfileImageUrl(); + mBannerImageUrl = account.getBannerImageUrl(); + mKarma = account.getKarma(); + } + + if (enableNotification) { + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + PeriodicWorkRequest pullNotificationRequest = + new PeriodicWorkRequest.Builder(PullNotificationWorker.class, + notificationInterval, timeUnit) + .setConstraints(constraints) + .build(); + + workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, + ExistingPeriodicWorkPolicy.KEEP, pullNotificationRequest); + } else { + workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); + } + + bindView(); + } + }).execute(); + } + + private void bottomAppBarOptionAction(int option) { + switch (option) { + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: { + Intent intent = new Intent(this, SubscribedThingListingActivity.class); + startActivity(intent); + break; + } + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: { + Intent intent = new Intent(this, SubscribedThingListingActivity.class); + intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); + startActivity(intent); + break; + } + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX: { + Intent intent = new Intent(this, InboxActivity.class); + startActivity(intent); + break; + } + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_PROFILE: { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); + startActivity(intent); + break; + } + } + } + + private int getBottomAppBarOptionDrawableResource(int option) { + switch (option) { + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: + return R.drawable.ic_subscritptions_bottom_app_bar_24dp; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: + return R.drawable.ic_multi_reddit_24dp; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX: + return R.drawable.ic_inbox_24dp; + default: + return R.drawable.ic_account_circle_24dp; + } + } + + private void bindView() { + if (isDestroyed()) { + return; + } + + if (mAccessToken == null) { + bottomAppBar.setVisibility(View.GONE); + fab.setVisibility(View.GONE); + } else { + if (showBottomAppBar) { + int optionCount = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT, 4); + int option1 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS); + int option2 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS); + + bottomAppBar.setVisibility(View.VISIBLE); + + if (optionCount == 2) { + linearLayoutBottomAppBar.setWeightSum(3); + option1BottomAppBar.setVisibility(View.GONE); + option3BottomAppBar.setVisibility(View.GONE); + + option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); + option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); + + option2BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option1); + }); + + option4BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option2); + }); + } else { + int option3 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX); + int option4 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_PROFILE); + + option1BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); + option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); + option3BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option3)); + option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option4)); + + option1BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option1); + }); + + option2BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option2); + }); + + option3BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option3); + }); + + option4BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option4); + }); + } + } else { + CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); + lp.setAnchorId(View.NO_ID); + lp.gravity = Gravity.END | Gravity.BOTTOM; + fab.setLayoutParams(lp); + } + + int fabOption = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB, SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS); + switch (fabOption) { + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_REFRESH: + fab.setImageResource(R.drawable.ic_refresh_24dp); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: + fab.setImageResource(R.drawable.ic_sort_toolbar_24dp); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: + fab.setImageResource(R.drawable.ic_post_layout_24dp); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SEARCH: + fab.setImageResource(R.drawable.ic_search_black_24dp); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: + fab.setImageResource(R.drawable.ic_subreddit_24dp); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_USER: + fab.setImageResource(R.drawable.ic_user_24dp); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_RANDOM: + fab.setImageResource(R.drawable.ic_random_24dp); + break; + default: + fab.setImageResource(R.drawable.ic_add_day_night_24dp); + break; + } + fab.setOnClickListener(view -> { + switch (fabOption) { + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_REFRESH: { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.refresh(); + } + break; + } + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: { + changeSortType(); + break; + } + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: { + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + break; + } + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SEARCH: { + Intent intent = new Intent(this, SearchActivity.class); + startActivity(intent); + break; + } + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: + goToSubreddit(); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_USER: + goToUser(); + break; + case SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_RANDOM: + randomThing(); + break; + default: + postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); + break; + } + }); + fab.setOnLongClickListener(view -> { + fabMoreOptionsBottomSheetFragment.show(getSupportFragmentManager(), fabMoreOptionsBottomSheetFragment.getTag()); + return true; + }); + fab.setVisibility(View.VISIBLE); + } + + adapter = new NavigationDrawerRecyclerViewAdapter(this, mSharedPreferences, + mNsfwAndSpoilerSharedPreferences, mCustomThemeWrapper, mAccountName, + mProfileImageUrl, mBannerImageUrl, mKarma, + new NavigationDrawerRecyclerViewAdapter.ItemClickListener() { + @Override + public void onMenuClick(int stringId) { + Intent intent = null; + switch (stringId) { + case R.string.profile: + intent = new Intent(MainActivity.this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); + break; + case R.string.subscriptions: + intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); + break; + case R.string.multi_reddit: + intent = new Intent(MainActivity.this, SubscribedThingListingActivity.class); + intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); + break; + case R.string.inbox: + intent = new Intent(MainActivity.this, InboxActivity.class); + break; + case R.string.upvoted: + intent = new Intent(MainActivity.this, AccountPostsActivity.class); + intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_UPVOTED); + break; + case R.string.downvoted: + intent = new Intent(MainActivity.this, AccountPostsActivity.class); + intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_DOWNVOTED); + break; + case R.string.hidden: + intent = new Intent(MainActivity.this, AccountPostsActivity.class); + intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_HIDDEN); + break; + case R.string.saved: + intent = new Intent(MainActivity.this, AccountSavedThingActivity.class); + break; + case R.string.gilded: + intent = new Intent(MainActivity.this, AccountPostsActivity.class); + intent.putExtra(AccountPostsActivity.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_GILDED); + break; + case R.string.light_theme: + mSharedPreferences.edit().putString(SharedPreferencesUtils.THEME_KEY, "0").apply(); + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); + mCustomThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); + break; + case R.string.dark_theme: + mSharedPreferences.edit().putString(SharedPreferencesUtils.THEME_KEY, "1").apply(); + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AMOLED_DARK_KEY, false)) { + mCustomThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); + } else { + mCustomThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); + } + break; + case R.string.enable_nsfw: + if (sectionsPagerAdapter != null) { + mNsfwAndSpoilerSharedPreferences.edit().putBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, true).apply(); + sectionsPagerAdapter.changeNSFW(true); + } + break; + case R.string.disable_nsfw: + if (sectionsPagerAdapter != null) { + mNsfwAndSpoilerSharedPreferences.edit().putBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false).apply(); + sectionsPagerAdapter.changeNSFW(false); + } + break; + case R.string.settings: + intent = new Intent(MainActivity.this, SettingsActivity.class); + break; + case R.string.add_account: + Intent addAccountIntent = new Intent(MainActivity.this, LoginActivity.class); + startActivityForResult(addAccountIntent, LOGIN_ACTIVITY_REQUEST_CODE); + break; + case R.string.anonymous_account: + new SwitchToAnonymousAccountAsyncTask(mRedditDataRoomDatabase, false, + () -> { + Intent anonymousIntent = new Intent(MainActivity.this, MainActivity.class); + startActivity(anonymousIntent); + finish(); + }).execute(); + break; + case R.string.log_out: + new SwitchToAnonymousAccountAsyncTask(mRedditDataRoomDatabase, true, + () -> { + Intent logOutIntent = new Intent(MainActivity.this, MainActivity.class); + startActivity(logOutIntent); + finish(); + }).execute(); + + } + if (intent != null) { + startActivity(intent); + } + drawer.closeDrawers(); + } + + @Override + public void onSubscribedSubredditClick(String subredditName) { + Intent intent = new Intent(MainActivity.this, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); + startActivity(intent); + } + + @Override + public void onAccountClick(String accountName) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, accountName, newAccount -> { + Intent intent = new Intent(MainActivity.this, MainActivity.class); + startActivity(intent); + finish(); + }).execute(); + } + }); + navDrawerRecyclerView.setLayoutManager(new LinearLayoutManager(this)); + navDrawerRecyclerView.setAdapter(adapter); + + int tabCount = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_COUNT, 3); + mShowFavoriteSubscribedSubreddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, false); + mShowSubscribedSubreddits = mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, false); + sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle(), tabCount, + mShowFavoriteSubscribedSubreddits, mShowSubscribedSubreddits); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(1); + viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); + if (mMainActivityTabsSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true)) { + if (mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) { + tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE); + } else { + tabLayout.setTabMode(TabLayout.MODE_FIXED); + } + new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { + if (mAccessToken == null) { + switch (position) { + case 0: + tab.setText(R.string.popular); + break; + case 1: + tab.setText(R.string.all); + break; + } + } else { + switch (position) { + case 0: + tab.setText(mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.home))); + break; + case 1: + tab.setText(mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, getString(R.string.popular))); + break; + case 2: + tab.setText(mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE, getString(R.string.all))); + break; + } + if (position >= tabCount && (mShowFavoriteSubscribedSubreddits || mShowSubscribedSubreddits) && sectionsPagerAdapter != null) { + List favoriteSubscribedSubreddits = sectionsPagerAdapter.favoriteSubscribedSubreddits; + List subscribedSubreddits = sectionsPagerAdapter.subscribedSubreddits; + if (position - tabCount < favoriteSubscribedSubreddits.size()) { + tab.setText(favoriteSubscribedSubreddits.get(position - tabCount).getName()); + } else if (position - tabCount - favoriteSubscribedSubreddits.size() < subscribedSubreddits.size()) { + tab.setText(subscribedSubreddits.get(position - tabCount - favoriteSubscribedSubreddits.size()).getName()); + } + } + } + }).attach(); + } else { + tabLayout.setVisibility(View.GONE); + } + + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + if (mAccessToken != null) { + if (showBottomAppBar) { + bottomAppBar.performShow(); + } + fab.show(); + } + sectionsPagerAdapter.displaySortTypeInToolbar(); + } + }); + + fixViewPager2Sensitivity(viewPager2); + + loadSubscriptions(); + + subscribedSubredditViewModel = new ViewModelProvider(this, + new SubscribedSubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName)) + .get(SubscribedSubredditViewModel.class); + subscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, + subscribedSubredditData -> { + adapter.setSubscribedSubreddits(subscribedSubredditData); + if (mShowSubscribedSubreddits && sectionsPagerAdapter != null) { + sectionsPagerAdapter.setSubscribedSubreddits(subscribedSubredditData); + } + }); + subscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, subscribedSubredditData -> { + adapter.setFavoriteSubscribedSubreddits(subscribedSubredditData); + if (mShowFavoriteSubscribedSubreddits && sectionsPagerAdapter != null) { + sectionsPagerAdapter.setFavoriteSubscribedSubreddits(subscribedSubredditData); + } + }); + + accountViewModel = new ViewModelProvider(this, + new AccountViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName)).get(AccountViewModel.class); + accountViewModel.getAccountsExceptCurrentAccountLiveData().observe(this, adapter::changeAccountsDataset); + accountViewModel.getCurrentAccountLiveData().observe(this, account -> { + if (account != null) { + adapter.updateKarma(account.getKarma()); + } + }); + + if (getIntent().hasExtra(EXTRA_POST_TYPE)) { + String type = getIntent().getStringExtra(EXTRA_POST_TYPE); + if (type != null && type.equals("popular")) { + viewPager2.setCurrentItem(1); + } else { + viewPager2.setCurrentItem(2); + } + } + + loadUserData(); + + if (mAccessToken != null) { + if (mMessageFullname != null) { + ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { + @Override + public void readSuccess() { + mMessageFullname = null; + } + + @Override + public void readFailed() { + + } + }); + } + } + } + + private void loadSubscriptions() { + if (mAccessToken != null && !mFetchSubscriptionsSuccess) { + FetchSubscribedThing.fetchSubscribedThing(mOauthRetrofit, mAccessToken, mAccountName, null, + new ArrayList<>(), new ArrayList<>(), + new ArrayList<>(), + new FetchSubscribedThing.FetchSubscribedThingListener() { + @Override + public void onFetchSubscribedThingSuccess(ArrayList subscribedSubredditData, + ArrayList subscribedUserData, + ArrayList subredditData) { + new InsertSubscribedThingsAsyncTask( + mRedditDataRoomDatabase, + mAccountName, + subscribedSubredditData, + subscribedUserData, + subredditData, + () -> mFetchSubscriptionsSuccess = true).execute(); + } + + @Override + public void onFetchSubscribedThingFail() { + mFetchSubscriptionsSuccess = false; + } + }); + } + } + + private void loadUserData() { + if (!mFetchUserInfoSuccess) { + FetchMyInfo.fetchAccountInfo(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, + new FetchMyInfo.FetchMyInfoListener() { + @Override + public void onFetchMyInfoSuccess(String name, String profileImageUrl, String bannerImageUrl, int karma) { + mAccountName = name; + mProfileImageUrl = profileImageUrl; + mBannerImageUrl = bannerImageUrl; + mKarma = karma; + mFetchUserInfoSuccess = true; + } + + @Override + public void onFetchMyInfoFailed(boolean parseFailed) { + mFetchUserInfoSuccess = false; + } + }); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == LOGIN_ACTIVITY_REQUEST_CODE && resultCode == Activity.RESULT_OK) { + Intent intent = new Intent(this, MainActivity.class); + startActivity(intent); + finish(); + } + + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_main_activity); + + if (isInLazyMode) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } else { + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } + + return true; + } + + private void changeSortType() { + int currentPostType = sectionsPagerAdapter.getCurrentPostType(); + Bundle bundle = new Bundle(); + if (currentPostType != PostDataSource.TYPE_FRONT_PAGE) { + bundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + } else { + bundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, false); + } + sortTypeBottomSheetFragment.setArguments(bundle); + sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.action_search_main_activity: + Intent intent = new Intent(this, SearchActivity.class); + startActivity(intent); + return true; + case R.id.action_sort_main_activity: + changeSortType(); + return true; + case R.id.action_refresh_main_activity: + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_main_activity).setTitle(R.string.action_start_lazy_mode); + } + sectionsPagerAdapter.refresh(); + mFetchUserInfoSuccess = false; + loadUserData(); + return true; + case R.id.action_lazy_mode_main_activity: + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_main_activity); + if (isInLazyMode) { + sectionsPagerAdapter.stopLazyMode(); + isInLazyMode = false; + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } else { + if (sectionsPagerAdapter.startLazyMode()) { + isInLazyMode = true; + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } + } + return true; + case R.id.action_change_post_layout_main_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + } + return false; + } + + @Override + public void onBackPressed() {; + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + if (mConfirmToExit) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.exit_app) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } else { + super.onBackPressed(); + } + } + } + + @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 + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess); + outState.putBoolean(FETCH_SUBSCRIPTIONS_STATE, mFetchSubscriptionsSuccess); + outState.putBoolean(DRAWER_ON_ACCOUNT_SWITCH_STATE, mDrawerOnAccountSwitch); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(ACCOUNT_PROFILE_IMAGE_URL_STATE, mProfileImageUrl); + outState.putString(ACCOUNT_BANNER_IMAGE_URL_STATE, mBannerImageUrl); + outState.putInt(ACCOUNT_KARMA_STATE, mKarma); + outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); + outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + public void sortTypeSelected(SortType sortType) { + sectionsPagerAdapter.changeSortType(sortType); + } + + @Override + public void sortTypeSelected(String sortType) { + Bundle bundle = new Bundle(); + bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); + sortTimeBottomSheetFragment.setArguments(bundle); + sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); + } + + @Override + public void postTypeSelected(int postType) { + Intent intent; + switch (postType) { + case PostTypeBottomSheetFragment.TYPE_TEXT: + intent = new Intent(MainActivity.this, PostTextActivity.class); + startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_LINK: + intent = new Intent(MainActivity.this, PostLinkActivity.class); + startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_IMAGE: + intent = new Intent(MainActivity.this, PostImageActivity.class); + startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_VIDEO: + intent = new Intent(MainActivity.this, PostVideoActivity.class); + startActivity(intent); + } + } + + @Override + public void postLayoutSelected(int postLayout) { + sectionsPagerAdapter.changePostLayout(postLayout); + } + + public void postScrollUp() { + if (mAccessToken != null) { + if (showBottomAppBar && !mLockBottomAppBar) { + bottomAppBar.performShow(); + } + if (!(showBottomAppBar && mLockBottomAppBar)) { + fab.show(); + } + } + } + + public void postScrollDown() { + if (mAccessToken != null) { + if (!(showBottomAppBar && mLockBottomAppBar)) { + fab.hide(); + } + if (showBottomAppBar && !mLockBottomAppBar) { + bottomAppBar.performHide(); + } + } + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + if (!getClass().getName().equals(event.excludeActivityClassName)) { + finish(); + } + } + + @Subscribe + public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { + sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); + if (adapter != null) { + adapter.setNSFWEnabled(changeNSFWEvent.nsfw); + } + } + + @Subscribe + public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { + recreate(); + } + + @Subscribe + public void onChangeConfirmToExitEvent(ChangeConfirmToExitEvent changeConfirmToExitEvent) { + mConfirmToExit = changeConfirmToExitEvent.confirmToExit; + } + + @Subscribe + public void onChangeLockBottomAppBar(ChangeLockBottomAppBarEvent changeLockBottomAppBarEvent) { + mLockBottomAppBar = changeLockBottomAppBarEvent.lockBottomAppBar; + } + + @Subscribe + public void onChangeDisableSwipingBetweenTabsEvent(ChangeDisableSwipingBetweenTabsEvent changeDisableSwipingBetweenTabsEvent) { + mDisableSwipingBetweenTabs = changeDisableSwipingBetweenTabsEvent.disableSwipingBetweenTabs; + viewPager2.setUserInputEnabled(!mDisableSwipingBetweenTabs); + } + + @Subscribe + public void onChangeRequireAuthToAccountSectionEvent(ChangeRequireAuthToAccountSectionEvent changeRequireAuthToAccountSectionEvent) { + adapter.setRequireAuthToAccountSection(changeRequireAuthToAccountSectionEvent.requireAuthToAccountSection); + } + + @Override + public void onLongPress() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.goBackToTop(); + } + } + + @Override + public void displaySortType() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.displaySortTypeInToolbar(); + } + } + + @Override + public void fabOptionSelected(int option) { + switch (option) { + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SUBMIT_POST: + postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_REFRESH: + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.refresh(); + } + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_SORT_TYPE: + changeSortType(); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_POST_LAYOUT: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SEARCH: + Intent intent = new Intent(this, SearchActivity.class); + startActivity(intent); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_SUBREDDIT: { + goToSubreddit(); + break; + } + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_USER: { + goToUser(); + break; + } + case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { + randomThing(); + break; + } + } + } + + private void goToSubreddit() { + EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); + thingEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.go_to_subreddit) + .setView(thingEditText) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); + subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); + startActivity(subredditIntent); + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) + .show(); + } + + private void goToUser() { + EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); + thingEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.go_to_user) + .setView(thingEditText) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent userIntent = new Intent(this, ViewUserDetailActivity.class); + userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); + startActivity(userIntent); + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) + .show(); + } + + private void randomThing() { + RandomBottomSheetFragment randomBottomSheetFragment = new RandomBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean(RandomBottomSheetFragment.EXTRA_IS_NSFW, mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)); + randomBottomSheetFragment.setArguments(bundle); + randomBottomSheetFragment.show(getSupportFragmentManager(), randomBottomSheetFragment.getTag()); + } + + @Override + public void randomOptionSelected(int option) { + Intent intent = new Intent(this, FetchRandomSubredditOrPostActivity.class); + intent.putExtra(FetchRandomSubredditOrPostActivity.EXTRA_RANDOM_OPTION, option); + startActivity(intent); + } + + private class SectionsPagerAdapter extends FragmentStateAdapter { + int tabCount; + boolean showFavoriteSubscribedSubreddits; + boolean showSubscribedSubreddits; + List favoriteSubscribedSubreddits; + List subscribedSubreddits; + + SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle, int tabCount, boolean showFavoriteSubscribedSubreddits, boolean showSubscribedSubreddits) { + super(fm, lifecycle); + this.tabCount = tabCount; + favoriteSubscribedSubreddits = new ArrayList<>(); + subscribedSubreddits = new ArrayList<>(); + this.showFavoriteSubscribedSubreddits = showFavoriteSubscribedSubreddits; + this.showSubscribedSubreddits = showSubscribedSubreddits; + } + + @NonNull + @Override + public Fragment createFragment(int position) { + if (mAccessToken == null) { + if (position == 0) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + bundle.putString(PostFragment.EXTRA_NAME, "popular"); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } else { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + bundle.putString(PostFragment.EXTRA_NAME, "all"); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + } + + if (position == 0) { + int postType = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_HOME); + String name = mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME, ""); + return generatePostFragment(postType, name); + } else if (position == 1) { + int postType = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_POPULAR); + String name = mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME, ""); + return generatePostFragment(postType, name); + } else { + if (showFavoriteSubscribedSubreddits) { + if (position >= tabCount && position - tabCount < favoriteSubscribedSubreddits.size()) { + int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT; + String name = favoriteSubscribedSubreddits.get(position - tabCount).getName(); + return generatePostFragment(postType, name); + } + } + if (showSubscribedSubreddits) { + if (position >= tabCount && position - tabCount - favoriteSubscribedSubreddits.size() < subscribedSubreddits.size()) { + int postType = SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT; + String name = subscribedSubreddits.get(position - tabCount - favoriteSubscribedSubreddits.size()).getName(); + return generatePostFragment(postType, name); + } + } + int postType = mMainActivityTabsSharedPreferences.getInt((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_ALL); + String name = mMainActivityTabsSharedPreferences.getString((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME, ""); + return generatePostFragment(postType, name); + } + } + + public void setFavoriteSubscribedSubreddits(List favoriteSubscribedSubreddits) { + this.favoriteSubscribedSubreddits = favoriteSubscribedSubreddits; + notifyDataSetChanged(); + } + + public void setSubscribedSubreddits(List subscribedSubreddits) { + this.subscribedSubreddits = subscribedSubreddits; + notifyDataSetChanged(); + } + + private Fragment generatePostFragment(int postType, String name) { + if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_HOME) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_FRONT_PAGE); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_ALL) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + bundle.putString(PostFragment.EXTRA_NAME, "all"); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + bundle.putString(PostFragment.EXTRA_NAME, name); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putString(PostFragment.EXTRA_NAME, name); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_MULTI_REDDIT); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } else if (postType == SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); + bundle.putString(PostFragment.EXTRA_USER_NAME, name); + bundle.putString(PostFragment.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SUBMITTED); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } else { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + bundle.putString(PostFragment.EXTRA_NAME, "popular"); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + } + + @Override + public int getItemCount() { + if (mAccessToken == null) { + return 2; + } + return tabCount + favoriteSubscribedSubreddits.size() + subscribedSubreddits.size(); + } + + @Nullable + private PostFragment getCurrentFragment() { + if (viewPager2 == null || fragmentManager == null) { + return null; + } + Fragment fragment = fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); + if (fragment instanceof PostFragment) { + return (PostFragment) fragment; + } + return null; + } + + boolean handleKeyDown(int keyCode) { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + return currentFragment.handleKeyDown(keyCode); + } + return false; + } + + boolean startLazyMode() { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + return currentFragment.startLazyMode(); + } + + return false; + } + + void stopLazyMode() { + for (int i = 0; i < getItemCount(); i++) { + Fragment fragment = fragmentManager.findFragmentByTag("f" + i); + if (fragment instanceof PostFragment && ((PostFragment) fragment).isInLazyMode()) { + ((PostFragment) fragment).stopLazyMode(); + } + } + } + + int getCurrentPostType() { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + return currentFragment.getPostType(); + } + return PostDataSource.TYPE_SUBREDDIT; + } + + void changeSortType(SortType sortType) { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.changeSortType(sortType); + } + displaySortTypeInToolbar(); + } + + public void refresh() { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.refresh(); + } + } + + void changeNSFW(boolean nsfw) { + for (int i = 0; i < getItemCount(); i++) { + Fragment fragment = fragmentManager.findFragmentByTag("f" + i); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeNSFW(nsfw); + } + } + } + + void changePostLayout(int postLayout) { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.changePostLayout(postLayout); + } + } + + void goBackToTop() { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + currentFragment.goBackToTop(); + } + } + + void displaySortTypeInToolbar() { + PostFragment currentFragment = getCurrentFragment(); + if (currentFragment != null) { + SortType sortType = currentFragment.getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java new file mode 100644 index 00000000..a8517925 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostImageActivity.java @@ -0,0 +1,678 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Environment; +import android.provider.MediaStore; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.FileProvider; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; +import com.libRG.CustomTextView; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.io.File; +import java.io.IOException; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIconAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitImagePostEvent; +import ml.docilealligator.infinityforreddit.events.SubmitVideoOrGifPostEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class PostImageActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { + + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_ICON_STATE = "SIS"; + private static final String SUBREDDIT_SELECTED_STATE = "SSS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + private static final String IMAGE_URI_STATE = "IUS"; + private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; + private static final String IS_POSTING_STATE = "IPS"; + private static final String FLAIR_STATE = "FS"; + private static final String IS_SPOILER_STATE = "ISS"; + private static final String IS_NSFW_STATE = "INS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + private static final int PICK_IMAGE_REQUEST_CODE = 1; + private static final int CAPTURE_IMAGE_REQUEST_CODE = 2; + + @BindView(R.id.coordinator_layout_post_image_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_post_image_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_post_image_activity) + Toolbar toolbar; + @BindView(R.id.subreddit_icon_gif_image_view_post_image_activity) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_post_image_activity) + TextView subredditNameTextView; + @BindView(R.id.rules_button_post_image_activity) + Button rulesButton; + @BindView(R.id.divider_1_post_image_activity) + View divider1; + @BindView(R.id.flair_custom_text_view_post_image_activity) + CustomTextView flairTextView; + @BindView(R.id.spoiler_custom_text_view_post_image_activity) + CustomTextView spoilerTextView; + @BindView(R.id.nsfw_custom_text_view_post_image_activity) + CustomTextView nsfwTextView; + @BindView(R.id.divider_2_post_image_activity) + View divider2; + @BindView(R.id.post_title_edit_text_post_image_activity) + EditText titleEditText; + @BindView(R.id.divider_3_post_image_activity) + View divider3; + @BindView(R.id.select_image_constraint_layout_post_image_activity) + ConstraintLayout constraintLayout; + @BindView(R.id.capture_fab_post_image_activity) + FloatingActionButton captureFab; + @BindView(R.id.select_from_library_fab_post_image_activity) + FloatingActionButton selectFromLibraryFab; + @BindView(R.id.select_again_text_view_post_image_activity) + TextView selectAgainTextView; + @BindView(R.id.image_view_post_image_activity) + ImageView imageView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String iconUrl; + private String subredditName; + private boolean subredditSelected = false; + private boolean subredditIsUser; + private boolean loadSubredditIconSuccessful = true; + private boolean isPosting; + private Uri imageUri; + private int primaryTextColor; + private int flairBackgroundColor; + private int flairTextColor; + private int spoilerBackgroundColor; + private int spoilerTextColor; + private int nsfwBackgroundColor; + private int nsfwTextColor; + private Flair flair; + private boolean isSpoiler = false; + private boolean isNSFW = false; + private Resources resources; + private Menu mMemu; + private RequestManager mGlide; + private FlairBottomSheetFragment flairSelectionBottomSheetFragment; + private Snackbar mPostingSnackbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_post_image); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); + + resources = getResources(); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); + subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); + isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); + flair = savedInstanceState.getParcelable(FLAIR_STATE); + isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); + isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + + if (savedInstanceState.getString(IMAGE_URI_STATE) != null) { + imageUri = Uri.parse(savedInstanceState.getString(IMAGE_URI_STATE)); + loadImage(); + } + + if (subredditName != null) { + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + if (!loadSubredditIconSuccessful) { + loadSubredditIcon(); + } + } + displaySubredditIcon(); + + if (isPosting) { + mPostingSnackbar.show(); + } + + if (flair != null) { + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + if (isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + } else { + getCurrentAccount(); + + isPosting = false; + + if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { + loadSubredditIconSuccessful = false; + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + subredditSelected = true; + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + loadSubredditIcon(); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + + imageUri = getIntent().getData(); + if (imageUri != null) { + loadImage(); + } + } + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + subredditNameTextView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + rulesButton.setOnClickListener(view -> { + if (subredditName == null) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(this, RulesActivity.class); + if (subredditIsUser) { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + startActivity(intent); + } + }); + + flairTextView.setOnClickListener(view -> { + if (flair == null) { + flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); + flairSelectionBottomSheetFragment.setArguments(bundle); + flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); + } else { + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + }); + + spoilerTextView.setOnClickListener(view -> { + if (!isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + isSpoiler = true; + } else { + spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + spoilerTextView.setTextColor(primaryTextColor); + isSpoiler = false; + } + }); + + nsfwTextView.setOnClickListener(view -> { + if (!isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + isNSFW = true; + } else { + nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + nsfwTextView.setTextColor(primaryTextColor); + isNSFW = false; + } + }); + + captureFab.setOnClickListener(view -> { + Intent pictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + if (pictureIntent.resolveActivity(getPackageManager()) != null) { + try { + imageUri = FileProvider.getUriForFile(this, "ml.docilealligator.infinityforreddit.provider", + File.createTempFile("temp_img", ".jpg", getExternalFilesDir(Environment.DIRECTORY_PICTURES))); + pictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); + startActivityForResult(pictureIntent, CAPTURE_IMAGE_REQUEST_CODE); + } catch (IOException ex) { + Snackbar.make(coordinatorLayout, R.string.error_creating_temp_file, Snackbar.LENGTH_SHORT).show(); + } + } else { + Snackbar.make(coordinatorLayout, R.string.no_camera_available, Snackbar.LENGTH_SHORT).show(); + } + }); + + selectFromLibraryFab.setOnClickListener(view -> { + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, resources.getString(R.string.select_from_gallery)), PICK_IMAGE_REQUEST_CODE); + }); + + selectAgainTextView.setOnClickListener(view -> { + imageUri = null; + selectAgainTextView.setVisibility(View.GONE); + mGlide.clear(imageView); + imageView.setVisibility(View.GONE); + constraintLayout.setVisibility(View.VISIBLE); + }); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + subredditNameTextView.setTextColor(secondaryTextColor); + rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); + rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + divider3.setBackgroundColor(dividerColor); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); + flairTextColor = mCustomThemeWrapper.getFlairTextColor(); + spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); + spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); + nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); + nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); + flairTextView.setTextColor(primaryTextColor); + spoilerTextView.setTextColor(primaryTextColor); + nsfwTextView.setTextColor(primaryTextColor); + titleEditText.setTextColor(primaryTextColor); + titleEditText.setHintTextColor(secondaryTextColor); + applyFABTheme(captureFab); + applyFABTheme(selectFromLibraryFab); + selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent()); + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + }).execute(); + } + + private void loadImage() { + constraintLayout.setVisibility(View.GONE); + imageView.setVisibility(View.VISIBLE); + selectAgainTextView.setVisibility(View.VISIBLE); + mGlide.load(imageUri).into(imageView); + } + + private void displaySubredditIcon() { + if (iconUrl != null && !iconUrl.equals("")) { + 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(iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + private void loadSubredditIcon() { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { + iconUrl = iconImageUrl; + displaySubredditIcon(); + loadSubredditIconSuccessful = true; + }).execute(); + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.post_image_activity, menu); + applyMenuItemTheme(menu); + mMemu = menu; + if (isPosting) { + mMemu.findItem(R.id.action_send_post_image_activity).setEnabled(false); + mMemu.findItem(R.id.action_send_post_image_activity).getIcon().setAlpha(130); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + return true; + } else { + if (!titleEditText.getText().toString().equals("") || imageUri != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + return true; + } + } + finish(); + return true; + case R.id.action_send_post_image_activity: + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (imageUri == null) { + Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); + return true; + } + + isPosting = true; + + item.setEnabled(false); + item.getIcon().setAlpha(130); + + mPostingSnackbar.show(); + + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } + + Intent intent = new Intent(this, SubmitPostService.class); + intent.setData(imageUri); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + String mimeType = getContentResolver().getType(imageUri); + if (mimeType != null && mimeType.contains("gif")) { + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); + } else { + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_IMAGE); + } + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + + return true; + } + + return false; + } + + @Override + public void onBackPressed() { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + } else { + if (!titleEditText.getText().toString().equals("") || imageUri != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } else { + finish(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putString(SUBREDDIT_ICON_STATE, iconUrl); + outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + if (imageUri != null) { + outState.putString(IMAGE_URI_STATE, imageUri.toString()); + } + outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); + outState.putBoolean(IS_POSTING_STATE, isPosting); + outState.putParcelable(FLAIR_STATE, flair); + outState.putBoolean(IS_SPOILER_STATE, isSpoiler); + outState.putBoolean(IS_NSFW_STATE, isNSFW); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + subredditSelected = true; + subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); + + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + displaySubredditIcon(); + + flairTextView.setVisibility(View.VISIBLE); + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + } else if (requestCode == PICK_IMAGE_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + if (data == null) { + Snackbar.make(coordinatorLayout, R.string.error_getting_image, Snackbar.LENGTH_SHORT).show(); + return; + } + + imageUri = data.getData(); + loadImage(); + } + } else if (requestCode == CAPTURE_IMAGE_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + loadImage(); + } + } + } + + @Override + protected void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + } + + @Override + public void flairSelected(Flair flair) { + this.flair = flair; + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onSubmitImagePostEvent(SubmitImagePostEvent submitImagePostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + if (submitImagePostEvent.postSuccess) { + Intent intent = new Intent(PostImageActivity.this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); + startActivity(intent); + finish(); + } else { + mMemu.findItem(R.id.action_send_post_image_activity).setEnabled(true); + mMemu.findItem(R.id.action_send_post_image_activity).getIcon().setAlpha(255); + if (submitImagePostEvent.errorMessage == null || submitImagePostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitImagePostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitImagePostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } + + @Subscribe + public void onSubmitVideoOrGifPostEvent(SubmitVideoOrGifPostEvent submitVideoOrGifPostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + mMemu.findItem(R.id.action_send_post_image_activity).setEnabled(true); + mMemu.findItem(R.id.action_send_post_image_activity).getIcon().setAlpha(255); + + if (submitVideoOrGifPostEvent.postSuccess) { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, + mAccountName); + startActivity(intent); + finish(); + } else if (submitVideoOrGifPostEvent.errorProcessingVideoOrGif) { + Snackbar.make(coordinatorLayout, R.string.error_processing_image, Snackbar.LENGTH_SHORT).show(); + } else { + if (submitVideoOrGifPostEvent.errorMessage == null || submitVideoOrGifPostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitVideoOrGifPostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitVideoOrGifPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java new file mode 100644 index 00000000..2f76cd9d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostLinkActivity.java @@ -0,0 +1,552 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.libRG.CustomTextView; + +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 jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIconAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitTextOrLinkPostEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class PostLinkActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { + + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + static final String EXTRA_LINK = "EL"; + + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_ICON_STATE = "SIS"; + private static final String SUBREDDIT_SELECTED_STATE = "SSS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; + private static final String IS_POSTING_STATE = "IPS"; + private static final String FLAIR_STATE = "FS"; + private static final String IS_SPOILER_STATE = "ISS"; + private static final String IS_NSFW_STATE = "INS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + + @BindView(R.id.coordinator_layout_post_link_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_post_link_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_post_link_activity) + Toolbar toolbar; + @BindView(R.id.subreddit_icon_gif_image_view_post_link_activity) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_post_link_activity) + TextView subredditNameTextView; + @BindView(R.id.rules_button_post_link_activity) + Button rulesButton; + @BindView(R.id.divider_1_post_link_activity) + View divider1; + @BindView(R.id.divider_2_post_link_activity) + View divider2; + @BindView(R.id.divider_3_post_link_activity) + View divider3; + @BindView(R.id.flair_custom_text_view_post_link_activity) + CustomTextView flairTextView; + @BindView(R.id.spoiler_custom_text_view_post_link_activity) + CustomTextView spoilerTextView; + @BindView(R.id.nsfw_custom_text_view_post_link_activity) + CustomTextView nsfwTextView; + @BindView(R.id.post_title_edit_text_post_link_activity) + EditText titleEditText; + @BindView(R.id.post_link_edit_text_post_link_activity) + EditText linkEditText; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String iconUrl; + private String subredditName; + private boolean subredditSelected = false; + private boolean subredditIsUser; + private boolean loadSubredditIconSuccessful = true; + private boolean isPosting; + private int primaryTextColor; + private int flairBackgroundColor; + private int flairTextColor; + private int spoilerBackgroundColor; + private int spoilerTextColor; + private int nsfwBackgroundColor; + private int nsfwTextColor; + private Flair flair; + private boolean isSpoiler = false; + private boolean isNSFW = false; + private Resources resources; + private Menu mMemu; + private RequestManager mGlide; + private FlairBottomSheetFragment flairSelectionBottomSheetFragment; + private Snackbar mPostingSnackbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_post_link); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); + + resources = getResources(); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); + subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); + isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); + flair = savedInstanceState.getParcelable(FLAIR_STATE); + isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); + isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + + if (subredditName != null) { + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + if (!loadSubredditIconSuccessful) { + loadSubredditIcon(); + } + } + displaySubredditIcon(); + + if (isPosting) { + mPostingSnackbar.show(); + } + + if (flair != null) { + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + if (isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + } else { + getCurrentAccount(); + + isPosting = false; + + if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { + loadSubredditIconSuccessful = false; + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + subredditSelected = true; + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + loadSubredditIcon(); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + + String link = getIntent().getStringExtra(EXTRA_LINK); + if (link != null) { + linkEditText.setText(link); + } + } + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + subredditNameTextView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + rulesButton.setOnClickListener(view -> { + if (subredditName == null) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(this, RulesActivity.class); + if (subredditIsUser) { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + startActivity(intent); + } + }); + + flairTextView.setOnClickListener(view -> { + if (flair == null) { + flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); + flairSelectionBottomSheetFragment.setArguments(bundle); + flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); + } else { + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + }); + + spoilerTextView.setOnClickListener(view -> { + if (!isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + isSpoiler = true; + } else { + spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + spoilerTextView.setTextColor(primaryTextColor); + isSpoiler = false; + } + }); + + nsfwTextView.setOnClickListener(view -> { + if (!isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + isNSFW = true; + } else { + nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + nsfwTextView.setTextColor(primaryTextColor); + isNSFW = false; + } + }); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + subredditNameTextView.setTextColor(secondaryTextColor); + rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); + rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + divider3.setBackgroundColor(dividerColor); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); + flairTextColor = mCustomThemeWrapper.getFlairTextColor(); + spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); + spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); + nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); + nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); + flairTextView.setTextColor(primaryTextColor); + spoilerTextView.setTextColor(primaryTextColor); + nsfwTextView.setTextColor(primaryTextColor); + titleEditText.setTextColor(primaryTextColor); + titleEditText.setHintTextColor(secondaryTextColor); + linkEditText.setTextColor(primaryTextColor); + linkEditText.setHintTextColor(secondaryTextColor); + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + }).execute(); + } + + private void displaySubredditIcon() { + if (iconUrl != null && !iconUrl.equals("")) { + 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(iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + private void loadSubredditIcon() { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { + iconUrl = iconImageUrl; + displaySubredditIcon(); + loadSubredditIconSuccessful = true; + }).execute(); + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.post_link_activity, menu); + applyMenuItemTheme(menu); + mMemu = menu; + if (isPosting) { + mMemu.findItem(R.id.action_send_post_link_activity).setEnabled(false); + mMemu.findItem(R.id.action_send_post_link_activity).getIcon().setAlpha(130); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + return true; + } else { + if (!titleEditText.getText().toString().equals("") || !linkEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + return true; + } + } + finish(); + return true; + case R.id.action_send_post_link_activity: + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (linkEditText.getText() == null || linkEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.link_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + isPosting = true; + + item.setEnabled(false); + item.getIcon().setAlpha(130); + + mPostingSnackbar.show(); + + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } + + Intent intent = new Intent(this, SubmitPostService.class); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_CONTENT, linkEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_LINK); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TEXT_OR_LINK); + startService(intent); + + return true; + } + + return false; + } + + @Override + public void onBackPressed() { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + } else { + if (!titleEditText.getText().toString().equals("") || !linkEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } else { + finish(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putString(SUBREDDIT_ICON_STATE, iconUrl); + outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); + outState.putBoolean(IS_POSTING_STATE, isPosting); + outState.putParcelable(FLAIR_STATE, flair); + outState.putBoolean(IS_SPOILER_STATE, isSpoiler); + outState.putBoolean(IS_NSFW_STATE, isNSFW); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + subredditSelected = true; + subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); + + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + displaySubredditIcon(); + + flairTextView.setVisibility(View.VISIBLE); + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + } + } + + @Override + protected void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + } + + @Override + public void flairSelected(Flair flair) { + this.flair = flair; + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onSubmitLinkPostEvent(SubmitTextOrLinkPostEvent submitTextOrLinkPostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + if (submitTextOrLinkPostEvent.postSuccess) { + Intent intent = new Intent(PostLinkActivity.this, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, submitTextOrLinkPostEvent.post); + startActivity(intent); + finish(); + } else { + mMemu.findItem(R.id.action_send_post_link_activity).setEnabled(true); + mMemu.findItem(R.id.action_send_post_link_activity).getIcon().setAlpha(255); + if (submitTextOrLinkPostEvent.errorMessage == null || submitTextOrLinkPostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitTextOrLinkPostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitTextOrLinkPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java new file mode 100644 index 00000000..31814057 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostTextActivity.java @@ -0,0 +1,569 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.libRG.CustomTextView; + +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 jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.adapters.MarkdownBottomBarRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIconAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitTextOrLinkPostEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class PostTextActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { + + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + static final String EXTRA_CONTENT = "EC"; + + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_ICON_STATE = "SIS"; + private static final String SUBREDDIT_SELECTED_STATE = "SSS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; + private static final String IS_POSTING_STATE = "IPS"; + private static final String FLAIR_STATE = "FS"; + private static final String IS_SPOILER_STATE = "ISS"; + private static final String IS_NSFW_STATE = "INS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + + @BindView(R.id.coordinator_layout_post_text_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_post_text_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_post_text_activity) + Toolbar toolbar; + @BindView(R.id.subreddit_icon_gif_image_view_search_activity) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_search_activity) + TextView subredditNameTextView; + @BindView(R.id.rules_button_post_text_activity) + Button rulesButton; + @BindView(R.id.divider_1_post_text_activity) + View divider1; + @BindView(R.id.flair_custom_text_view_post_text_activity) + CustomTextView flairTextView; + @BindView(R.id.spoiler_custom_text_view_post_text_activity) + CustomTextView spoilerTextView; + @BindView(R.id.nsfw_custom_text_view_post_text_activity) + CustomTextView nsfwTextView; + @BindView(R.id.divider_2_post_text_activity) + View divider2; + @BindView(R.id.post_title_edit_text_post_text_activity) + EditText titleEditText; + @BindView(R.id.divider_3_post_text_activity) + View divider3; + @BindView(R.id.post_text_content_edit_text_post_text_activity) + EditText contentEditText; + @BindView(R.id.markdown_bottom_bar_recycler_view_post_text_activity) + RecyclerView markdownBottomBarRecyclerView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String iconUrl; + private String subredditName; + private boolean subredditSelected = false; + private boolean subredditIsUser; + private boolean loadSubredditIconSuccessful = true; + private boolean isPosting; + private int primaryTextColor; + private int flairBackgroundColor; + private int flairTextColor; + private int spoilerBackgroundColor; + private int spoilerTextColor; + private int nsfwBackgroundColor; + private int nsfwTextColor; + private Flair flair; + private boolean isSpoiler = false; + private boolean isNSFW = false; + private Resources resources; + private Menu mMenu; + private RequestManager mGlide; + private FlairBottomSheetFragment flairSelectionBottomSheetFragment; + private Snackbar mPostingSnackbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_post_text); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); + + resources = getResources(); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); + subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); + isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); + flair = savedInstanceState.getParcelable(FLAIR_STATE); + isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); + isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + + if (subredditName != null) { + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + if (!loadSubredditIconSuccessful) { + loadSubredditIcon(); + } + } + displaySubredditIcon(); + + if (isPosting) { + mPostingSnackbar.show(); + } + + if (flair != null) { + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + if (isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + } else { + getCurrentAccount(); + + isPosting = false; + + if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { + loadSubredditIconSuccessful = false; + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + subredditSelected = true; + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + loadSubredditIcon(); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + + String text = getIntent().getStringExtra(EXTRA_CONTENT); + if (text != null) { + contentEditText.setText(text); + } + } + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + subredditNameTextView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + rulesButton.setOnClickListener(view -> { + if (subredditName == null) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(this, RulesActivity.class); + if (subredditIsUser) { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + startActivity(intent); + } + }); + + flairTextView.setOnClickListener(view -> { + if (flair == null) { + flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + if (subredditIsUser) { + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); + } + flairSelectionBottomSheetFragment.setArguments(bundle); + flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); + } else { + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + }); + + spoilerTextView.setOnClickListener(view -> { + if (!isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + isSpoiler = true; + } else { + spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + spoilerTextView.setTextColor(primaryTextColor); + isSpoiler = false; + } + }); + + nsfwTextView.setOnClickListener(view -> { + if (!isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + isNSFW = true; + } else { + nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + nsfwTextView.setTextColor(primaryTextColor); + isNSFW = false; + } + }); + + MarkdownBottomBarRecyclerViewAdapter adapter = new MarkdownBottomBarRecyclerViewAdapter(mCustomThemeWrapper, item -> { + MarkdownBottomBarRecyclerViewAdapter.bindEditTextWithItemClickListener(this, contentEditText, item); + }); + + markdownBottomBarRecyclerView.setLayoutManager(new LinearLayoutManager(this, + LinearLayoutManager.HORIZONTAL, false)); + markdownBottomBarRecyclerView.setAdapter(adapter); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + subredditNameTextView.setTextColor(secondaryTextColor); + rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); + rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + divider3.setBackgroundColor(dividerColor); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); + flairTextColor = mCustomThemeWrapper.getFlairTextColor(); + spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); + spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); + nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); + nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); + flairTextView.setTextColor(primaryTextColor); + spoilerTextView.setTextColor(primaryTextColor); + nsfwTextView.setTextColor(primaryTextColor); + titleEditText.setTextColor(primaryTextColor); + titleEditText.setHintTextColor(secondaryTextColor); + contentEditText.setTextColor(primaryTextColor); + contentEditText.setHintTextColor(secondaryTextColor); + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + }).execute(); + } + + private void displaySubredditIcon() { + if (iconUrl != null && !iconUrl.equals("")) { + 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(iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + private void loadSubredditIcon() { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { + iconUrl = iconImageUrl; + displaySubredditIcon(); + loadSubredditIconSuccessful = true; + }).execute(); + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.post_text_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + if (isPosting) { + mMenu.findItem(R.id.action_send_post_text_activity).setEnabled(false); + mMenu.findItem(R.id.action_send_post_text_activity).getIcon().setAlpha(130); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + return true; + } else { + if (!titleEditText.getText().toString().equals("") || !contentEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + return true; + } + } + finish(); + return true; + } else if (itemId == R.id.action_preview_post_text_activity) { + Intent intent = new Intent(this, FullMarkdownActivity.class); + intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, contentEditText.getText().toString()); + startActivity(intent); + } else if (itemId == R.id.action_send_post_text_activity) { + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + isPosting = true; + + item.setEnabled(false); + item.getIcon().setAlpha(130); + + mPostingSnackbar.show(); + + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } + + Intent intent = new Intent(this, SubmitPostService.class); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_CONTENT, contentEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_SELF); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TEXT_OR_LINK); + startService(intent); + + return true; + } + + return false; + } + + @Override + public void onBackPressed() { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + } else { + if (!titleEditText.getText().toString().equals("") || !contentEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } else { + finish(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putString(SUBREDDIT_ICON_STATE, iconUrl); + outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); + outState.putBoolean(IS_POSTING_STATE, isPosting); + outState.putParcelable(FLAIR_STATE, flair); + outState.putBoolean(IS_SPOILER_STATE, isSpoiler); + outState.putBoolean(IS_NSFW_STATE, isNSFW); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + subredditSelected = true; + subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); + + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + displaySubredditIcon(); + + flairTextView.setVisibility(View.VISIBLE); + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + } + } + + @Override + protected void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + } + + @Override + public void flairSelected(Flair flair) { + this.flair = flair; + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onSubmitTextPostEvent(SubmitTextOrLinkPostEvent submitTextOrLinkPostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + if (submitTextOrLinkPostEvent.postSuccess) { + Intent intent = new Intent(PostTextActivity.this, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, submitTextOrLinkPostEvent.post); + startActivity(intent); + finish(); + } else { + mMenu.findItem(R.id.action_send_post_text_activity).setEnabled(true); + mMenu.findItem(R.id.action_send_post_text_activity).getIcon().setAlpha(255); + if (submitTextOrLinkPostEvent.errorMessage == null || submitTextOrLinkPostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitTextOrLinkPostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitTextOrLinkPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java new file mode 100644 index 00000000..fb9bca66 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostVideoActivity.java @@ -0,0 +1,679 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.MediaStore; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.source.ExtractorMediaSource; +import com.google.android.exoplayer2.ui.PlayerView; +import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.util.Util; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; +import com.libRG.CustomTextView; + +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 jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIconAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitVideoOrGifPostEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class PostVideoActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { + + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_ICON_STATE = "SIS"; + private static final String SUBREDDIT_SELECTED_STATE = "SSS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + private static final String VIDEO_URI_STATE = "IUS"; + private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; + private static final String IS_POSTING_STATE = "IPS"; + private static final String FLAIR_STATE = "FS"; + private static final String IS_SPOILER_STATE = "ISS"; + private static final String IS_NSFW_STATE = "INS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + private static final int PICK_VIDEO_REQUEST_CODE = 1; + private static final int CAPTURE_VIDEO_REQUEST_CODE = 2; + + @BindView(R.id.coordinator_layout_post_video_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_post_video_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_post_video_activity) + Toolbar toolbar; + @BindView(R.id.subreddit_icon_gif_image_view_post_video_activity) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_post_video_activity) + TextView subredditNameTextView; + @BindView(R.id.rules_button_post_video_activity) + Button rulesButton; + @BindView(R.id.divider_1_post_video_activity) + View divider1; + @BindView(R.id.flair_custom_text_view_post_video_activity) + CustomTextView flairTextView; + @BindView(R.id.spoiler_custom_text_view_post_video_activity) + CustomTextView spoilerTextView; + @BindView(R.id.nsfw_custom_text_view_post_video_activity) + CustomTextView nsfwTextView; + @BindView(R.id.divider_2_post_video_activity) + View divider2; + @BindView(R.id.post_title_edit_text_post_video_activity) + EditText titleEditText; + @BindView(R.id.divider_3_post_video_activity) + View divider3; + @BindView(R.id.select_video_constraint_layout_post_video_activity) + ConstraintLayout constraintLayout; + @BindView(R.id.capture_fab_post_video_activity) + FloatingActionButton captureFab; + @BindView(R.id.select_from_library_fab_post_video_activity) + FloatingActionButton selectFromLibraryFab; + @BindView(R.id.select_again_text_view_post_video_activity) + TextView selectAgainTextView; + @BindView(R.id.player_view_post_video_activity) + PlayerView videoPlayerView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject + @Named("upload_video") + Retrofit mUploadVideoRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String iconUrl; + private String subredditName; + private boolean subredditSelected = false; + private boolean subredditIsUser; + private Uri videoUri; + private boolean loadSubredditIconSuccessful = true; + private boolean isPosting; + private boolean wasPlaying; + private int primaryTextColor; + private int flairBackgroundColor; + private int flairTextColor; + private int spoilerBackgroundColor; + private int spoilerTextColor; + private int nsfwBackgroundColor; + private int nsfwTextColor; + private Flair flair; + private boolean isSpoiler = false; + private boolean isNSFW = false; + private Resources resources; + private Menu mMemu; + private RequestManager mGlide; + private FlairBottomSheetFragment mFlairSelectionBottomSheetFragment; + private Snackbar mPostingSnackbar; + private DataSource.Factory dataSourceFactory; + private SimpleExoPlayer player; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_post_video); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + player = ExoPlayerFactory.newSimpleInstance(this); + videoPlayerView.setPlayer(player); + dataSourceFactory = new DefaultDataSourceFactory(this, + Util.getUserAgent(this, "Infinity")); + player.setRepeatMode(Player.REPEAT_MODE_ALL); + + mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); + + resources = getResources(); + + if (savedInstanceState != null) { + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); + subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); + isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); + flair = savedInstanceState.getParcelable(FLAIR_STATE); + isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); + isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + + if (savedInstanceState.getString(VIDEO_URI_STATE) != null) { + videoUri = Uri.parse(savedInstanceState.getString(VIDEO_URI_STATE)); + loadVideo(); + } + + if (subredditName != null) { + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + if (!loadSubredditIconSuccessful) { + loadSubredditIcon(); + } + } + displaySubredditIcon(); + + if (isPosting) { + mPostingSnackbar.show(); + } + + if (flair != null) { + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + if (isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + } else { + getCurrentAccount(); + + isPosting = false; + + if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { + loadSubredditIconSuccessful = false; + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + subredditSelected = true; + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + loadSubredditIcon(); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + + videoUri = getIntent().getData(); + if (videoUri != null) { + loadVideo(); + } + } + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + subredditNameTextView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + rulesButton.setOnClickListener(view -> { + if (subredditName == null) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(this, RulesActivity.class); + if (subredditIsUser) { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + startActivity(intent); + } + }); + + flairTextView.setOnClickListener(view -> { + if (flair == null) { + mFlairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); + mFlairSelectionBottomSheetFragment.setArguments(bundle); + mFlairSelectionBottomSheetFragment.show(getSupportFragmentManager(), mFlairSelectionBottomSheetFragment.getTag()); + } else { + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + }); + + spoilerTextView.setOnClickListener(view -> { + if (!isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + isSpoiler = true; + } else { + spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + spoilerTextView.setTextColor(primaryTextColor); + isSpoiler = false; + } + }); + + nsfwTextView.setOnClickListener(view -> { + if (!isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + isNSFW = true; + } else { + nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + nsfwTextView.setTextColor(primaryTextColor); + isNSFW = false; + } + }); + + captureFab.setOnClickListener(view -> { + Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + if (takeVideoIntent.resolveActivity(getPackageManager()) != null) { + startActivityForResult(takeVideoIntent, CAPTURE_VIDEO_REQUEST_CODE); + } + }); + + selectFromLibraryFab.setOnClickListener(view -> { + Intent intent = new Intent(); + intent.setType("video/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, resources.getString(R.string.select_from_gallery)), PICK_VIDEO_REQUEST_CODE); + }); + + selectAgainTextView.setOnClickListener(view -> { + wasPlaying = false; + player.setPlayWhenReady(false); + videoUri = null; + videoPlayerView.setVisibility(View.GONE); + selectAgainTextView.setVisibility(View.GONE); + constraintLayout.setVisibility(View.VISIBLE); + }); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + subredditNameTextView.setTextColor(secondaryTextColor); + rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); + rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + divider3.setBackgroundColor(dividerColor); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); + flairTextColor = mCustomThemeWrapper.getFlairTextColor(); + spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); + spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); + nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); + nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); + flairTextView.setTextColor(primaryTextColor); + spoilerTextView.setTextColor(primaryTextColor); + nsfwTextView.setTextColor(primaryTextColor); + titleEditText.setTextColor(primaryTextColor); + titleEditText.setHintTextColor(secondaryTextColor); + applyFABTheme(captureFab); + applyFABTheme(selectFromLibraryFab); + selectAgainTextView.setTextColor(mCustomThemeWrapper.getColorAccent()); + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + }).execute(); + } + + private void loadVideo() { + constraintLayout.setVisibility(View.GONE); + selectAgainTextView.setVisibility(View.VISIBLE); + videoPlayerView.setVisibility(View.VISIBLE); + player.prepare(new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(videoUri)); + player.setPlayWhenReady(true); + wasPlaying = true; + } + + private void displaySubredditIcon() { + if (iconUrl != null && !iconUrl.equals("")) { + 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(iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + private void loadSubredditIcon() { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { + iconUrl = iconImageUrl; + displaySubredditIcon(); + loadSubredditIconSuccessful = true; + }).execute(); + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.post_video_activity, menu); + applyMenuItemTheme(menu); + mMemu = menu; + if (isPosting) { + mMemu.findItem(R.id.action_send_post_video_activity).setEnabled(false); + mMemu.findItem(R.id.action_send_post_video_activity).getIcon().setAlpha(130); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + return true; + } else { + if (!titleEditText.getText().toString().equals("") || videoUri != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + return true; + } + } + finish(); + return true; + case R.id.action_send_post_video_activity: + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (videoUri == null) { + Snackbar.make(coordinatorLayout, R.string.select_an_image, Snackbar.LENGTH_SHORT).show(); + return true; + } + + isPosting = true; + + item.setEnabled(false); + item.getIcon().setAlpha(130); + + mPostingSnackbar.show(); + + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } + + Intent intent = new Intent(this, SubmitPostService.class); + intent.setData(videoUri); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_VIDEO); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + + return true; + } + + return false; + } + + @Override + public void onBackPressed() { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + } else { + if (!titleEditText.getText().toString().equals("") || videoUri != null) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } else { + finish(); + } + } + } + + @Override + protected void onStart() { + super.onStart(); + if (wasPlaying) { + player.setPlayWhenReady(true); + } + } + + @Override + protected void onStop() { + super.onStop(); + player.setPlayWhenReady(false); + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putString(SUBREDDIT_ICON_STATE, iconUrl); + outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + if (videoUri != null) { + outState.putString(VIDEO_URI_STATE, videoUri.toString()); + } + outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); + outState.putBoolean(IS_POSTING_STATE, isPosting); + outState.putParcelable(FLAIR_STATE, flair); + outState.putBoolean(IS_SPOILER_STATE, isSpoiler); + outState.putBoolean(IS_NSFW_STATE, isNSFW); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + if (data != null) { + subredditName = data.getStringExtra(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + iconUrl = data.getStringExtra(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + subredditSelected = true; + subredditIsUser = data.getBooleanExtra(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER, false); + + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + displaySubredditIcon(); + + flairTextView.setVisibility(View.VISIBLE); + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + } + } else if (requestCode == PICK_VIDEO_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + if (data == null) { + Snackbar.make(coordinatorLayout, R.string.error_getting_video, Snackbar.LENGTH_SHORT).show(); + return; + } + + videoUri = data.getData(); + loadVideo(); + } + } else if (requestCode == CAPTURE_VIDEO_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + if (data != null && data.getData() != null) { + videoUri = data.getData(); + loadVideo(); + } else { + Snackbar.make(coordinatorLayout, R.string.error_getting_video, Snackbar.LENGTH_SHORT).show(); + } + } + } + } + + @Override + protected void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + player.release(); + } + + @Override + public void flairSelected(Flair flair) { + this.flair = flair; + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onSubmitVideoPostEvent(SubmitVideoOrGifPostEvent submitVideoOrGifPostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + mMemu.findItem(R.id.action_send_post_video_activity).setEnabled(true); + mMemu.findItem(R.id.action_send_post_video_activity).getIcon().setAlpha(255); + + if (submitVideoOrGifPostEvent.postSuccess) { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, + mAccountName); + startActivity(intent); + finish(); + } else if (submitVideoOrGifPostEvent.errorProcessingVideoOrGif) { + Snackbar.make(coordinatorLayout, R.string.error_processing_video, Snackbar.LENGTH_SHORT).show(); + } else { + if (submitVideoOrGifPostEvent.errorMessage == null || submitVideoOrGifPostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitVideoOrGifPostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitVideoOrGifPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java new file mode 100644 index 00000000..cc414325 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ReportActivity.java @@ -0,0 +1,219 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.snackbar.Snackbar; +import com.r0adkll.slidr.Slidr; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.ReportReasonRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FetchRules; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.ReportReason; +import ml.docilealligator.infinityforreddit.ReportThing; +import ml.docilealligator.infinityforreddit.Rule; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class ReportActivity extends BaseActivity { + + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + public static final String EXTRA_THING_FULLNAME = "ETF"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String GENERAL_REASONS_STATE = "GRS"; + private static final String RULES_REASON_STATE = "RRS"; + + @BindView(R.id.coordinator_layout_report_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_report_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_report_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_report_activity) + RecyclerView recyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mFullname; + private String mSubredditName; + private ArrayList generalReasons; + private ArrayList rulesReasons; + private ReportReasonRecyclerViewAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_report); + + ButterKnife.bind(this); + + 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); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mFullname = getIntent().getStringExtra(EXTRA_THING_FULLNAME); + mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + + generalReasons = savedInstanceState.getParcelableArrayList(GENERAL_REASONS_STATE); + rulesReasons = savedInstanceState.getParcelableArrayList(RULES_REASON_STATE); + } else { + getCurrentAccount(); + } + + if (generalReasons != null) { + mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, generalReasons); + } else { + mAdapter = new ReportReasonRecyclerViewAdapter(mCustomThemeWrapper, ReportReason.getGeneralReasons(this)); + } + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(mAdapter); + + if (rulesReasons == null) { + FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + @Override + public void success(ArrayList rules) { + mAdapter.setRules(ReportReason.convertRulesToReasons(rules)); + } + + @Override + public void failed() { + Snackbar.make(coordinatorLayout, R.string.error_loading_rules_without_retry, Snackbar.LENGTH_SHORT).show(); + } + }); + } else { + mAdapter.setRules(rulesReasons); + } + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + }).execute(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.report_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_send_report_activity: + ReportReason reportReason = mAdapter.getSelectedReason(); + if (reportReason != null) { + Toast.makeText(ReportActivity.this, R.string.reporting, Toast.LENGTH_SHORT).show(); + ReportThing.reportThing(mOauthRetrofit, mAccessToken, mFullname, mSubredditName, + reportReason.getReasonType(), reportReason.getReportReason(), new ReportThing.ReportThingListener() { + @Override + public void success() { + Toast.makeText(ReportActivity.this, R.string.report_successful, Toast.LENGTH_SHORT).show(); + finish(); + } + + @Override + public void failed() { + Toast.makeText(ReportActivity.this, R.string.report_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + Toast.makeText(ReportActivity.this, R.string.report_reason_not_selected, Toast.LENGTH_SHORT).show(); + } + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + if (mAdapter != null) { + outState.putParcelableArrayList(GENERAL_REASONS_STATE, mAdapter.getGeneralReasons()); + outState.putParcelableArrayList(RULES_REASON_STATE, mAdapter.getRules()); + } + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java new file mode 100644 index 00000000..0e3021e9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/RulesActivity.java @@ -0,0 +1,295 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.RulesRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.FetchRules; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.Rule; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class RulesActivity extends BaseActivity { + + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + + @BindView(R.id.coordinator_layout_rules_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_rules_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_rules_activity) + Toolbar toolbar; + @BindView(R.id.progress_bar_rules_activity) + ProgressBar progressBar; + @BindView(R.id.recycler_view_rules_activity) + RecyclerView recyclerView; + @BindView(R.id.error_text_view_rules_activity) + TextView errorTextView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String mSubredditName; + private RulesRecyclerViewAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_rules); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + + int navBarHeight = getNavBarHeight(); + if (navBarHeight > 0) { + recyclerView.setPadding(0, 0, 0, navBarHeight); + } + } + } + + appBarLayout.setBackgroundColor(mCustomThemeWrapper.getColorPrimary()); + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mSubredditName = getIntent().getExtras().getString(EXTRA_SUBREDDIT_NAME); + + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + mAdapter = new RulesRecyclerViewAdapter(this, mCustomThemeWrapper); + recyclerView.setAdapter(mAdapter); + + //fetchRules(); + + FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + @Override + public void success(ArrayList rules) { + progressBar.setVisibility(View.GONE); + if (rules == null || rules.size() == 0) { + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.no_rule); + errorTextView.setOnClickListener(view -> { + }); + } + mAdapter.changeDataset(rules); + } + + @Override + public void failed() { + displayError(); + } + }); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorAccent())); + errorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + } + + /*private void fetchRules() { + progressBar.setVisibility(View.VISIBLE); + errorTextView.setVisibility(View.GONE); + + RedditAPI api = mRetrofit.create(RedditAPI.class); + Call rulesCall = api.getRules(mSubredditName); + rulesCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseRulesAsyncTask(response.body(), new ParseRulesAsyncTask.ParseRulesAsyncTaskListener() { + @Override + public void parseSuccessful(ArrayList rules) { + progressBar.setVisibility(View.GONE); + if (rules == null || rules.size() == 0) { + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.no_rule); + errorTextView.setOnClickListener(view -> { + }); + } + mAdapter.changeDataset(rules); + } + + @Override + public void parseFailed() { + displayError(); + } + }).execute(); + } else { + displayError(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + displayError(); + } + }); + }*/ + + private void displayError() { + progressBar.setVisibility(View.GONE); + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.error_loading_rules); + errorTextView.setOnClickListener(view -> { + progressBar.setVisibility(View.VISIBLE); + errorTextView.setVisibility(View.GONE); + FetchRules.fetchRules(mRetrofit, mSubredditName, new FetchRules.FetchRulesListener() { + @Override + public void success(ArrayList rules) { + progressBar.setVisibility(View.GONE); + if (rules == null || rules.size() == 0) { + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.no_rule); + errorTextView.setOnClickListener(view -> { + }); + } + mAdapter.changeDataset(rules); + } + + @Override + public void failed() { + displayError(); + } + }); + }); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + /*private static class ParseRulesAsyncTask extends AsyncTask, ArrayList> { + private String response; + private ParseRulesAsyncTaskListener parseRulesAsyncTaskListener; + + ParseRulesAsyncTask(String response, ParseRulesAsyncTaskListener parseRulesAsyncTaskListener) { + this.response = response; + this.parseRulesAsyncTaskListener = parseRulesAsyncTaskListener; + } + + @Override + protected ArrayList doInBackground(Void... voids) { + try { + JSONArray rulesArray = new JSONObject(response).getJSONArray(JSONUtils.RULES_KEY); + ArrayList rules = new ArrayList<>(); + for (int i = 0; i < rulesArray.length(); i++) { + String shortName = rulesArray.getJSONObject(i).getString(JSONUtils.SHORT_NAME_KEY); + String description = null; + if (rulesArray.getJSONObject(i).has(JSONUtils.DESCRIPTION_KEY)) { + description = Utils.modifyMarkdown(rulesArray.getJSONObject(i).getString(JSONUtils.DESCRIPTION_KEY)); + } + rules.add(new Rule(shortName, description)); + } + return rules; + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(ArrayList rules) { + if (rules != null) { + parseRulesAsyncTaskListener.parseSuccessful(rules); + } else { + parseRulesAsyncTaskListener.parseFailed(); + } + } + + interface ParseRulesAsyncTaskListener { + void parseSuccessful(ArrayList rules); + + void parseFailed(); + } + }*/ +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java new file mode 100644 index 00000000..b0b96ccb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchActivity.java @@ -0,0 +1,391 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.drawable.ColorDrawable; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.RelativeLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.ferfalk.simplesearchview.SimpleSearchView; +import com.google.android.material.appbar.AppBarLayout; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.SearchActivityRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.recentsearchquery.DeleteRecentSearchQuery; +import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQuery; +import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQueryViewModel; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class SearchActivity extends BaseActivity { + + static final String EXTRA_QUERY = "EQ"; + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + static final String EXTRA_SUBREDDIT_IS_USER = "ESIU"; + static final String EXTRA_SEARCH_ONLY_SUBREDDITS = "ESOS"; + static final String EXTRA_RETURN_SUBREDDIT_NAME = "ERSN"; + static final String EXTRA_RETURN_SUBREDDIT_ICON_URL = "ERSIURL"; + + private static final String NULL_ACCOUNT_NAME_STATE = "NANS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 1; + + @BindView(R.id.coordinator_layout_search_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_search_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar) + Toolbar toolbar; + @BindView(R.id.search_view_search_activity) + SimpleSearchView simpleSearchView; + @BindView(R.id.subreddit_name_relative_layout_search_activity) + RelativeLayout subredditNameRelativeLayout; + @BindView(R.id.search_in_text_view_search_activity) + TextView searchInTextView; + @BindView(R.id.subreddit_name_text_view_search_activity) + TextView subredditNameTextView; + @BindView(R.id.divider_search_activity) + View divider; + @BindView(R.id.recent_summary_text_view_search_activity) + TextView recentSummaryTextView; + @BindView(R.id.recycler_view_search_activity) + RecyclerView recyclerView; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccountName = false; + private String mAccountName; + private String query; + private String subredditName; + private boolean subredditIsUser; + private boolean searchOnlySubreddits; + private SearchActivityRecyclerViewAdapter adapter; + RecentSearchQueryViewModel mRecentSearchQueryViewModel; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_search); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + setSupportActionBar(toolbar); + + searchOnlySubreddits = getIntent().getBooleanExtra(EXTRA_SEARCH_ONLY_SUBREDDITS, false); + + simpleSearchView.setOnSearchViewListener(new SimpleSearchView.SearchViewListener() { + @Override + public void onSearchViewShown() { + + } + + @Override + public void onSearchViewClosed() { + finish(); + } + + @Override + public void onSearchViewShownAnimation() { + + } + + @Override + public void onSearchViewClosedAnimation() { + + } + }); + + simpleSearchView.setOnQueryTextListener(new SimpleSearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + search(query); + return true; + } + + @Override + public boolean onQueryTextChange(String newText) { + return false; + } + + @Override + public boolean onQueryTextCleared() { + return false; + } + }); + + if (savedInstanceState != null) { + mNullAccountName = savedInstanceState.getBoolean(NULL_ACCOUNT_NAME_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + + if (subredditName == null) { + subredditNameTextView.setText(R.string.all_subreddits); + } else { + subredditNameTextView.setText(subredditName); + } + + if (!mNullAccountName && mAccountName == null) { + getCurrentAccountAndInitializeViewPager(); + } else { + bindView(); + } + } else { + query = getIntent().getStringExtra(EXTRA_QUERY); + getCurrentAccountAndInitializeViewPager(); + } + + if (searchOnlySubreddits) { + subredditNameRelativeLayout.setVisibility(View.GONE); + } else { + subredditNameRelativeLayout.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + intent.putExtra(SubredditSelectionActivity.EXTRA_EXTRA_CLEAR_SELECTION, true); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + } + + Intent intent = getIntent(); + if (intent.hasExtra(EXTRA_SUBREDDIT_NAME)) { + subredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); + subredditNameTextView.setText(subredditName); + subredditIsUser = intent.getBooleanExtra(EXTRA_SUBREDDIT_IS_USER, false); + } + } + + private void getCurrentAccountAndInitializeViewPager() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccountName = true; + } else { + mAccountName = account.getUsername(); + } + bindView(); + }).execute(); + } + + private void bindView() { + if (mAccountName != null) { + adapter = new SearchActivityRecyclerViewAdapter(this, mCustomThemeWrapper, new SearchActivityRecyclerViewAdapter.ItemOnClickListener() { + @Override + public void onClick(String query) { + search(query); + } + + @Override + public void onDelete(RecentSearchQuery recentSearchQuery) { + DeleteRecentSearchQuery.deleteRecentSearchQueryListener(mRedditDataRoomDatabase, recentSearchQuery, () -> {}); + } + }); + recyclerView.setNestedScrollingEnabled(false); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(adapter); + mRecentSearchQueryViewModel = new ViewModelProvider(this, + new RecentSearchQueryViewModel.Factory(mRedditDataRoomDatabase, mAccountName)) + .get(RecentSearchQueryViewModel.class); + + mRecentSearchQueryViewModel.getAllRecentSearchQueries().observe(this, recentSearchQueries -> { + if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) { + divider.setVisibility(View.VISIBLE); + recentSummaryTextView.setVisibility(View.VISIBLE); + } else { + divider.setVisibility(View.GONE); + recentSummaryTextView.setVisibility(View.GONE); + } + adapter.setRecentSearchQueries(recentSearchQueries); + }); + } + } + + private void search(String query) { + if (searchOnlySubreddits) { + Intent intent = new Intent(SearchActivity.this, SearchSubredditsResultActivity.class); + intent.putExtra(SearchSubredditsResultActivity.EXTRA_QUERY, query); + startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); + } else { + Intent intent = new Intent(SearchActivity.this, SearchResultActivity.class); + intent.putExtra(SearchResultActivity.EXTRA_QUERY, query); + if (subredditName != null) { + if (subredditIsUser) { + intent.putExtra(SearchResultActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(SearchResultActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + } + startActivity(intent); + finish(); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + simpleSearchView.setSearchBackground(new ColorDrawable(mCustomThemeWrapper.getColorPrimary())); + int toolbarPrimaryTextAndIconColorColor = mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor(); + simpleSearchView.setIconsColor(toolbarPrimaryTextAndIconColorColor); + simpleSearchView.setTextColor(toolbarPrimaryTextAndIconColorColor); + simpleSearchView.setBackIconColor(toolbarPrimaryTextAndIconColorColor); + simpleSearchView.setHintTextColor(mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); + int colorAccent = mCustomThemeWrapper.getColorAccent(); + searchInTextView.setTextColor(colorAccent); + subredditNameTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); + divider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); + recentSummaryTextView.setTextColor(colorAccent); + } + + @Override + protected void onStart() { + super.onStart(); + simpleSearchView.showSearch(false); + simpleSearchView.getSearchEditText().requestFocus(); + + if (query != null) { + simpleSearchView.getSearchEditText().setText(query); + simpleSearchView.getSearchEditText().setSelection(query.length()); + query = null; + } + + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + } + + @Override + protected void onPause() { + super.onPause(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.hideSoftInputFromWindow(simpleSearchView.getSearchEditText().getWindowToken(), 0); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + if (simpleSearchView.onActivityResult(requestCode, resultCode, data)) { + return; + } + + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); + + if (subredditName == null) { + subredditNameTextView.setText(R.string.all_subreddits); + } else { + subredditNameTextView.setText(subredditName); + } + } + } else if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + String name = data.getExtras().getString(SearchSubredditsResultActivity.EXTRA_RETURN_SUBREDDIT_NAME); + String iconUrl = data.getExtras().getString(SearchSubredditsResultActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } + } + + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.search_activity, menu); + simpleSearchView.setMenuItem(menu.findItem(R.id.action_search_search_activity)); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCOUNT_NAME_STATE, mNullAccountName); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java new file mode 100644 index 00000000..249e6ed2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java @@ -0,0 +1,513 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +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.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SearchPostSortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SearchUserAndSubredditSortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.fragments.SubredditListingFragment; +import ml.docilealligator.infinityforreddit.fragments.UserListingFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.recentsearchquery.InsertRecentSearchQuery; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; + +public class SearchResultActivity extends BaseActivity implements SortTypeSelectionCallback, + PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { + static final String EXTRA_QUERY = "QK"; + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String INSERT_SEARCH_QUERY_SUCCESS_STATE = "ISQSS"; + @BindView(R.id.coordinator_layout_search_result_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_search_result_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_search_result_activity) + Toolbar toolbar; + @BindView(R.id.tab_layout_search_result_activity) + TabLayout tabLayout; + @BindView(R.id.view_pager_search_result_activity) + ViewPager2 viewPager2; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String mQuery; + private String mSubredditName; + private boolean mInsertSearchQuerySuccess; + private FragmentManager fragmentManager; + private SectionsPagerAdapter sectionsPagerAdapter; + private SearchPostSortTypeBottomSheetFragment searchPostSortTypeBottomSheetFragment; + private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; + private SearchUserAndSubredditSortTypeBottomSheetFragment searchUserAndSubredditSortTypeBottomSheetFragment; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + private SlidrInterface mSlidrInterface; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_search_result); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + // Get the intent, verify the action and get the query + Intent intent = getIntent(); + String query = intent.getStringExtra(EXTRA_QUERY); + + mSubredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); + + if (query != null) { + mQuery = query; + setTitle(query); + } + + fragmentManager = getSupportFragmentManager(); + + if (savedInstanceState == null) { + getCurrentAccountAndInitializeViewPager(); + } else { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + mInsertSearchQuerySuccess = savedInstanceState.getBoolean(INSERT_SEARCH_QUERY_SUCCESS_STATE); + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndInitializeViewPager(); + } else { + initializeViewPager(); + } + } + + searchPostSortTypeBottomSheetFragment = new SearchPostSortTypeBottomSheetFragment(); + Bundle bundle = new Bundle(); + searchPostSortTypeBottomSheetFragment.setArguments(bundle); + + sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); + + searchUserAndSubredditSortTypeBottomSheetFragment = new SearchUserAndSubredditSortTypeBottomSheetFragment(); + + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + } + + @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()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + applyTabLayoutTheme(tabLayout); + } + + private void getCurrentAccountAndInitializeViewPager() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + initializeViewPager(); + }).execute(); + } + + private void initializeViewPager() { + sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(3); + viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + sectionsPagerAdapter.displaySortTypeInToolbar(); + if (position == 0) { + unlockSwipeRightToGoBack(); + } else { + lockSwipeRightToGoBack(); + } + } + }); + new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { + switch (position) { + case 0: + tab.setText(R.string.posts); + break; + case 1: + tab.setText(R.string.subreddits); + break; + case 2: + tab.setText(R.string.users); + break; + } + }).attach(); + fixViewPager2Sensitivity(viewPager2); + + if (mAccountName != null && !mInsertSearchQuerySuccess && mQuery != null) { + InsertRecentSearchQuery.insertRecentSearchQueryListener(mRedditDataRoomDatabase, mAccountName, + mQuery, () -> mInsertSearchQuerySuccess = true); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.search_result_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + onBackPressed(); + return true; + case R.id.action_sort_search_result_activity: + switch (viewPager2.getCurrentItem()) { + case 0: { + searchPostSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchPostSortTypeBottomSheetFragment.getTag()); + break; + } + case 1: + case 2: + Bundle bundle = new Bundle(); + bundle.putInt(SearchUserAndSubredditSortTypeBottomSheetFragment.EXTRA_FRAGMENT_POSITION, viewPager2.getCurrentItem()); + searchUserAndSubredditSortTypeBottomSheetFragment.setArguments(bundle); + searchUserAndSubredditSortTypeBottomSheetFragment.show(getSupportFragmentManager(), searchUserAndSubredditSortTypeBottomSheetFragment.getTag()); + break; + } + return true; + case R.id.action_search_search_result_activity: + Intent intent = new Intent(this, SearchActivity.class); + if (mSubredditName != null && !mSubredditName.equals("")) { + intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, mSubredditName); + } + intent.putExtra(SearchActivity.EXTRA_QUERY, mQuery); + finish(); + startActivity(intent); + return true; + case R.id.action_refresh_search_result_activity: + sectionsPagerAdapter.refresh(); + return true; + case R.id.action_change_post_layout_search_result_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + } + return super.onOptionsItemSelected(item); + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putBoolean(INSERT_SEARCH_QUERY_SUCCESS_STATE, mInsertSearchQuerySuccess); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + public void sortTypeSelected(SortType sortType) { + sectionsPagerAdapter.changeSortType(sortType); + } + + @Override + public void sortTypeSelected(String sortType) { + Bundle bundle = new Bundle(); + bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); + sortTimeBottomSheetFragment.setArguments(bundle); + sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); + } + + @Override + public void searchUserAndSubredditSortTypeSelected(SortType sortType, int fragmentPosition) { + sectionsPagerAdapter.changeSortType(sortType, fragmentPosition); + } + + @Override + public void postLayoutSelected(int postLayout) { + sectionsPagerAdapter.changePostLayout(postLayout); + } + + @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 displaySortType() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.displaySortTypeInToolbar(); + } + } + + private class SectionsPagerAdapter extends FragmentStateAdapter { + + public SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { + super(fm, lifecycle); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + switch (position) { + case 0: { + PostFragment mFragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SEARCH); + bundle.putString(PostFragment.EXTRA_NAME, mSubredditName); + bundle.putString(PostFragment.EXTRA_QUERY, mQuery); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + mFragment.setArguments(bundle); + return mFragment; + } + case 1: { + SubredditListingFragment mFragment = new SubredditListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(SubredditListingFragment.EXTRA_QUERY, mQuery); + bundle.putBoolean(SubredditListingFragment.EXTRA_IS_POSTING, false); + bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + mFragment.setArguments(bundle); + return mFragment; + } + default: { + UserListingFragment mFragment = new UserListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(UserListingFragment.EXTRA_QUERY, mQuery); + bundle.putString(UserListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(UserListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + mFragment.setArguments(bundle); + return mFragment; + } + } + } + + @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; + } + + void changeSortType(SortType sortType) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeSortType(sortType); + displaySortTypeInToolbar(); + } + } + + void changeSortType(SortType sortType, int fragmentPosition) { + Fragment fragment = fragmentManager.findFragmentByTag("f" + fragmentPosition); + if (fragment instanceof SubredditListingFragment) { + ((SubredditListingFragment) fragment).changeSortType(sortType); + } else if (fragment instanceof UserListingFragment) { + ((UserListingFragment) fragment).changeSortType(sortType); + } + displaySortTypeInToolbar(); + } + + public void refresh() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) fragment).refresh(); + } + } + + void changeNSFW(boolean nsfw) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeNSFW(nsfw); + } + } + + void changePostLayout(int postLayout) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changePostLayout(postLayout); + } + } + + void goBackToTop() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).goBackToTop(); + } else if (fragment instanceof SubredditListingFragment) { + ((SubredditListingFragment) fragment).goBackToTop(); + } else if (fragment instanceof UserListingFragment) { + ((UserListingFragment) fragment).goBackToTop(); + } + } + + void displaySortTypeInToolbar() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + SortType sortType = ((PostFragment) fragment).getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } else if (fragment instanceof SubredditListingFragment) { + SortType sortType = ((SubredditListingFragment) fragment).getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } else if (fragment instanceof UserListingFragment) { + SortType sortType = ((UserListingFragment) fragment).getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } + } + + @Override + public int getItemCount() { + return 3; + } + } + + private void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + private void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchSubredditsResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchSubredditsResultActivity.java new file mode 100644 index 00000000..21ebd255 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchSubredditsResultActivity.java @@ -0,0 +1,205 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; + +import com.google.android.material.appbar.AppBarLayout; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.SubredditListingFragment; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class SearchSubredditsResultActivity extends BaseActivity implements ActivityToolbarInterface { + + static final String EXTRA_QUERY = "EQ"; + static final String EXTRA_RETURN_SUBREDDIT_NAME = "ERSN"; + static final String EXTRA_RETURN_SUBREDDIT_ICON_URL = "ERSIURL"; + + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String FRAGMENT_OUT_STATE = "FOS"; + + @BindView(R.id.coordinator_layout_search_subreddits_result_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_search_subreddits_result_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_search_subreddits_result_activity) + Toolbar toolbar; + Fragment mFragment; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_search_subreddits_result); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + String query = getIntent().getExtras().getString(EXTRA_QUERY); + + if (savedInstanceState == null) { + getCurrentAccountAndInitializeFragment(query); + } else { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndInitializeFragment(query); + } else { + mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_search_subreddits_result_activity, mFragment).commit(); + } + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + private void getCurrentAccountAndInitializeFragment(String query) { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + + mFragment = new SubredditListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(SubredditListingFragment.EXTRA_QUERY, query); + bundle.putBoolean(SubredditListingFragment.EXTRA_IS_POSTING, true); + bundle.putString(SubredditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(SubredditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + mFragment.setArguments(bundle); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_search_subreddits_result_activity, mFragment).commit(); + }).execute(); + } + + public void getSelectedSubreddit(String name, String iconUrl) { + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Override + public void onLongPress() { + if (mFragment != null) { + ((SubredditListingFragment) mFragment).goBackToTop(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java new file mode 100644 index 00000000..886a1cd4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectUserFlairActivity.java @@ -0,0 +1,261 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.r0adkll.slidr.Slidr; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.adapters.UserFlairRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FetchUserFlairs; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SelectUserFlair; +import ml.docilealligator.infinityforreddit.UserFlair; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class SelectUserFlairActivity extends BaseActivity implements ActivityToolbarInterface { + + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String USER_FLAIRS_STATE = "UFS"; + + @BindView(R.id.coordinator_layout_select_user_flair_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_select_user_flair_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_select_user_flair_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_select_user_flair_activity) + RecyclerView recyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private LinearLayoutManager mLinearLayoutManager; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private ArrayList mUserFlairs; + private String mSubredditName; + private UserFlairRecyclerViewAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_select_user_flair); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + setTitle(mSubredditName); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + mUserFlairs = savedInstanceState.getParcelableArrayList(USER_FLAIRS_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + getCurrentAccountAndBindView(); + } + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + bindView(); + }).execute(); + } + + private void bindView() { + if (mUserFlairs == null) { + FetchUserFlairs.fetchUserFlairsInSubreddit(mOauthRetrofit, mAccessToken, mSubredditName, + new FetchUserFlairs.FetchUserFlairsInSubredditListener() { + @Override + public void fetchSuccessful(ArrayList userFlairs) { + mUserFlairs = userFlairs; + instantiateRecyclerView(); + } + + @Override + public void fetchFailed() { + + } + }); + } else { + instantiateRecyclerView(); + } + } + + private void instantiateRecyclerView() { + mAdapter = new UserFlairRecyclerViewAdapter(mCustomThemeWrapper, mUserFlairs, (userFlair, editUserFlair) -> { + if (editUserFlair) { + View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_flair, null); + EditText flairEditText = dialogView.findViewById(R.id.flair_edit_text_edit_flair_dialog); + flairEditText.setText(userFlair.getText()); + flairEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.edit_flair) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); + } + userFlair.setText(flairEditText.getText().toString()); + selectUserFlair(userFlair); + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); + } + }) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); + } + }) + .show(); + } else { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.select_this_user_flair) + .setMessage(userFlair.getText()) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> selectUserFlair(userFlair)) + .setNegativeButton(R.string.no, null) + .show(); + } + }); + mLinearLayoutManager = new LinearLayoutManager(SelectUserFlairActivity.this); + recyclerView.setLayoutManager(mLinearLayoutManager); + recyclerView.setAdapter(mAdapter); + } + + private void selectUserFlair(UserFlair userFlair) { + SelectUserFlair.selectUserFlair(mOauthRetrofit, mAccessToken, userFlair, mSubredditName, mAccountName, + new SelectUserFlair.SelectUserFlairListener() { + @Override + public void success() { + Toast.makeText(SelectUserFlairActivity.this, R.string.select_user_flair_success, Toast.LENGTH_SHORT).show(); + finish(); + } + + @Override + public void failed(String errorMessage) { + if (errorMessage == null || errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.select_user_flair_success, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); + } + } + }); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putParcelableArrayList(USER_FLAIRS_STATE, mUserFlairs); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + @Override + public void onLongPress() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsActivity.java new file mode 100644 index 00000000..f6100535 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SelectedSubredditsActivity.java @@ -0,0 +1,175 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.r0adkll.slidr.Slidr; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.adapters.SelectedSubredditsRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class SelectedSubredditsActivity extends BaseActivity implements ActivityToolbarInterface { + + public static final String EXTRA_SELECTED_SUBREDDITS = "ESS"; + public static final String EXTRA_RETURN_SELECTED_SUBREDDITS = "ERSS"; + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 1; + private static final String SELECTED_SUBREDDITS_STATE = "SSS"; + + @BindView(R.id.coordinator_layout_selected_subreddits_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_selected_subreddits_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_selected_subreddits_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_selected_subreddits_activity) + RecyclerView recyclerView; + @BindView(R.id.fab_selected_subreddits_activity) + FloatingActionButton fab; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private LinearLayoutManager linearLayoutManager; + private SelectedSubredditsRecyclerViewAdapter adapter; + private ArrayList subreddits; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_selected_subreddits); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + if (savedInstanceState != null) { + subreddits = savedInstanceState.getStringArrayList(SELECTED_SUBREDDITS_STATE); + } else { + subreddits = getIntent().getStringArrayListExtra(EXTRA_SELECTED_SUBREDDITS); + } + + adapter = new SelectedSubredditsRecyclerViewAdapter(mCustomThemeWrapper, subreddits); + linearLayoutManager = new LinearLayoutManager(this); + recyclerView.setLayoutManager(linearLayoutManager); + recyclerView.setAdapter(adapter); + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (dy > 0) { + fab.hide(); + } else { + fab.show(); + } + } + }); + + fab.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditMultiselectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.selected_subreddits_activity, menu); + 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_selected_subreddits_activity) { + if (adapter != null) { + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_RETURN_SELECTED_SUBREDDITS, adapter.getSubreddits()); + setResult(Activity.RESULT_OK, returnIntent); + } + finish(); + } + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE && resultCode == RESULT_OK) { + if (data != null) { + if (subreddits == null) { + subreddits = new ArrayList<>(); + } + subreddits = data.getStringArrayListExtra(SubredditMultiselectionActivity.EXTRA_RETURN_SELECTED_SUBREDDITS); + adapter.addSubreddits(subreddits); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + if (adapter != null) { + outState.putStringArrayList(SELECTED_SUBREDDITS_STATE, adapter.getSubreddits()); + } + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + applyFABTheme(fab); + } + + @Override + public void onLongPress() { + if (linearLayoutManager != null) { + linearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SendPrivateMessageActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SendPrivateMessageActivity.java new file mode 100644 index 00000000..da04e142 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SendPrivateMessageActivity.java @@ -0,0 +1,210 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.snackbar.Snackbar; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.ComposeMessage; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import retrofit2.Retrofit; + +public class SendPrivateMessageActivity extends BaseActivity { + public static final String EXTRA_RECIPIENT_USERNAME = "ERU"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + @BindView(R.id.coordinator_layout_send_private_message_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_send_private_message_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_send_private_message_activity) + Toolbar toolbar; + @BindView(R.id.username_edit_text_send_private_message_activity) + EditText usernameEditText; + @BindView(R.id.divider_1_send_private_message_activity) + View divider1; + @BindView(R.id.subjet_edit_text_send_private_message_activity) + EditText subjectEditText; + @BindView(R.id.divider_2_send_private_message_activity) + View divider2; + @BindView(R.id.content_edit_text_send_private_message_activity) + EditText messageEditText; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private boolean isSubmitting = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_send_private_message); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (savedInstanceState == null) { + getCurrentAccount(); + } else { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + } + + setSupportActionBar(toolbar); + + String username = getIntent().getStringExtra(EXTRA_RECIPIENT_USERNAME); + if (username != null) { + usernameEditText.setText(username); + } + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + }).execute(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.send_private_message_activity, menu); + 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_send_send_private_message_activity) { + if (!isSubmitting) { + isSubmitting = true; + if (usernameEditText.getText() == null || usernameEditText.getText().toString().equals("")) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.message_username_required, Snackbar.LENGTH_LONG).show(); + return true; + } + + if (subjectEditText.getText() == null || subjectEditText.getText().toString().equals("")) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.message_subject_required, Snackbar.LENGTH_LONG).show(); + return true; + } + + if (messageEditText.getText() == null || messageEditText.getText().toString().equals("")) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.message_content_required, Snackbar.LENGTH_LONG).show(); + return true; + } + + item.setEnabled(false); + item.getIcon().setAlpha(130); + Snackbar sendingSnackbar = Snackbar.make(coordinatorLayout, R.string.sending_message, Snackbar.LENGTH_INDEFINITE); + sendingSnackbar.show(); + + ComposeMessage.composeMessage(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale, + usernameEditText.getText().toString(), subjectEditText.getText().toString(), + messageEditText.getText().toString(), new ComposeMessage.ComposeMessageListener() { + @Override + public void composeMessageSuccess() { + isSubmitting = false; + item.setEnabled(true); + item.getIcon().setAlpha(255); + Toast.makeText(SendPrivateMessageActivity.this, R.string.send_message_success, Toast.LENGTH_SHORT).show(); + finish(); + } + + @Override + public void composeMessageFailed(String errorMessage) { + isSubmitting = false; + sendingSnackbar.dismiss(); + item.setEnabled(true); + item.getIcon().setAlpha(255); + + if (errorMessage == null || errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.send_message_failed, Snackbar.LENGTH_LONG).show(); + } else { + Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); + } + } + }); + } + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + usernameEditText.setTextColor(primaryTextColor); + subjectEditText.setTextColor(primaryTextColor); + messageEditText.setTextColor(primaryTextColor); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + usernameEditText.setHintTextColor(secondaryTextColor); + subjectEditText.setHintTextColor(secondaryTextColor); + messageEditText.setHintTextColor(secondaryTextColor); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SettingsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SettingsActivity.java new file mode 100644 index 00000000..f9c8c39e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SettingsActivity.java @@ -0,0 +1,194 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.fragment.app.Fragment; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import com.google.android.material.appbar.AppBarLayout; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.settings.AboutPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.CustomizeBottomAppBarFragment; +import ml.docilealligator.infinityforreddit.settings.CustomizeMainPageTabsFragment; +import ml.docilealligator.infinityforreddit.settings.FontPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.GesturesAndButtonsPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.InterfacePreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.MainPreferenceFragment; +import ml.docilealligator.infinityforreddit.settings.NsfwAndBlurringFragment; + +public class SettingsActivity extends BaseActivity implements + PreferenceFragmentCompat.OnPreferenceStartFragmentCallback { + + private static final String TITLE_STATE = "TS"; + + @BindView(R.id.appbar_layout_settings_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_settings_activity) + Toolbar toolbar; + private boolean mNullAccountName; + private String mAccountName; + + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_settings); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + + getCurrentAccountAndBindView(savedInstanceState); + + getSupportFragmentManager().addOnBackStackChangedListener(() -> { + if (getSupportFragmentManager().getBackStackEntryCount() == 0) { + setTitle(R.string.settings_activity_label); + } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof AboutPreferenceFragment) { + setTitle(R.string.settings_about_master_title); + } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof InterfacePreferenceFragment) { + setTitle(R.string.settings_interface_title); + } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof FontPreferenceFragment) { + setTitle(R.string.settings_font_title); + } else if (getSupportFragmentManager().findFragmentById(R.id.frame_layout_settings_activity) instanceof GesturesAndButtonsPreferenceFragment) { + setTitle(R.string.settings_gestures_and_buttons_title); + } + }); + } + + private void getCurrentAccountAndBindView(Bundle savedInstanceState) { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (getSupportFragmentManager().isDestroyed()) { + return; + } + if (account == null) { + mNullAccountName = true; + } else { + mAccountName = account.getUsername(); + } + + if (savedInstanceState == null) { + getSupportFragmentManager() + .beginTransaction() + .replace(R.id.frame_layout_settings_activity, new MainPreferenceFragment()) + .commit(); + } else { + setTitle(savedInstanceState.getCharSequence(TITLE_STATE)); + } + }).execute(); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } + return false; + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putCharSequence(TITLE_STATE, getTitle()); + } + + @Override + public boolean onSupportNavigateUp() { + if (getSupportFragmentManager().popBackStackImmediate()) { + return true; + } + return super.onSupportNavigateUp(); + } + + @Override + public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) { + // Instantiate the new Fragment + final Bundle args = pref.getExtras(); + final Fragment fragment = getSupportFragmentManager().getFragmentFactory().instantiate( + getClassLoader(), + pref.getFragment()); + if (fragment instanceof CustomizeMainPageTabsFragment) { + args.putString(CustomizeMainPageTabsFragment.EXTRA_ACCOUNT_NAME, mAccountName); + } else if (fragment instanceof NsfwAndBlurringFragment) { + args.putString(NsfwAndBlurringFragment.EXTRA_ACCOUNT_NAME, mAccountName); + } else if (fragment instanceof CustomizeBottomAppBarFragment) { + args.putString(CustomizeBottomAppBarFragment.EXTRA_ACCOUNT_NAME, mAccountName); + } + fragment.setArguments(args); + fragment.setTargetFragment(caller, 0); + + getSupportFragmentManager().beginTransaction() + .setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right) + .replace(R.id.frame_layout_settings_activity, fragment) + .addToBackStack(null) + .commit(); + setTitle(pref.getTitle()); + return true; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onRecreateActivityEvent(RecreateActivityEvent recreateActivityEvent) { + recreate(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ShareDataResolverActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ShareDataResolverActivity.java new file mode 100644 index 00000000..c2fed537 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ShareDataResolverActivity.java @@ -0,0 +1,79 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.util.Patterns; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; + +import ml.docilealligator.infinityforreddit.R; + +public class ShareDataResolverActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Intent receivedIntent = getIntent(); + String action = receivedIntent.getAction(); + String type = receivedIntent.getType(); + + if (Intent.ACTION_SEND.equals(action) && type != null) { + if ("text/plain".equals(type)) { + String text = receivedIntent.getStringExtra(Intent.EXTRA_TEXT); + if (text != null) { + if (Patterns.WEB_URL.matcher(text).matches()) { + //It's a link + Intent intent = new Intent(this, PostLinkActivity.class); + intent.putExtra(PostLinkActivity.EXTRA_LINK, text); + startActivity(intent); + } else { + Intent intent = new Intent(this, PostTextActivity.class); + intent.putExtra(PostTextActivity.EXTRA_CONTENT, text); + startActivity(intent); + } + } else { + Toast.makeText(this, R.string.no_data_received, Toast.LENGTH_SHORT).show(); + } + } else if (type.equals("image/gif")) { + Uri videoUri = receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM); + if (videoUri != null) { + Intent intent = new Intent(this, PostVideoActivity.class); + intent.setData(videoUri); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(intent); + } else { + Toast.makeText(this, R.string.no_video_path_received, Toast.LENGTH_SHORT).show(); + } + } else if (type.startsWith("image/")) { + Uri imageUri = receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM); + if (imageUri != null) { + Intent intent = new Intent(this, PostImageActivity.class); + intent.setData(imageUri); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(intent); + } else { + Toast.makeText(this, R.string.no_image_path_received, Toast.LENGTH_SHORT).show(); + } + } else if (type.startsWith("video/")) { + Uri videoUri = receivedIntent.getParcelableExtra(Intent.EXTRA_STREAM); + if (videoUri != null) { + Intent intent = new Intent(this, PostVideoActivity.class); + intent.setData(videoUri); + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(intent); + } else { + Toast.makeText(this, R.string.no_video_path_received, Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(this, R.string.cannot_handle_intent, Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(this, R.string.cannot_handle_intent, Toast.LENGTH_SHORT).show(); + } + + finish(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java new file mode 100644 index 00000000..04c70dc4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubmitCrosspostActivity.java @@ -0,0 +1,623 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; + +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.davemorrissey.labs.subscaleview.ImageSource; +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.libRG.CustomTextView; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIconAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitCrosspostEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class SubmitCrosspostActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { + + public static final String EXTRA_POST = "EP"; + + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_ICON_STATE = "SIS"; + private static final String SUBREDDIT_SELECTED_STATE = "SSS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; + private static final String IS_POSTING_STATE = "IPS"; + private static final String FLAIR_STATE = "FS"; + private static final String IS_SPOILER_STATE = "ISS"; + private static final String IS_NSFW_STATE = "INS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + + @BindView(R.id.coordinator_layout_submit_crosspost_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_submit_crosspost_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_submit_crosspost_activity) + Toolbar toolbar; + @BindView(R.id.subreddit_icon_gif_image_view_submit_crosspost_activity) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_submit_crosspost_activity) + TextView subredditNameTextView; + @BindView(R.id.rules_button_submit_crosspost_activity) + Button rulesButton; + @BindView(R.id.divider_1_submit_crosspost_activity) + View divider1; + @BindView(R.id.flair_custom_text_view_submit_crosspost_activity) + CustomTextView flairTextView; + @BindView(R.id.spoiler_custom_text_view_submit_crosspost_activity) + CustomTextView spoilerTextView; + @BindView(R.id.nsfw_custom_text_view_submit_crosspost_activity) + CustomTextView nsfwTextView; + @BindView(R.id.divider_2_submit_crosspost_activity) + View divider2; + @BindView(R.id.post_title_edit_text_submit_crosspost_activity) + EditText titleEditText; + @BindView(R.id.divider_3_submit_crosspost_activity) + View divider3; + @BindView(R.id.post_content_text_view_submit_crosspost_activity) + TextView contentTextView; + @BindView(R.id.frame_layout_submit_crosspost_activity) + FrameLayout frameLayout; + @BindView(R.id.image_view_submit_crosspost_activity) + SubsamplingScaleImageView imageView; + @BindView(R.id.play_button_image_view_submit_crosspost_activity) + ImageView playButton; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private Post post; + private String iconUrl; + private String subredditName; + private boolean subredditSelected = false; + private boolean subredditIsUser; + private boolean loadSubredditIconSuccessful = true; + private boolean isPosting; + private int primaryTextColor; + private int flairBackgroundColor; + private int flairTextColor; + private int spoilerBackgroundColor; + private int spoilerTextColor; + private int nsfwBackgroundColor; + private int nsfwTextColor; + private Flair flair; + private boolean isSpoiler = false; + private boolean isNSFW = false; + private Resources resources; + private Menu mMenu; + private RequestManager mGlide; + private FlairBottomSheetFragment flairSelectionBottomSheetFragment; + private Snackbar mPostingSnackbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_submit_crosspost); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); + + resources = getResources(); + + post = getIntent().getParcelableExtra(EXTRA_POST); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccount(); + } + + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); + subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); + isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); + flair = savedInstanceState.getParcelable(FLAIR_STATE); + isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); + isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + + if (subredditName != null) { + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + if (!loadSubredditIconSuccessful) { + loadSubredditIcon(); + } + } + displaySubredditIcon(); + + if (isPosting) { + mPostingSnackbar.show(); + } + + if (flair != null) { + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + if (isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + } else { + getCurrentAccount(); + + isPosting = false; + + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + + if (post.isSpoiler()) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (post.isNSFW()) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + + titleEditText.setText(post.getTitle()); + } + + if (post.getPostType() == Post.TEXT_TYPE) { + contentTextView.setVisibility(View.VISIBLE); + contentTextView.setText(post.getSelfTextPlain()); + } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + contentTextView.setVisibility(View.VISIBLE); + contentTextView.setText(post.getUrl()); + } else if (post.getPostType() == Post.GIF_TYPE || post.getPostType() == Post.GALLERY_TYPE || post.getPostType() == Post.IMAGE_TYPE) { + Post.Preview preview = getPreview(post); + if (preview != null) { + frameLayout.setVisibility(View.VISIBLE); + mGlide.asBitmap().load(preview.getPreviewUrl()).into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + imageView.setImage(ImageSource.bitmap(resource)); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + } + } else if (post.getPostType() == Post.VIDEO_TYPE) { + Post.Preview preview = getPreview(post); + if (preview != null) { + frameLayout.setVisibility(View.VISIBLE); + mGlide.asBitmap().load(preview.getPreviewUrl()).into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + imageView.setImage(ImageSource.bitmap(resource)); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + playButton.setVisibility(View.VISIBLE); + } + } + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + subredditNameTextView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + rulesButton.setOnClickListener(view -> { + if (subredditName == null) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(this, RulesActivity.class); + if (subredditIsUser) { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + startActivity(intent); + } + }); + + flairTextView.setOnClickListener(view -> { + if (flair == null) { + flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + if (subredditIsUser) { + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); + } + flairSelectionBottomSheetFragment.setArguments(bundle); + flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); + } else { + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + }); + + spoilerTextView.setOnClickListener(view -> { + if (!isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + isSpoiler = true; + } else { + spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + spoilerTextView.setTextColor(primaryTextColor); + isSpoiler = false; + } + }); + + nsfwTextView.setOnClickListener(view -> { + if (!isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + isNSFW = true; + } else { + nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + nsfwTextView.setTextColor(primaryTextColor); + isNSFW = false; + } + }); + } + + @Nullable + private Post.Preview getPreview(Post post) { + ArrayList previews = post.getPreviews(); + if (previews != null && !previews.isEmpty()) { + return previews.get(0); + } + + return null; + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + subredditNameTextView.setTextColor(secondaryTextColor); + rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); + rulesButton.setBackgroundTintList(ColorStateList.valueOf(mCustomThemeWrapper.getColorPrimaryLightTheme())); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setBackgroundColor(dividerColor); + divider2.setBackgroundColor(dividerColor); + divider3.setBackgroundColor(dividerColor); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); + flairTextColor = mCustomThemeWrapper.getFlairTextColor(); + spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); + spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); + nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); + nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); + flairTextView.setTextColor(primaryTextColor); + spoilerTextView.setTextColor(primaryTextColor); + nsfwTextView.setTextColor(primaryTextColor); + titleEditText.setTextColor(primaryTextColor); + titleEditText.setHintTextColor(secondaryTextColor); + contentTextView.setTextColor(primaryTextColor); + contentTextView.setHintTextColor(secondaryTextColor); + } + + private void getCurrentAccount() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + }).execute(); + } + + private void displaySubredditIcon() { + if (iconUrl != null && !iconUrl.equals("")) { + 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(iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + private void loadSubredditIcon() { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, iconImageUrl -> { + iconUrl = iconImageUrl; + displaySubredditIcon(); + loadSubredditIconSuccessful = true; + }).execute(); + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.submit_crosspost_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + if (isPosting) { + mMenu.findItem(R.id.action_send_submit_crosspost_activity).setEnabled(false); + mMenu.findItem(R.id.action_send_submit_crosspost_activity).getIcon().setAlpha(130); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + return true; + } else { + if (!titleEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + return true; + } + } + finish(); + return true; + case R.id.action_send_submit_crosspost_activity: + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (titleEditText.getText() == null || titleEditText.getText().toString().equals("")) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + isPosting = true; + + item.setEnabled(false); + item.getIcon().setAlpha(130); + + mPostingSnackbar.show(); + + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } + + Intent intent = new Intent(this, SubmitPostService.class); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_TITLE, titleEditText.getText().toString()); + if (post.isCrosspost()) { + intent.putExtra(SubmitPostService.EXTRA_CONTENT, "t3_" + post.getCrosspostParentId()); + } else { + intent.putExtra(SubmitPostService.EXTRA_CONTENT, post.getFullName()); + } + intent.putExtra(SubmitPostService.EXTRA_KIND, APIUtils.KIND_CROSSPOST); + intent.putExtra(SubmitPostService.EXTRA_FLAIR, flair); + intent.putExtra(SubmitPostService.EXTRA_IS_SPOILER, isSpoiler); + intent.putExtra(SubmitPostService.EXTRA_IS_NSFW, isNSFW); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_CROSSPOST); + startService(intent); + + return true; + } + + return false; + } + + @Override + public void onBackPressed() { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + } else { + if (!titleEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } else { + finish(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putString(SUBREDDIT_ICON_STATE, iconUrl); + outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); + outState.putBoolean(IS_POSTING_STATE, isPosting); + outState.putParcelable(FLAIR_STATE, flair); + outState.putBoolean(IS_SPOILER_STATE, isSpoiler); + outState.putBoolean(IS_NSFW_STATE, isNSFW); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + subredditSelected = true; + subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); + + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + displaySubredditIcon(); + + flairTextView.setVisibility(View.VISIBLE); + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + } + } + + @Override + protected void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + } + + @Override + public void flairSelected(Flair flair) { + this.flair = flair; + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onSubmitTextPostEvent(SubmitCrosspostEvent submitCrosspostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + if (submitCrosspostEvent.postSuccess) { + Intent intent = new Intent(this, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, submitCrosspostEvent.post); + startActivity(intent); + finish(); + } else { + mMenu.findItem(R.id.action_send_post_text_activity).setEnabled(true); + mMenu.findItem(R.id.action_send_post_text_activity).getIcon().setAlpha(255); + if (submitCrosspostEvent.errorMessage == null || submitCrosspostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitCrosspostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitCrosspostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditFilterPopularAndAllActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditFilterPopularAndAllActivity.java new file mode 100644 index 00000000..292e65be --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditFilterPopularAndAllActivity.java @@ -0,0 +1,168 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.SubredditFilterRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subredditfilter.DeleteSubredditFilter; +import ml.docilealligator.infinityforreddit.subredditfilter.InsertSubredditFilter; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilterViewModel; + +public class SubredditFilterPopularAndAllActivity extends BaseActivity { + + private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 1; + @BindView(R.id.coordinator_layout_subreddit_filter_popular_and_all_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_subreddit_filter_popular_and_all_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_subreddit_filter_popular_and_all_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_subreddit_filter_popular_and_all_activity) + RecyclerView recyclerView; + @BindView(R.id.fab_subreddit_filter_popular_and_all_activity) + FloatingActionButton fab; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + SubredditFilterViewModel subredditFilterViewModel; + private SubredditFilterRecyclerViewAdapter adapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_subreddit_filter_popular_and_all); + + ButterKnife.bind(this); + + applyCustomTheme(); + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + adapter = new SubredditFilterRecyclerViewAdapter(subredditFilter -> DeleteSubredditFilter.deleteSubredditFilter(redditDataRoomDatabase, subredditFilter, () -> {})); + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setAdapter(adapter); + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + fab.hide(); + } else if (dy < 0) { + fab.show(); + } + } + }); + + subredditFilterViewModel = new ViewModelProvider(this, + new SubredditFilterViewModel.Factory(redditDataRoomDatabase)) + .get(SubredditFilterViewModel.class); + subredditFilterViewModel.getSubredditFilterLiveData().observe(this, subredditFilters -> adapter.updateSubredditsName(subredditFilters)); + + fab.setOnClickListener(view -> { + EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); + thingEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.choose_a_subreddit) + .setView(thingEditText) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + SubredditFilter subredditFilter = new SubredditFilter(thingEditText.getText().toString(), SubredditFilter.TYPE_POPULAR_AND_ALL); + InsertSubredditFilter.insertSubredditFilter(redditDataRoomDatabase, subredditFilter, + () -> {}); + }) + .setNegativeButton(R.string.cancel, null) + .setNeutralButton(R.string.search, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, true); + startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); + }) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) + .show(); + }); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE && resultCode == RESULT_OK && data != null) { + SubredditFilter subredditFilter = new SubredditFilter(data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_NAME), SubredditFilter.TYPE_POPULAR_AND_ALL); + InsertSubredditFilter.insertSubredditFilter(redditDataRoomDatabase, subredditFilter, + () -> {}); + } + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return sharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return customThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java new file mode 100644 index 00000000..e77e1437 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditMultiselectionActivity.java @@ -0,0 +1,266 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +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.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.google.android.material.appbar.AppBarLayout; +import com.r0adkll.slidr.Slidr; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.adapters.SubredditMultiselectionRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditViewModel; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class SubredditMultiselectionActivity extends BaseActivity implements ActivityToolbarInterface { + + static final String EXTRA_RETURN_SELECTED_SUBREDDITS = "ERSS"; + + private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 1; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + + @BindView(R.id.coordinator_layout_subreddits_multiselection_activity) + CoordinatorLayout mCoordinatorLayout; + @BindView(R.id.appbar_layout_subreddits_multiselection_activity) + AppBarLayout mAppBarLayout; + @BindView(R.id.toolbar_subscribed_subreddits_multiselection_activity) + Toolbar mToolbar; + @BindView(R.id.swipe_refresh_layout_subscribed_subscribed_subreddits_multiselection_activity) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_subscribed_subscribed_subreddits_multiselection_activity) + RecyclerView mRecyclerView; + @BindView(R.id.no_subscriptions_linear_layout_subscribed_subreddits_multiselection_activity) + LinearLayout mLinearLayout; + @BindView(R.id.no_subscriptions_image_view_subscribed_subreddits_multiselection_activity) + ImageView mImageView; + @BindView(R.id.error_text_view_subscribed_subreddits_multiselection_activity) + TextView mErrorTextView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + public SubscribedSubredditViewModel mSubscribedSubredditViewModel; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private LinearLayoutManager mLinearLayoutManager; + private SubredditMultiselectionRecyclerViewAdapter mAdapter; + private RequestManager mGlide; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_subscribed_subreddits_multiselection); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(mAppBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + mCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(mToolbar); + + int navBarHeight = getNavBarHeight(); + if (navBarHeight > 0) { + mRecyclerView.setPadding(0, 0, 0, navBarHeight); + } + } + } + + setSupportActionBar(mToolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + mSwipeRefreshLayout.setEnabled(false); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + + if (!mNullAccessToken && mAccountName == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + getCurrentAccountAndBindView(); + } + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + Toast.makeText(this, R.string.logged_out, Toast.LENGTH_SHORT).show(); + finish(); + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + bindView(); + } + }).execute(); + } + + private void bindView() { + mLinearLayoutManager = new LinearLayoutManager(this); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + mAdapter = new SubredditMultiselectionRecyclerViewAdapter(this, mCustomThemeWrapper); + mRecyclerView.setAdapter(mAdapter); + + mSubscribedSubredditViewModel = new ViewModelProvider(this, + new SubscribedSubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, mAccountName)) + .get(SubscribedSubredditViewModel.class); + mSubscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, subscribedSubredditData -> { + mSwipeRefreshLayout.setRefreshing(false); + if (subscribedSubredditData == null || subscribedSubredditData.size() == 0) { + mRecyclerView.setVisibility(View.GONE); + mLinearLayout.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.error_image).into(mImageView); + } else { + mLinearLayout.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + mGlide.clear(mImageView); + } + + mAdapter.setSubscribedSubreddits(subscribedSubredditData); + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.subreddit_multiselection_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_save_subreddit_multiselection_activity: + if (mAdapter != null) { + Intent returnIntent = new Intent(); + returnIntent.putStringArrayListExtra(EXTRA_RETURN_SELECTED_SUBREDDITS, + mAdapter.getAllSelectedSubreddits()); + setResult(RESULT_OK, returnIntent); + } + finish(); + return true; + case R.id.action_search_subreddit_multiselection_activity: + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, true); + startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); + } + + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE && resultCode == RESULT_OK && data != null && mAdapter != null) { + Intent returnIntent = new Intent(); + ArrayList selectedSubreddits = mAdapter.getAllSelectedSubreddits(); + selectedSubreddits.add(data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_NAME)); + returnIntent.putStringArrayListExtra(EXTRA_RETURN_SELECTED_SUBREDDITS, selectedSubreddits); + setResult(RESULT_OK, returnIntent); + finish(); + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); + mErrorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + } + + @Override + public void onLongPress() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditSelectionActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditSelectionActivity.java new file mode 100644 index 00000000..3a81c202 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubredditSelectionActivity.java @@ -0,0 +1,298 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +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 com.google.android.material.appbar.AppBarLayout; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.InsertSubscribedThingsAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.FetchSubscribedThing; +import ml.docilealligator.infinityforreddit.fragments.SubscribedSubredditsListingFragment; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class SubredditSelectionActivity extends BaseActivity implements ActivityToolbarInterface { + + static final String EXTRA_EXTRA_CLEAR_SELECTION = "EECS"; + static final String EXTRA_RETURN_SUBREDDIT_NAME = "ERSN"; + static final String EXTRA_RETURN_SUBREDDIT_ICON_URL = "ERSIURL"; + static final String EXTRA_RETURN_SUBREDDIT_IS_USER = "ERSIU"; + + private static final int SUBREDDIT_SEARCH_REQUEST_CODE = 0; + private static final String INSERT_SUBSCRIBED_SUBREDDIT_STATE = "ISSS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String ACCOUNT_PROFILE_IMAGE_URL = "APIU"; + private static final String FRAGMENT_OUT_STATE = "FOS"; + + @BindView(R.id.coordinator_layout_subreddit_selection_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_subreddit_selection_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_subreddit_selection_activity) + Toolbar toolbar; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String mAccountProfileImageUrl; + private boolean mInsertSuccess = false; + private Fragment mFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_subreddit_selection); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + if (savedInstanceState == null) { + getCurrentAccountAndBindView(); + } else { + mInsertSuccess = savedInstanceState.getBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE); + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + mAccountProfileImageUrl = savedInstanceState.getString(ACCOUNT_PROFILE_IMAGE_URL); + + mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_subreddit_selection_activity, mFragment).commit(); + + if (!mNullAccessToken && mAccountName == null) { + getCurrentAccountAndBindView(); + } else { + bindView(false); + } + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + mAccountProfileImageUrl = account.getProfileImageUrl(); + } + bindView(true); + }).execute(); + } + + private void bindView(boolean initializeFragment) { + loadSubscriptions(); + + if (initializeFragment) { + mFragment = new SubscribedSubredditsListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(SubscribedSubredditsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + bundle.putString(SubscribedSubredditsListingFragment.EXTRA_ACCOUNT_PROFILE_IMAGE_URL, mAccountProfileImageUrl); + bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, true); + if (getIntent().hasExtra(EXTRA_EXTRA_CLEAR_SELECTION)) { + bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_EXTRA_CLEAR_SELECTION, + getIntent().getExtras().getBoolean(EXTRA_EXTRA_CLEAR_SELECTION)); + } + mFragment.setArguments(bundle); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_subreddit_selection_activity, mFragment).commit(); + } + } + + private void loadSubscriptions() { + if (!mInsertSuccess) { + FetchSubscribedThing.fetchSubscribedThing(mOauthRetrofit, mAccessToken, mAccountName, null, + new ArrayList<>(), new ArrayList<>(), + new ArrayList<>(), + new FetchSubscribedThing.FetchSubscribedThingListener() { + @Override + public void onFetchSubscribedThingSuccess(ArrayList subscribedSubredditData, + ArrayList subscribedUserData, + ArrayList subredditData) { + new InsertSubscribedThingsAsyncTask( + mRedditDataRoomDatabase, + mAccountName, + subscribedSubredditData, + subscribedUserData, + subredditData, + () -> mInsertSuccess = true).execute(); + } + + @Override + public void onFetchSubscribedThingFail() { + mInsertSuccess = false; + } + }); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.subreddit_selection_activity, menu); + applyMenuItemTheme(menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_search_subreddit_selection_activity: + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SEARCH_ONLY_SUBREDDITS, true); + startActivityForResult(intent, SUBREDDIT_SEARCH_REQUEST_CODE); + return true; + } + + return false; + } + + public void getSelectedSubreddit(String name, String iconUrl, boolean subredditIsUser) { + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_IS_USER, subredditIsUser); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + if (requestCode == SUBREDDIT_SEARCH_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + String name = data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_NAME); + String iconUrl = data.getStringExtra(SearchActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_NAME, name); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_ICON_URL, iconUrl); + returnIntent.putExtra(EXTRA_RETURN_SUBREDDIT_IS_USER, false); + setResult(Activity.RESULT_OK, returnIntent); + finish(); + } + } + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE, mFragment); + outState.putBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE, mInsertSuccess); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(ACCOUNT_PROFILE_IMAGE_URL, mAccountProfileImageUrl); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Override + public void onLongPress() { + if (mFragment != null) { + ((SubscribedSubredditsListingFragment) mFragment).goBackToTop(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java new file mode 100644 index 00000000..7ba30bd9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SubscribedThingListingActivity.java @@ -0,0 +1,472 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentPagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.tabs.TabLayout; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.InsertMultiRedditAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.InsertSubscribedThingsAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.GoBackToMainPageEvent; +import ml.docilealligator.infinityforreddit.events.RefreshMultiRedditsEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.FetchSubscribedThing; +import ml.docilealligator.infinityforreddit.fragments.FollowedUsersListingFragment; +import ml.docilealligator.infinityforreddit.fragments.MultiRedditListingFragment; +import ml.docilealligator.infinityforreddit.fragments.SubscribedSubredditsListingFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.multireddit.DeleteMultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.FetchMyMultiReddits; +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class SubscribedThingListingActivity extends BaseActivity implements ActivityToolbarInterface { + + public static final String EXTRA_SHOW_MULTIREDDITS = "ESM"; + private static final String INSERT_SUBSCRIBED_SUBREDDIT_STATE = "ISSS"; + private static final String INSERT_MULTIREDDIT_STATE = "IMS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + + @BindView(R.id.coordinator_layout_subscribed_thing_listing_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_subscribed_thing_listing_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_subscribed_thing_listing_activity) + Toolbar toolbar; + @BindView(R.id.tab_layout_subscribed_thing_listing_activity) + TabLayout tabLayout; + @BindView(R.id.view_pager_subscribed_thing_listing_activity) + ViewPager viewPager; + @BindView(R.id.fab_subscribed_thing_listing_activity) + public FloatingActionButton fab; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private SlidrInterface mSlidrInterface; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private boolean mInsertSuccess = false; + private boolean mInsertMultiredditSuccess = false; + private boolean showMultiReddits = false; + private SectionsPagerAdapter sectionsPagerAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_subscribed_thing_listing); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + + int navBarHeight = getNavBarHeight(); + if (navBarHeight > 0) { + CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); + params.bottomMargin = navBarHeight; + fab.setLayoutParams(params); + } + } + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + if (savedInstanceState != null) { + mInsertSuccess = savedInstanceState.getBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE); + mInsertMultiredditSuccess = savedInstanceState.getBoolean(INSERT_MULTIREDDIT_STATE); + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndInitializeViewPager(); + } else { + initializeViewPagerAndLoadSubscriptions(); + } + } else { + showMultiReddits = getIntent().getBooleanExtra(EXTRA_SHOW_MULTIREDDITS, false); + getCurrentAccountAndInitializeViewPager(); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + applyTabLayoutTheme(tabLayout); + applyFABTheme(fab); + } + + private void getCurrentAccountAndInitializeViewPager() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + initializeViewPagerAndLoadSubscriptions(); + }).execute(); + } + + private void initializeViewPagerAndLoadSubscriptions() { + fab.setOnClickListener(view -> { + Intent intent = new Intent(this, CreateMultiRedditActivity.class); + startActivity(intent); + }); + sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + viewPager.setAdapter(sectionsPagerAdapter); + viewPager.setOffscreenPageLimit(3); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + if (position == 0) { + unlockSwipeRightToGoBack(); + fab.hide(); + } else { + lockSwipeRightToGoBack(); + if (position == 1) { + fab.hide(); + } else { + fab.show(); + } + } + } + }); + tabLayout.setupWithViewPager(viewPager); + + if (showMultiReddits) { + viewPager.setCurrentItem(2); + } + + loadSubscriptions(false); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(INSERT_SUBSCRIBED_SUBREDDIT_STATE, mInsertSuccess); + outState.putBoolean(INSERT_MULTIREDDIT_STATE, mInsertMultiredditSuccess); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + public void loadSubscriptions(boolean forceLoad) { + if (!(!forceLoad && mInsertSuccess)) { + FetchSubscribedThing.fetchSubscribedThing(mOauthRetrofit, mAccessToken, mAccountName, null, + new ArrayList<>(), new ArrayList<>(), + new ArrayList<>(), + new FetchSubscribedThing.FetchSubscribedThingListener() { + @Override + public void onFetchSubscribedThingSuccess(ArrayList subscribedSubredditData, + ArrayList subscribedUserData, + ArrayList subredditData) { + new InsertSubscribedThingsAsyncTask( + mRedditDataRoomDatabase, + mAccountName, + subscribedSubredditData, + subscribedUserData, + subredditData, + () -> { + mInsertSuccess = true; + sectionsPagerAdapter.stopRefreshProgressbar(); + }).execute(); + } + + @Override + public void onFetchSubscribedThingFail() { + mInsertSuccess = false; + sectionsPagerAdapter.stopRefreshProgressbar(); + Toast.makeText(SubscribedThingListingActivity.this, + R.string.error_loading_subscriptions, Toast.LENGTH_SHORT).show(); + } + }); + } + + if (!(!forceLoad && mInsertMultiredditSuccess)) { + loadMultiReddits(); + } + } + + private void loadMultiReddits() { + FetchMyMultiReddits.fetchMyMultiReddits(mOauthRetrofit, mAccessToken, new FetchMyMultiReddits.FetchMyMultiRedditsListener() { + @Override + public void success(ArrayList multiReddits) { + new InsertMultiRedditAsyncTask(mRedditDataRoomDatabase, multiReddits, mAccountName, () -> { + mInsertMultiredditSuccess = true; + sectionsPagerAdapter.stopMultiRedditRefreshProgressbar(); + }).execute(); + } + + @Override + public void failed() { + mInsertMultiredditSuccess = false; + sectionsPagerAdapter.stopMultiRedditRefreshProgressbar(); + Toast.makeText(SubscribedThingListingActivity.this, R.string.error_loading_multi_reddit_list, Toast.LENGTH_SHORT).show(); + } + }); + } + + public void deleteMultiReddit(MultiReddit multiReddit) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete) + .setMessage(R.string.delete_multi_reddit_dialog_message) + .setPositiveButton(R.string.delete, (dialogInterface, i) + -> DeleteMultiReddit.deleteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, + mAccessToken, mAccountName, multiReddit.getPath(), new DeleteMultiReddit.DeleteMultiRedditListener() { + @Override + public void success() { + Toast.makeText(SubscribedThingListingActivity.this, + R.string.delete_multi_reddit_success, Toast.LENGTH_SHORT).show(); + loadMultiReddits(); + } + + @Override + public void failed() { + Toast.makeText(SubscribedThingListingActivity.this, + R.string.delete_multi_reddit_failed, Toast.LENGTH_SHORT).show(); + } + })) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void goBackToMainPageEvent(GoBackToMainPageEvent event) { + finish(); + } + + @Subscribe + public void onRefreshMultiRedditsEvent(RefreshMultiRedditsEvent event) { + loadMultiReddits(); + } + + @Override + public void onLongPress() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.goBackToTop(); + } + } + + private void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + private void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + + private class SectionsPagerAdapter extends FragmentPagerAdapter { + + private SubscribedSubredditsListingFragment subscribedSubredditsListingFragment; + private FollowedUsersListingFragment followedUsersListingFragment; + private MultiRedditListingFragment multiRedditListingFragment; + + public SectionsPagerAdapter(FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + } + + @NonNull + @Override + public Fragment getItem(int position) { + switch (position) { + case 0: { + SubscribedSubredditsListingFragment fragment = new SubscribedSubredditsListingFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean(SubscribedSubredditsListingFragment.EXTRA_IS_SUBREDDIT_SELECTION, false); + bundle.putString(SubscribedSubredditsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + case 1: { + FollowedUsersListingFragment fragment = new FollowedUsersListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FollowedUsersListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + bundle.putString(FollowedUsersListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + fragment.setArguments(bundle); + return fragment; + } + default: { + MultiRedditListingFragment fragment = new MultiRedditListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(MultiRedditListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(MultiRedditListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + } + } + + @Override + public int getCount() { + return 3; + } + + @Override + public CharSequence getPageTitle(int position) { + switch (position) { + case 0: + return getString(R.string.subreddits); + case 1: + return getString(R.string.users); + case 2: + return getString(R.string.multi_reddits); + } + + return null; + } + + @NonNull + @Override + public Object instantiateItem(@NonNull ViewGroup container, int position) { + Fragment fragment = (Fragment) super.instantiateItem(container, position); + if (position == 0) { + subscribedSubredditsListingFragment = (SubscribedSubredditsListingFragment) fragment; + } else if (position == 1) { + followedUsersListingFragment = (FollowedUsersListingFragment) fragment; + } else { + multiRedditListingFragment = (MultiRedditListingFragment) fragment; + } + + return fragment; + } + + void stopRefreshProgressbar() { + if (subscribedSubredditsListingFragment != null) { + ((FragmentCommunicator) subscribedSubredditsListingFragment).stopRefreshProgressbar(); + } + if (followedUsersListingFragment != null) { + ((FragmentCommunicator) followedUsersListingFragment).stopRefreshProgressbar(); + } + } + + void stopMultiRedditRefreshProgressbar() { + if (multiRedditListingFragment != null) { + ((FragmentCommunicator) multiRedditListingFragment).stopRefreshProgressbar(); + } + } + + void goBackToTop() { + if (viewPager.getCurrentItem() == 0) { + subscribedSubredditsListingFragment.goBackToTop(); + } else if (viewPager.getCurrentItem() == 1) { + followedUsersListingFragment.goBackToTop(); + } else { + multiRedditListingFragment.goBackToTop(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java new file mode 100644 index 00000000..62ef3ddf --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImageOrGifActivity.java @@ -0,0 +1,492 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.Manifest; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.Html; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.gif.GifDrawable; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; +import com.github.piasy.biv.BigImageViewer; +import com.github.piasy.biv.loader.ImageLoader; +import com.github.piasy.biv.loader.glide.GlideImageLoader; +import com.github.piasy.biv.view.BigImageView; +import com.github.piasy.biv.view.GlideImageViewFactory; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrConfig; +import com.r0adkll.slidr.model.SlidrPosition; + +import java.io.File; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.asynctasks.SaveBitmapImageToFileAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SaveGIFToFileAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SetAsWallpaperBottomSheetFragment; +import ml.docilealligator.infinityforreddit.BuildConfig; +import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.ContentFontStyle; +import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.FontStyle; +import ml.docilealligator.infinityforreddit.font.TitleFontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontStyle; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.services.DownloadMediaService; +import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.WallpaperSetter; + +public class ViewImageOrGifActivity extends AppCompatActivity implements SetAsWallpaperCallback { + + public static final String EXTRA_IMAGE_URL_KEY = "EIUK"; + public static final String EXTRA_GIF_URL_KEY = "EGUK"; + public static final String EXTRA_FILE_NAME_KEY = "EFNK"; + public static final String EXTRA_SUBREDDIT_OR_USERNAME_KEY = "ESOUK"; + public static final String EXTRA_POST_TITLE_KEY = "EPTK"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; + @BindView(R.id.progress_bar_view_image_or_gif_activity) + ProgressBar mProgressBar; + @BindView(R.id.image_view_view_image_or_gif_activity) + BigImageView mImageView; + @BindView(R.id.load_image_error_linear_layout_view_image_or_gif_activity) + LinearLayout mLoadErrorLinearLayout; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + private boolean isActionBarHidden = false; + private boolean isDownloading = false; + private RequestManager glide; + private String mImageUrl; + private String mImageFileName; + private String mSubredditName; + private boolean isGif = true; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ((Infinity) getApplication()).getAppComponent().inject(this); + + getTheme().applyStyle(R.style.Theme_Normal, true); + + getTheme().applyStyle(FontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(TitleFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(ContentFontStyle.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(TitleFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); + + BigImageViewer.initialize(GlideImageLoader.with(this)); + + setContentView(R.layout.activity_view_image_or_gif); + + ButterKnife.bind(this); + + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + + Slidr.attach(this, new SlidrConfig.Builder().position(SlidrPosition.VERTICAL).distanceThreshold(0.125f).build()); + + glide = Glide.with(this); + + Intent intent = getIntent(); + mImageUrl = intent.getStringExtra(EXTRA_GIF_URL_KEY); + if (mImageUrl == null) { + isGif = false; + mImageUrl = intent.getStringExtra(EXTRA_IMAGE_URL_KEY); + } + mImageFileName = intent.getStringExtra(EXTRA_FILE_NAME_KEY); + String postTitle = intent.getStringExtra(EXTRA_POST_TITLE_KEY); + mSubredditName = intent.getStringExtra(EXTRA_SUBREDDIT_OR_USERNAME_KEY); + + if (postTitle != null) { + setTitle(Html.fromHtml(String.format("%s", postTitle))); + } else { + setTitle(""); + } + + mLoadErrorLinearLayout.setOnClickListener(view -> { + mProgressBar.setVisibility(View.VISIBLE); + mLoadErrorLinearLayout.setVisibility(View.GONE); + loadImage(); + }); + + mImageView.setOnClickListener(view -> { + if (isActionBarHidden) { + getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + isActionBarHidden = false; + } else { + getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE); + isActionBarHidden = true; + } + }); + + mImageView.setImageViewFactory(new GlideImageViewFactory()); + + mImageView.setImageLoaderCallback(new ImageLoader.Callback() { + @Override + public void onCacheHit(int imageType, File image) { + + } + + @Override + public void onCacheMiss(int imageType, File image) { + + } + + @Override + public void onStart() { + + } + + @Override + public void onProgress(int progress) { + + } + + @Override + public void onFinish() { + + } + + @Override + public void onSuccess(File image) { + mProgressBar.setVisibility(View.GONE); + + final SubsamplingScaleImageView view = mImageView.getSSIV(); + + if (view != null) { + view.setMinimumDpi(80); + + view.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() { + @Override + public void onReady() { + + } + + @Override + public void onImageLoaded() { + view.setDoubleTapZoomDpi(70); + view.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); + view.setQuickScaleEnabled(true); + } + + @Override + public void onPreviewLoadError(Exception e) { + + } + + @Override + public void onImageLoadError(Exception e) { + + } + + @Override + public void onTileLoadError(Exception e) { + + } + + @Override + public void onPreviewReleased() { + + } + }); + } + } + + @Override + public void onFail(Exception error) { + mProgressBar.setVisibility(View.GONE); + mLoadErrorLinearLayout.setVisibility(View.VISIBLE); + } + }); + + loadImage(); + } + + private void loadImage() { + mImageView.showImage(Uri.parse(mImageUrl)); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_image_or_gif_activity, menu); + if (!isGif) + menu.findItem(R.id.action_set_wallpaper_view_image_or_gif_activity).setVisible(true); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_download_view_image_or_gif_activity: + if (isDownloading) { + return false; + } + + isDownloading = true; + + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + + return true; + case R.id.action_share_view_image_or_gif_activity: + if (isGif) + shareGif(); + else + shareImage(); + return true; + case R.id.action_set_wallpaper_view_image_or_gif_activity: + if (!isGif) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); + setAsWallpaperBottomSheetFragment.show(getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); + } else { + WallpaperSetter.set(mImageUrl, WallpaperSetter.BOTH_SCREENS, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + return true; + } + + return false; + } + + private void download() { + isDownloading = false; + + Intent intent = new Intent(this, DownloadMediaService.class); + intent.putExtra(DownloadMediaService.EXTRA_URL, mImageUrl); + intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, isGif ? DownloadMediaService.EXTRA_MEDIA_TYPE_GIF : DownloadMediaService.EXTRA_MEDIA_TYPE_IMAGE); + intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, mImageFileName); + intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, mSubredditName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + Toast.makeText(this, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + private void shareImage() { + glide.asBitmap().load(mImageUrl).into(new CustomTarget() { + + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + if (getExternalCacheDir() != null) { + Toast.makeText(ViewImageOrGifActivity.this, R.string.save_image_first, Toast.LENGTH_SHORT).show(); + new SaveBitmapImageToFileAsyncTask(resource, getExternalCacheDir().getPath(), mImageFileName, + new SaveBitmapImageToFileAsyncTask.SaveBitmapImageToFileAsyncTaskListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(ViewImageOrGifActivity.this, + BuildConfig.APPLICATION_ID + ".provider", imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(ViewImageOrGifActivity.this, + R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); + } + }).execute(); + } else { + Toast.makeText(ViewImageOrGifActivity.this, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + } + + private void shareGif() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.save_gif_first, Toast.LENGTH_SHORT).show(); + glide.asGif().load(mImageUrl).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + if (getExternalCacheDir() != null) { + new SaveGIFToFileAsyncTask(resource, getExternalCacheDir().getPath(), mImageFileName, + new SaveGIFToFileAsyncTask.SaveGIFToFileAsyncTaskListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(ViewImageOrGifActivity.this, + BuildConfig.APPLICATION_ID + ".provider", imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(ViewImageOrGifActivity.this, + R.string.cannot_save_gif, Toast.LENGTH_SHORT).show(); + } + }).execute(); + } else { + Toast.makeText(ViewImageOrGifActivity.this, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + return false; + } + }).submit(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + isDownloading = false; + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + } + } + + @Override + public void setToHomeScreen(int viewPagerPosition) { + WallpaperSetter.set(mImageUrl, WallpaperSetter.HOME_SCREEN, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public void setToLockScreen(int viewPagerPosition) { + WallpaperSetter.set(mImageUrl, WallpaperSetter.LOCK_SCREEN, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public void setToBoth(int viewPagerPosition) { + WallpaperSetter.set(mImageUrl, WallpaperSetter.BOTH_SCREENS, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImageOrGifActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java new file mode 100644 index 00000000..58898098 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewImgurMediaActivity.java @@ -0,0 +1,495 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.AsyncTask; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.thefuntasty.hauler.DragDirection; +import com.thefuntasty.hauler.HaulerView; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.apis.ImgurAPI; +import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.ContentFontStyle; +import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.FontStyle; +import ml.docilealligator.infinityforreddit.font.TitleFontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontStyle; +import ml.docilealligator.infinityforreddit.fragments.ViewImgurImageFragment; +import ml.docilealligator.infinityforreddit.fragments.ViewImgurVideoFragment; +import ml.docilealligator.infinityforreddit.ImgurMedia; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.WallpaperSetter; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class ViewImgurMediaActivity extends AppCompatActivity implements SetAsWallpaperCallback { + + public static final String EXTRA_IMGUR_TYPE = "EIT"; + public static final String EXTRA_IMGUR_ID = "EII"; + public static final int IMGUR_TYPE_GALLERY = 0; + public static final int IMGUR_TYPE_ALBUM = 1; + public static final int IMGUR_TYPE_IMAGE = 2; + private static final String IMGUR_IMAGES_STATE = "IIS"; + + @BindView(R.id.hauler_view_view_imgur_media_activity) + HaulerView haulerView; + @BindView(R.id.progress_bar_view_imgur_media_activity) + ProgressBar progressBar; + @BindView(R.id.view_pager_view_imgur_media_activity) + ViewPager viewPager; + @BindView(R.id.load_image_error_linear_layout_view_imgur_media_activity) + LinearLayout errorLinearLayout; + private SectionsPagerAdapter sectionsPagerAdapter; + private ArrayList images; + @Inject + @Named("imgur") + Retrofit imgurRetrofit; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ((Infinity) getApplication()).getAppComponent().inject(this); + + getTheme().applyStyle(R.style.Theme_Normal, true); + + getTheme().applyStyle(FontStyle.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(TitleFontStyle.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(ContentFontStyle.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(FontFamily.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(TitleFontFamily.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(ContentFontFamily.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); + + setContentView(R.layout.activity_view_imgur_media); + + ButterKnife.bind(this); + + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + + setTitle(" "); + + String imgurId = getIntent().getStringExtra(EXTRA_IMGUR_ID); + if (imgurId == null) { + finish(); + return; + } + + if (savedInstanceState != null) { + images = savedInstanceState.getParcelableArrayList(IMGUR_IMAGES_STATE); + } + + haulerView.setOnDragDismissedListener(dragDirection -> { + int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; + finish(); + overridePendingTransition(0, slide); + }); + + if (images == null) { + fetchImgurMedia(imgurId); + } else { + progressBar.setVisibility(View.GONE); + setupViewPager(); + } + + errorLinearLayout.setOnClickListener(view -> fetchImgurMedia(imgurId)); + } + + private void fetchImgurMedia(String imgurId) { + errorLinearLayout.setVisibility(View.GONE); + progressBar.setVisibility(View.VISIBLE); + switch (getIntent().getIntExtra(EXTRA_IMGUR_TYPE, IMGUR_TYPE_IMAGE)) { + case IMGUR_TYPE_GALLERY: + imgurRetrofit.create(ImgurAPI.class).getGalleryImages(APIUtils.IMGUR_CLIENT_ID, imgurId) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseImgurImagesAsyncTask(response.body(), new ParseImgurImagesAsyncTask.ParseImgurImagesAsyncTaskListener() { + @Override + public void success(ArrayList images) { + ViewImgurMediaActivity.this.images = images; + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.GONE); + setupViewPager(); + } + + @Override + public void failed() { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + }).execute(); + } else { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + }); + break; + case IMGUR_TYPE_ALBUM: + imgurRetrofit.create(ImgurAPI.class).getAlbumImages(APIUtils.IMGUR_CLIENT_ID, imgurId) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseImgurImagesAsyncTask(response.body(), new ParseImgurImagesAsyncTask.ParseImgurImagesAsyncTaskListener() { + @Override + public void success(ArrayList images) { + ViewImgurMediaActivity.this.images = images; + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.GONE); + setupViewPager(); + } + + @Override + public void failed() { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + }).execute(); + } else { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + }); + break; + case IMGUR_TYPE_IMAGE: + imgurRetrofit.create(ImgurAPI.class).getImage(APIUtils.IMGUR_CLIENT_ID, imgurId) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseImgurImageAsyncTask(response.body(), new ParseImgurImageAsyncTask.ParseImgurImageAsyncTaskListener() { + @Override + public void success(ImgurMedia image) { + ViewImgurMediaActivity.this.images = new ArrayList<>(); + ViewImgurMediaActivity.this.images.add(image); + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.GONE); + setupViewPager(); + } + + @Override + public void failed() { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + }).execute(); + } else { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + }); + break; + } + } + + private void setupViewPager() { + setToolbarTitle(0); + sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + setToolbarTitle(position); + } + }); + viewPager.setAdapter(sectionsPagerAdapter); + } + + private void setToolbarTitle(int position) { + if (images != null && position >= 0 && position < images.size()) { + if (images.get(position).getType() == ImgurMedia.TYPE_VIDEO) { + setTitle(getString(R.string.view_imgur_media_activity_video_label, position + 1, images.size())); + } else { + setTitle(getString(R.string.view_imgur_media_activity_image_label, position + 1, images.size())); + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putParcelableArrayList(IMGUR_IMAGES_STATE, images); + } + + @Override + public void setToHomeScreen(int viewPagerPosition) { + if (images != null && viewPagerPosition >= 0 && viewPagerPosition < images.size()) { + WallpaperSetter.set(images.get(viewPagerPosition).getLink(), WallpaperSetter.HOME_SCREEN, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImgurMediaActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImgurMediaActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + @Override + public void setToLockScreen(int viewPagerPosition) { + if (images != null && viewPagerPosition >= 0 && viewPagerPosition < images.size()) { + WallpaperSetter.set(images.get(viewPagerPosition).getLink(), WallpaperSetter.LOCK_SCREEN, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImgurMediaActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImgurMediaActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + @Override + public void setToBoth(int viewPagerPosition) { + if (images != null && viewPagerPosition >= 0 && viewPagerPosition < images.size()) { + WallpaperSetter.set(images.get(viewPagerPosition).getLink(), WallpaperSetter.BOTH_SCREENS, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewImgurMediaActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewImgurMediaActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + public int getCurrentPagePosition() { + return viewPager.getCurrentItem(); + } + + private class SectionsPagerAdapter extends FragmentStatePagerAdapter { + + SectionsPagerAdapter(@NonNull FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + } + + @NonNull + @Override + public Fragment getItem(int position) { + ImgurMedia imgurMedia = images.get(position); + if (imgurMedia.getType() == ImgurMedia.TYPE_VIDEO) { + ViewImgurVideoFragment fragment = new ViewImgurVideoFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(ViewImgurVideoFragment.EXTRA_IMGUR_VIDEO, imgurMedia); + fragment.setArguments(bundle); + return fragment; + } else { + ViewImgurImageFragment fragment = new ViewImgurImageFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(ViewImgurImageFragment.EXTRA_IMGUR_IMAGES, imgurMedia); + fragment.setArguments(bundle); + return fragment; + } + } + + @Override + public int getCount() { + return images.size(); + } + } + + private static class ParseImgurImagesAsyncTask extends AsyncTask { + + private String response; + private ArrayList images; + private boolean parseFailed = false; + private ParseImgurImagesAsyncTaskListener parseImgurImagesAsyncTaskListener; + + interface ParseImgurImagesAsyncTaskListener { + void success(ArrayList images); + + void failed(); + } + + ParseImgurImagesAsyncTask(String response, ParseImgurImagesAsyncTaskListener parseImgurImagesAsyncTaskListener) { + this.response = response; + this.parseImgurImagesAsyncTaskListener = parseImgurImagesAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONArray jsonArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.IMAGES_KEY); + images = new ArrayList<>(); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject image = jsonArray.getJSONObject(i); + String type = image.getString(JSONUtils.TYPE_KEY); + if (type.contains("gif")) { + images.add(new ImgurMedia(image.getString(JSONUtils.ID_KEY), + image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), + "video/mp4", image.getString(JSONUtils.MP4_KEY))); + } else { + images.add(new ImgurMedia(image.getString(JSONUtils.ID_KEY), + image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), + type, image.getString(JSONUtils.LINK_KEY))); + } + } + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (parseFailed) { + parseImgurImagesAsyncTaskListener.failed(); + } else { + parseImgurImagesAsyncTaskListener.success(images); + } + } + } + + private static class ParseImgurImageAsyncTask extends AsyncTask { + + private String response; + private ImgurMedia image; + private boolean parseFailed = false; + private ParseImgurImageAsyncTaskListener parseImgurImageAsyncTaskListener; + + interface ParseImgurImageAsyncTaskListener { + void success(ImgurMedia image); + + void failed(); + } + + ParseImgurImageAsyncTask(String response, ParseImgurImageAsyncTaskListener parseImgurImageAsyncTaskListener) { + this.response = response; + this.parseImgurImageAsyncTaskListener = parseImgurImageAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject image = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY); + String type = image.getString(JSONUtils.TYPE_KEY); + if (type.contains("gif")) { + this.image = new ImgurMedia(image.getString(JSONUtils.ID_KEY), + image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), + "video/mp4", image.getString(JSONUtils.MP4_KEY)); + } else { + this.image = new ImgurMedia(image.getString(JSONUtils.ID_KEY), + image.getString(JSONUtils.TITLE_KEY), image.getString(JSONUtils.DESCRIPTION_KEY), + type, image.getString(JSONUtils.LINK_KEY)); + } + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (parseFailed) { + parseImgurImageAsyncTaskListener.failed(); + } else { + parseImgurImageAsyncTaskListener.success(image); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java new file mode 100644 index 00000000..72ff2341 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java @@ -0,0 +1,364 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.view.WindowManager; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.r0adkll.slidr.Slidr; + +import org.greenrobot.eventbus.EventBus; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RefreshMultiRedditsEvent; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.multireddit.DeleteMultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + +public class ViewMultiRedditDetailActivity extends BaseActivity implements SortTypeSelectionCallback, + PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { + + public static final String EXTRA_MULTIREDDIT_DATA = "EMD"; + public static final String EXTRA_MULTIREDDIT_PATH = "EMP"; + + private static final String FRAGMENT_OUT_STATE_KEY = "FOSK"; + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + + @BindView(R.id.coordinator_layout_view_multi_reddit_detail_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_view_multi_reddit_detail_activity) + AppBarLayout appBarLayout; + @BindView(R.id.collapsing_toolbar_layout_view_multi_reddit_detail_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.toolbar_view_multi_reddit_detail_activity) + Toolbar toolbar; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String multiPath; + private boolean isInLazyMode = false; + private Fragment mFragment; + private Menu mMenu; + private AppBarLayout.LayoutParams params; + private SortTypeBottomSheetFragment sortTypeBottomSheetFragment; + private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_view_multi_reddit_detail); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(toolbar); + } + } + + MultiReddit multiReddit = getIntent().getParcelableExtra(EXTRA_MULTIREDDIT_DATA); + if (multiReddit == null) { + multiPath = getIntent().getStringExtra(EXTRA_MULTIREDDIT_PATH); + if (multiPath != null) { + toolbar.setTitle(multiPath.substring(multiPath.lastIndexOf("/", multiPath.length() - 2) + 1)); + } else { + Toast.makeText(this, R.string.error_getting_multi_reddit_data, Toast.LENGTH_SHORT).show(); + finish(); + return; + } + } else { + multiPath = multiReddit.getPath(); + toolbar.setTitle(multiReddit.getDisplayName()); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + + mFragment = getSupportFragmentManager().getFragment(savedInstanceState, FRAGMENT_OUT_STATE_KEY); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_view_multi_reddit_detail_activity, mFragment).commit(); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndInitializeFragment(); + } + } else { + getCurrentAccountAndInitializeFragment(); + } + + sortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle bottomSheetBundle = new Bundle(); + bottomSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + sortTypeBottomSheetFragment.setArguments(bottomSheetBundle); + + sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); + + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + + params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); + } + + private void getCurrentAccountAndInitializeFragment() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + initializeFragment(); + }).execute(); + } + + private void initializeFragment() { + mFragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putString(PostFragment.EXTRA_NAME, multiPath); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_MULTI_REDDIT); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + mFragment.setArguments(bundle); + getSupportFragmentManager().beginTransaction().replace(R.id.frame_layout_view_multi_reddit_detail_activity, mFragment).commit(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_multi_reddit_detail_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_multi_reddit_detail_activity); + if (isInLazyMode) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } else { + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_sort_view_multi_reddit_detail_activity: + sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); + return true; + case R.id.action_search_view_multi_reddit_detail_activity: + Intent intent = new Intent(this, SearchActivity.class); + startActivity(intent); + return true; + case R.id.action_refresh_view_multi_reddit_detail_activity: + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_view_multi_reddit_detail_activity).setTitle(R.string.action_start_lazy_mode); + } + if (mFragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) mFragment).refresh(); + } + return true; + case R.id.action_lazy_mode_view_multi_reddit_detail_activity: + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_multi_reddit_detail_activity); + if (isInLazyMode) { + isInLazyMode = false; + ((FragmentCommunicator) mFragment).stopLazyMode(); + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = true; + if (((FragmentCommunicator) mFragment).startLazyMode()) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + appBarLayout.setExpanded(false); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = false; + } + } + return true; + case R.id.action_change_post_layout_view_multi_reddit_detail_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + case R.id.action_edit_view_multi_reddit_detail_activity: + Intent editIntent = new Intent(this, EditMultiRedditActivity.class); + editIntent.putExtra(EditMultiRedditActivity.EXTRA_MULTI_PATH, multiPath); + startActivity(editIntent); + return true; + case R.id.action_delete_view_multi_reddit_detail_activity: + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete) + .setMessage(R.string.delete_multi_reddit_dialog_message) + .setPositiveButton(R.string.delete, (dialogInterface, i) + -> DeleteMultiReddit.deleteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, + mAccessToken, mAccountName, multiPath, new DeleteMultiReddit.DeleteMultiRedditListener() { + @Override + public void success() { + Toast.makeText(ViewMultiRedditDetailActivity.this, + R.string.delete_multi_reddit_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new RefreshMultiRedditsEvent()); + finish(); + } + + @Override + public void failed() { + Toast.makeText(ViewMultiRedditDetailActivity.this, + R.string.delete_multi_reddit_failed, Toast.LENGTH_SHORT).show(); + } + })) + .setNegativeButton(R.string.cancel, null) + .show(); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + getSupportFragmentManager().putFragment(outState, FRAGMENT_OUT_STATE_KEY, mFragment); + } + + @Override + public void sortTypeSelected(SortType sortType) { + ((PostFragment) mFragment).changeSortType(sortType); + displaySortType(); + } + + @Override + public void sortTypeSelected(String sortType) { + Bundle bundle = new Bundle(); + bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); + sortTimeBottomSheetFragment.setArguments(bundle); + sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); + } + + @Override + public void postLayoutSelected(int postLayout) { + if (mFragment != null) { + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + multiPath, postLayout).apply(); + ((FragmentCommunicator) mFragment).changePostLayout(postLayout); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + @Override + public void onLongPress() { + if (mFragment != null) { + ((PostFragment) mFragment).goBackToTop(); + } + } + + @Override + public void displaySortType() { + if (mFragment != null) { + SortType sortType = ((PostFragment) mFragment).getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java new file mode 100644 index 00000000..f3cac524 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java @@ -0,0 +1,1856 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.util.DisplayMetrics; +import android.view.HapticFeedbackConstants; +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 android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.res.ResourcesCompat; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.LinearSmoothScroller; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; +import androidx.transition.AutoTransition; +import androidx.transition.TransitionManager; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.evernote.android.state.State; +import com.github.piasy.biv.BigImageViewer; +import com.github.piasy.biv.loader.glide.GlideImageLoader; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; +import com.livefront.bridge.Bridge; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +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 javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import im.ene.toro.exoplayer.ExoCreator; +import im.ene.toro.media.PlaybackInfo; +import im.ene.toro.media.VolumeInfo; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.adapters.CommentAndPostRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostCommentSortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.comment.Comment; +import ml.docilealligator.infinityforreddit.comment.FetchComment; +import ml.docilealligator.infinityforreddit.comment.FetchRemovedComment; +import ml.docilealligator.infinityforreddit.comment.ParseComment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.CustomToroContainer; +import ml.docilealligator.infinityforreddit.DeleteThing; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWBlurEvent; +import ml.docilealligator.infinityforreddit.events.ChangeNetworkStatusEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSpoilerBlurEvent; +import ml.docilealligator.infinityforreddit.events.PostUpdateEventToDetailActivity; +import ml.docilealligator.infinityforreddit.events.PostUpdateEventToPostList; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.post.FetchPost; +import ml.docilealligator.infinityforreddit.post.FetchRemovedPost; +import ml.docilealligator.infinityforreddit.post.HidePost; +import ml.docilealligator.infinityforreddit.post.ParsePost; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SaveThing; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; +import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; +import static ml.docilealligator.infinityforreddit.activities.CommentActivity.RETURN_EXTRA_COMMENT_DATA_KEY; +import static ml.docilealligator.infinityforreddit.activities.CommentActivity.WRITE_COMMENT_REQUEST_CODE; + +public class ViewPostDetailActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback, + SortTypeSelectionCallback, ActivityToolbarInterface { + + public static final String EXTRA_POST_DATA = "EPD"; + public static final String EXTRA_POST_LIST_POSITION = "EPLI"; + public static final String EXTRA_POST_ID = "EPI"; + public static final String EXTRA_SINGLE_COMMENT_ID = "ESCI"; + public static final String EXTRA_MESSAGE_FULLNAME = "ENI"; + public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; + public static final int EDIT_COMMENT_REQUEST_CODE = 3; + public static final int GIVE_AWARD_REQUEST_CODE = 100; + private static final int EDIT_POST_REQUEST_CODE = 2; + @State + boolean mNullAccessToken = false; + @State + String mAccessToken; + @State + String mAccountName; + @State + Post mPost; + @State + boolean isLoadingMoreChildren = false; + @State + boolean isRefreshing = false; + @State + boolean isSingleCommentThreadMode = false; + @State + ArrayList comments; + @State + ArrayList children; + @State + int mChildrenStartingIndex = 0; + @State + boolean loadMoreChildrenSuccess = true; + @State + boolean hasMoreChildren; + @State + boolean isFetchingComments = false; + @State + String mMessageFullname; + @State + String mNewAccountName; + @State + String sortType; + @State + boolean mRespectSubredditRecommendedSortType; + @BindView(R.id.coordinator_layout_view_post_detail) + CoordinatorLayout mCoordinatorLayout; + @BindView(R.id.appbar_layout_view_post_detail_activity) + AppBarLayout mAppBarLayout; + @BindView(R.id.toolbar_view_post_detail_activity) + Toolbar mToolbar; + @BindView(R.id.swipe_refresh_layout_view_post_detail_activity) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_view_post_detail) + CustomToroContainer mRecyclerView; + @BindView(R.id.fetch_post_info_linear_layout_view_post_detail_activity) + LinearLayout mFetchPostInfoLinearLayout; + @BindView(R.id.fetch_post_info_image_view_view_post_detail_activity) + ImageView mFetchPostInfoImageView; + @BindView(R.id.fetch_post_info_text_view_view_post_detail_activity) + TextView mFetchPostInfoTextView; + @BindView(R.id.fab_view_post_detail_activity) + FloatingActionButton fab; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("pushshift") + Retrofit pushshiftRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("gfycat") + Retrofit mGfycatRetrofit; + @Inject + @Named("redgifs") + Retrofit mRedgifsRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + ExoCreator mExoCreator; + private RequestManager mGlide; + private Locale mLocale; + private Menu mMenu; + private int orientation; + private int postListPosition = -1; + private String mSingleCommentId; + private boolean showToast = false; + private boolean isSortingComments = false; + private boolean mVolumeKeysNavigateComments; + private boolean mIsSmoothScrolling = false; + private boolean mLockFab; + private boolean mSwipeUpToHideFab; + private boolean mExpandChildren; + private int mWindowWidth; + private LinearLayoutManager mLinearLayoutManager; + private CommentAndPostRecyclerViewAdapter mAdapter; + private RecyclerView.SmoothScroller mSmoothScroller; + private PostCommentSortTypeBottomSheetFragment mPostCommentSortTypeBottomSheetFragment; + private SlidrInterface mSlidrInterface; + private Drawable mSavedIcon; + private Drawable mUnsavedIcon; + private ColorDrawable backgroundSwipeRight; + private ColorDrawable backgroundSwipeLeft; + private Drawable drawableSwipeRight; + private Drawable drawableSwipeLeft; + private int swipeLeftAction; + private int swipeRightAction; + private float swipeActionThreshold; + private ItemTouchHelper touchHelper; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + super.onCreate(savedInstanceState); + + BigImageViewer.initialize(GlideImageLoader.with(this)); + + setContentView(R.layout.activity_view_post_detail); + + Bridge.restoreInstanceState(this, savedInstanceState); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + mSavedIcon = getMenuItemIcon(R.drawable.ic_bookmark_toolbar_24dp); + mUnsavedIcon = getMenuItemIcon(R.drawable.ic_bookmark_border_toolbar_24dp); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + + if (isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(mAppBarLayout); + } + + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + mCoordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + adjustToolbar(mToolbar); + + int navBarHeight = getNavBarHeight(); + if (navBarHeight > 0) { + CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); + params.bottomMargin = navBarHeight; + fab.setLayoutParams(params); + mRecyclerView.setPadding(0, 0, 0, navBarHeight + mRecyclerView.getPaddingBottom()); + showToast = true; + } + } + } + + DisplayMetrics displayMetrics = new DisplayMetrics(); + getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); + mWindowWidth = displayMetrics.widthPixels; + + mToolbar.setTitle(""); + setSupportActionBar(mToolbar); + setToolbarGoToTop(mToolbar); + + mVolumeKeysNavigateComments = mSharedPreferences.getBoolean(SharedPreferencesUtils.VOLUME_KEYS_NAVIGATE_COMMENTS, false); + mLockFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON, false); + mSwipeUpToHideFab = mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_UP_TO_HIDE_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON, false); + mExpandChildren = !mSharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_TOP_LEVEL_COMMENTS_FIRST, false); + if (savedInstanceState == null) { + mRespectSubredditRecommendedSortType = mSharedPreferences.getBoolean(SharedPreferencesUtils.RESPECT_SUBREDDIT_RECOMMENDED_COMMENT_SORT_TYPE, false); + } + + mGlide = Glide.with(this); + Resources resources = getResources(); + mLocale = getResources().getConfiguration().locale; + + mLinearLayoutManager = new LinearLayoutManager(this); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + + if (children != null && children.size() > 0) { + mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (!mIsSmoothScrolling && !mLockFab) { + if (!recyclerView.canScrollVertically(1)) { + fab.hide(); + } else { + if (dy > 0) { + if (mSwipeUpToHideFab) { + fab.show(); + } else { + fab.hide(); + } + } else { + if (mSwipeUpToHideFab) { + fab.hide(); + } else { + fab.show(); + } + } + } + } + + if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { + int visibleItemCount = mLinearLayoutManager.getChildCount(); + int totalItemCount = mLinearLayoutManager.getItemCount(); + int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + + if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { + fetchMoreComments(); + } + } + } + + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + mIsSmoothScrolling = false; + } + } + }); + } else { + mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (!mIsSmoothScrolling && !mLockFab) { + if (!recyclerView.canScrollVertically(1)) { + fab.hide(); + } else { + if (dy > 0) { + if (mSwipeUpToHideFab) { + fab.show(); + } else { + fab.hide(); + } + } else { + if (mSwipeUpToHideFab) { + fab.hide(); + } else { + fab.show(); + } + } + } + } + } + + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + mIsSmoothScrolling = false; + } + } + }); + } + + boolean enableSwipeAction = mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false); + boolean 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 CommentAndPostRecyclerViewAdapter.PostDetailBaseViewHolder) && + !(viewHolder instanceof CommentAndPostRecyclerViewAdapter.CommentViewHolder)) { + return makeMovementFlags(0, 0); + } + int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; + return makeMovementFlags(0, swipeFlags); + } + + @Override + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { + return false; + } + + @Override + public boolean isItemViewSwipeEnabled() { + return true; + } + + @Override + public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { + if (touchHelper != null) { + touchHelper.attachToRecyclerView(null); + touchHelper.attachToRecyclerView(mRecyclerView); + if (mAdapter != null) { + mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); + } + } + } + + @Override + public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + + View itemView = viewHolder.itemView; + int horizontalOffset = (int) Utils.convertDpToPixel(16, ViewPostDetailActivity.this); + if (dX > 0) { + if (dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeRight.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeRight.setBounds(0, 0, 0, 0); + } + + drawableSwipeRight.setBounds(itemView.getLeft() + ((int) dX) - horizontalOffset - drawableSwipeRight.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() - drawableSwipeRight.getIntrinsicHeight()) / 2, + itemView.getLeft() + ((int) dX) - horizontalOffset, + (itemView.getBottom() + itemView.getTop() + drawableSwipeRight.getIntrinsicHeight()) / 2); + backgroundSwipeRight.draw(c); + drawableSwipeRight.draw(c); + } else if (dX < 0) { + if (-dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeLeft.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeLeft.setBounds(0, 0, 0, 0); + } + drawableSwipeLeft.setBounds(itemView.getRight() + ((int) dX) + horizontalOffset, + (itemView.getBottom() + itemView.getTop() - drawableSwipeLeft.getIntrinsicHeight()) / 2, + itemView.getRight() + ((int) dX) + horizontalOffset + drawableSwipeLeft.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() + drawableSwipeLeft.getIntrinsicHeight()) / 2); + backgroundSwipeLeft.draw(c); + drawableSwipeLeft.draw(c); + } + } + + @Override + public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { + return swipeActionThreshold; + } + }); + + if (enableSwipeAction) { + touchHelper.attachToRecyclerView(mRecyclerView); + } + + mSwipeRefreshLayout.setOnRefreshListener(() -> refresh(true, true)); + + mSmoothScroller = new LinearSmoothScroller(this) { + @Override + protected int getVerticalSnapPreference() { + return LinearSmoothScroller.SNAP_TO_START; + } + }; + + mSingleCommentId = getIntent().getStringExtra(EXTRA_SINGLE_COMMENT_ID); + if (savedInstanceState == null) { + if (mSingleCommentId != null) { + isSingleCommentThreadMode = true; + } + mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); + } + + if (savedInstanceState == null) { + if (!mRespectSubredditRecommendedSortType || isSingleCommentThreadMode) { + sortType = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, SortType.Type.BEST.value.toUpperCase()); + if (sortType != null) { + mToolbar.setTitle(new SortType(SortType.Type.valueOf(sortType)).getType().fullName); + sortType = sortType.toLowerCase(); + } + } + } else { + if (sortType != null) { + mToolbar.setTitle(new SortType(SortType.Type.valueOf(sortType.toUpperCase())).getType().fullName); + } + } + + orientation = resources.getConfiguration().orientation; + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + + if (getIntent().hasExtra(EXTRA_POST_LIST_POSITION)) { + postListPosition = getIntent().getIntExtra(EXTRA_POST_LIST_POSITION, -1); + } + + mPostCommentSortTypeBottomSheetFragment = new PostCommentSortTypeBottomSheetFragment(); + } + + private void initializeSwipeActionDrawable() { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + backgroundSwipeRight = new ColorDrawable(mCustomThemeWrapper.getDownvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } else { + backgroundSwipeRight = new ColorDrawable(mCustomThemeWrapper.getUpvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } + + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + backgroundSwipeLeft = new ColorDrawable(mCustomThemeWrapper.getUpvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } else { + backgroundSwipeLeft = new ColorDrawable(mCustomThemeWrapper.getDownvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } + } + + @Override + protected void onResume() { + super.onResume(); + if (mAdapter != null && mRecyclerView != null) { + mRecyclerView.onWindowVisibilityChanged(View.VISIBLE); + } + } + + @Override + protected void onPause() { + super.onPause(); + if (mAdapter != null && mRecyclerView != null) { + mRecyclerView.onWindowVisibilityChanged(View.GONE); + } + } + + @Override + public SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + mCoordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); + mFetchPostInfoTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + applyFABTheme(fab); + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (mNewAccountName != null) { + if (account == null || !account.getUsername().equals(mNewAccountName)) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { + EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); + Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); + + mNewAccountName = null; + if (newAccount == null) { + mNullAccessToken = true; + } else { + mAccessToken = newAccount.getAccessToken(); + mAccountName = newAccount.getUsername(); + } + + bindView(); + }).execute(); + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + bindView(); + } + } else { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + + bindView(); + } + }).execute(); + } + + private void bindView() { + if (mAccessToken != null && mMessageFullname != null) { + ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { + @Override + public void readSuccess() { + mMessageFullname = null; + } + + @Override + public void readFailed() { + + } + }); + } + + if (mPost == null) { + mPost = getIntent().getParcelableExtra(EXTRA_POST_DATA); + } + + if (mPost == null) { + fetchPostAndCommentsById(getIntent().getStringExtra(EXTRA_POST_ID)); + } else { + setupMenu(); + + mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, + mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mRedditDataRoomDatabase, mGlide, + mWindowWidth, mAccessToken, mAccountName, mPost, mLocale, mSingleCommentId, + isSingleCommentThreadMode, mSharedPreferences, mNsfwAndSpoilerSharedPreferences, mExoCreator, + new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { + @Override + public void updatePost(Post post) { + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + + @Override + public void retryFetchingComments() { + fetchCommentsRespectRecommendedSort(false); + } + + @Override + public void retryFetchingMoreComments() { + isLoadingMoreChildren = false; + loadMoreChildrenSuccess = true; + + fetchMoreComments(); + } + }); + mRecyclerView.setAdapter(mAdapter); + + if (comments == null) { + fetchCommentsRespectRecommendedSort(false); + } else { + if (isRefreshing) { + isRefreshing = false; + refresh(true, true); + } else if (isFetchingComments) { + fetchCommentsRespectRecommendedSort(false); + } else { + mAdapter.addComments(comments, hasMoreChildren); + if (isLoadingMoreChildren) { + isLoadingMoreChildren = false; + fetchMoreComments(); + } + } + } + } + + mRecyclerView.setCacheManager(mAdapter); + mRecyclerView.setPlayerInitializer(order -> { + VolumeInfo volumeInfo = new VolumeInfo(true, 0f); + return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo); + }); + + fab.setOnClickListener(view -> scrollToNextParentComment()); + } + + private void setupMenu() { + if (mMenu != null) { + MenuItem saveItem = mMenu.findItem(R.id.action_save_view_post_detail_activity); + MenuItem hideItem = mMenu.findItem(R.id.action_hide_view_post_detail_activity); + + mMenu.findItem(R.id.action_comment_view_post_detail_activity).setVisible(true); + mMenu.findItem(R.id.action_sort_view_post_detail_activity).setVisible(true); + + if (mAccessToken != null) { + if (mPost.isSaved()) { + saveItem.setVisible(true); + saveItem.setIcon(mSavedIcon); + } else { + saveItem.setVisible(true); + saveItem.setIcon(mUnsavedIcon); + } + + if (mPost.isHidden()) { + hideItem.setVisible(true); + hideItem.setTitle(R.string.action_unhide_post); + } else { + hideItem.setVisible(true); + hideItem.setTitle(R.string.action_hide_post); + } + } else { + saveItem.setVisible(false); + hideItem.setVisible(false); + } + + if (mPost.getAuthor().equals(mAccountName)) { + if (mPost.getPostType() == Post.TEXT_TYPE) { + mMenu.findItem(R.id.action_edit_view_post_detail_activity).setVisible(true); + } + mMenu.findItem(R.id.action_delete_view_post_detail_activity).setVisible(true); + + MenuItem nsfwItem = mMenu.findItem(R.id.action_nsfw_view_post_detail_activity); + nsfwItem.setVisible(true); + if (mPost.isNSFW()) { + nsfwItem.setTitle(R.string.action_unmark_nsfw); + } else { + nsfwItem.setTitle(R.string.action_mark_nsfw); + } + + MenuItem spoilerItem = mMenu.findItem(R.id.action_spoiler_view_post_detail_activity); + spoilerItem.setVisible(true); + if (mPost.isSpoiler()) { + spoilerItem.setTitle(R.string.action_unmark_spoiler); + } else { + spoilerItem.setTitle(R.string.action_mark_spoiler); + } + + mMenu.findItem(R.id.action_edit_flair_view_post_detail_activity).setVisible(true); + } + + mMenu.findItem(R.id.action_view_crosspost_parent_view_post_detail_activity).setVisible(mPost.getCrosspostParentId() != null); + + if ("[deleted]".equals(mPost.getAuthor()) || + "[deleted]".equals(mPost.getSelfText()) || + "[removed]".equals(mPost.getSelfText()) + ) { + mMenu.findItem(R.id.action_see_removed_view_post_detail_activity).setVisible(true); + } + } + } + + private Drawable getMenuItemIcon(int drawableId) { + Drawable icon = getDrawable(drawableId); + if (icon != null) { + DrawableCompat.setTint(icon, mCustomThemeWrapper.getToolbarPrimaryTextAndIconColor()); + } + + return icon; + } + + private void fetchPostAndCommentsById(String subredditId) { + mFetchPostInfoLinearLayout.setVisibility(View.GONE); + mSwipeRefreshLayout.setRefreshing(true); + mGlide.clear(mFetchPostInfoImageView); + + Call postAndComments; + if (mAccessToken == null) { + if (isSingleCommentThreadMode && mSingleCommentId != null) { + postAndComments = mRetrofit.create(RedditAPI.class).getPostAndCommentsSingleThreadById( + subredditId, mSingleCommentId, sortType); + } else { + postAndComments = mRetrofit.create(RedditAPI.class).getPostAndCommentsById(subredditId, + sortType); + } + } else { + if (isSingleCommentThreadMode && mSingleCommentId != null) { + postAndComments = mOauthRetrofit.create(RedditAPI.class).getPostAndCommentsSingleThreadByIdOauth(subredditId, + mSingleCommentId, sortType, APIUtils.getOAuthHeader(mAccessToken)); + } else { + postAndComments = mOauthRetrofit.create(RedditAPI.class).getPostAndCommentsByIdOauth(subredditId, + sortType, APIUtils.getOAuthHeader(mAccessToken)); + } + } + postAndComments.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + mSwipeRefreshLayout.setRefreshing(false); + + if (response.isSuccessful()) { + ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(Post post) { + mPost = post; + + setupMenu(); + + mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, + mCustomThemeWrapper, mRetrofit, mOauthRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mRedditDataRoomDatabase, mGlide, + mWindowWidth, mAccessToken, mAccountName, mPost, mLocale, + mSingleCommentId, isSingleCommentThreadMode, mSharedPreferences, + mNsfwAndSpoilerSharedPreferences, mExoCreator, + new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { + @Override + public void updatePost(Post post) { + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + + @Override + public void retryFetchingComments() { + fetchCommentsRespectRecommendedSort(false); + } + + @Override + public void retryFetchingMoreComments() { + isLoadingMoreChildren = false; + loadMoreChildrenSuccess = true; + + fetchMoreComments(); + } + }); + mRecyclerView.setAdapter(mAdapter); + + if (mRespectSubredditRecommendedSortType) { + fetchCommentsRespectRecommendedSort(false); + } else { + ParseComment.parseComment(response.body(), new ArrayList<>(), mLocale, + mExpandChildren, new ParseComment.ParseCommentListener() { + @Override + public void onParseCommentSuccess(ArrayList expandedComments, String parentId, ArrayList moreChildrenFullnames) { + ViewPostDetailActivity.this.children = moreChildrenFullnames; + + hasMoreChildren = children.size() != 0; + mAdapter.addComments(expandedComments, hasMoreChildren); + + if (children.size() > 0) { + mRecyclerView.clearOnScrollListeners(); + mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (!mIsSmoothScrolling && !mLockFab) { + if (!recyclerView.canScrollVertically(1)) { + fab.hide(); + } else { + if (dy > 0) { + if (mSwipeUpToHideFab) { + fab.show(); + } else { + fab.hide(); + } + } else { + if (mSwipeUpToHideFab) { + fab.hide(); + } else { + fab.show(); + } + } + } + } + + if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { + int visibleItemCount = mLinearLayoutManager.getChildCount(); + int totalItemCount = mLinearLayoutManager.getItemCount(); + int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + + if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { + fetchMoreComments(); + } + } + } + + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + mIsSmoothScrolling = false; + } + } + }); + } + } + + @Override + public void onParseCommentFailed() { + mAdapter.initiallyLoadCommentsFailed(); + } + }); + } + } + + @Override + public void onParsePostFail() { + showErrorView(subredditId); + } + }); + } else { + showErrorView(subredditId); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + showErrorView(subredditId); + } + }); + } + + private void fetchCommentsRespectRecommendedSort(boolean changeRefreshState, boolean checkSortState, String sortType) { + if (mRespectSubredditRecommendedSortType && mPost != null) { + FetchSubredditData.fetchSubredditData(mRetrofit, mPost.getSubredditName(), + new FetchSubredditData.FetchSubredditDataListener() { + @Override + public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { + if (subredditData.getSuggestedCommentSort() == null || subredditData.getSuggestedCommentSort().equals("null") || subredditData.getSuggestedCommentSort().equals("")) { + mRespectSubredditRecommendedSortType = false; + ViewPostDetailActivity.this.sortType = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, SortType.Type.BEST.value.toUpperCase()); + if (ViewPostDetailActivity.this.sortType != null) { + mToolbar.setTitle(new SortType(SortType.Type.valueOf(ViewPostDetailActivity.this.sortType)).getType().fullName); + ViewPostDetailActivity.this.sortType = ViewPostDetailActivity.this.sortType.toLowerCase(); + } + fetchComments(changeRefreshState, checkSortState, sortType); + } else { + ViewPostDetailActivity.this.sortType = subredditData.getSuggestedCommentSort(); + String sortTypeTemp = ViewPostDetailActivity.this.sortType.toLowerCase().substring(0, 1).toUpperCase() + ViewPostDetailActivity.this.sortType.substring(1); + mToolbar.setTitle(sortTypeTemp); + fetchComments(changeRefreshState, checkSortState, subredditData.getSuggestedCommentSort()); + } + } + + @Override + public void onFetchSubredditDataFail() { + mRespectSubredditRecommendedSortType = false; + ViewPostDetailActivity.this.sortType = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, SortType.Type.BEST.value.toUpperCase()); + if (ViewPostDetailActivity.this.sortType != null) { + mToolbar.setTitle(new SortType(SortType.Type.valueOf(ViewPostDetailActivity.this.sortType)).getType().fullName); + ViewPostDetailActivity.this.sortType = ViewPostDetailActivity.this.sortType.toLowerCase(); + } + } + }); + } else { + fetchComments(changeRefreshState, checkSortState, sortType); + } + } + + private void fetchComments(boolean changeRefreshState, boolean checkSortState, String sortType) { + isFetchingComments = true; + mAdapter.setSingleComment(mSingleCommentId, isSingleCommentThreadMode); + mAdapter.initiallyLoading(); + String commentId = null; + if (isSingleCommentThreadMode) { + commentId = mSingleCommentId; + } + + Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; + FetchComment.fetchComments(retrofit, mAccessToken, mPost.getId(), commentId, sortType, mExpandChildren, + mLocale, new FetchComment.FetchCommentListener() { + @Override + public void onFetchCommentSuccess(ArrayList expandedComments, + String parentId, ArrayList children) { + if (checkSortState && isSortingComments) { + if (changeRefreshState) { + isRefreshing = false; + } + + return; + } + + ViewPostDetailActivity.this.children = children; + + comments = expandedComments; + hasMoreChildren = children.size() != 0; + mAdapter.addComments(expandedComments, hasMoreChildren); + + if (children.size() > 0) { + mRecyclerView.clearOnScrollListeners(); + mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (!mIsSmoothScrolling && !mLockFab) { + if (!recyclerView.canScrollVertically(1)) { + fab.hide(); + } else { + if (dy > 0) { + if (mSwipeUpToHideFab) { + fab.show(); + } else { + fab.hide(); + } + } else { + if (mSwipeUpToHideFab) { + fab.hide(); + } else { + fab.show(); + } + } + } + } + + if (!isLoadingMoreChildren && loadMoreChildrenSuccess) { + int visibleItemCount = mLinearLayoutManager.getChildCount(); + int totalItemCount = mLinearLayoutManager.getItemCount(); + int firstVisibleItemPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + + if ((visibleItemCount + firstVisibleItemPosition >= totalItemCount) && firstVisibleItemPosition >= 0) { + fetchMoreComments(); + } + } + } + + @Override + public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { + if (newState == RecyclerView.SCROLL_STATE_IDLE) { + mIsSmoothScrolling = false; + } + } + }); + } + if (changeRefreshState) { + isRefreshing = false; + } + + isFetchingComments = false; + } + + @Override + public void onFetchCommentFailed() { + isFetchingComments = false; + if (checkSortState && isSortingComments) { + if (changeRefreshState) { + isRefreshing = false; + } + + return; + } + + mAdapter.initiallyLoadCommentsFailed(); + if (changeRefreshState) { + isRefreshing = false; + } + } + }); + } + + private void fetchCommentsRespectRecommendedSort(boolean changeRefreshState) { + fetchCommentsRespectRecommendedSort(changeRefreshState, true, sortType); + } + + void fetchMoreComments() { + if (isFetchingComments || isLoadingMoreChildren || !loadMoreChildrenSuccess) { + return; + } + + isLoadingMoreChildren = true; + + Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; + FetchComment.fetchMoreComment(retrofit, mAccessToken, children, mChildrenStartingIndex, + 0, mExpandChildren, mLocale, new FetchComment.FetchMoreCommentListener() { + @Override + public void onFetchMoreCommentSuccess(ArrayList expandedComments, int childrenStartingIndex) { + hasMoreChildren = childrenStartingIndex < children.size(); + mAdapter.addComments(expandedComments, hasMoreChildren); + mChildrenStartingIndex = childrenStartingIndex; + isLoadingMoreChildren = false; + loadMoreChildrenSuccess = true; + } + + @Override + public void onFetchMoreCommentFailed() { + isLoadingMoreChildren = false; + loadMoreChildrenSuccess = false; + mAdapter.loadMoreCommentsFailed(); + } + }); + } + + private void refresh(boolean fetchPost, boolean fetchComments) { + if (mAdapter != null && !isRefreshing) { + isRefreshing = true; + mChildrenStartingIndex = 0; + + mFetchPostInfoLinearLayout.setVisibility(View.GONE); + mGlide.clear(mFetchPostInfoImageView); + + if (fetchComments) { + fetchCommentsRespectRecommendedSort(!fetchPost); + } + + if (fetchPost) { + Retrofit retrofit; + if (mAccessToken == null) { + retrofit = mRetrofit; + } else { + retrofit = mOauthRetrofit; + } + FetchPost.fetchPost(retrofit, mPost.getId(), mAccessToken, mLocale, + new FetchPost.FetchPostListener() { + @Override + public void fetchPostSuccess(Post post) { + mPost = post; + mAdapter.updatePost(mPost); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + isRefreshing = false; + setupMenu(); + mSwipeRefreshLayout.setRefreshing(false); + } + + @Override + public void fetchPostFailed() { + showMessage(R.string.refresh_post_failed); + isRefreshing = false; + } + }); + } + } + } + + private void showErrorView(String subredditId) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchPostInfoLinearLayout.setVisibility(View.VISIBLE); + mFetchPostInfoLinearLayout.setOnClickListener(view -> fetchPostAndCommentsById(subredditId)); + mFetchPostInfoTextView.setText(R.string.load_post_error); + mGlide.load(R.drawable.error_image).into(mFetchPostInfoImageView); + } + + private void showMessage(int resId) { + if (showToast) { + Toast.makeText(ViewPostDetailActivity.this, resId, Toast.LENGTH_SHORT).show(); + } else { + Snackbar.make(mCoordinatorLayout, resId, Snackbar.LENGTH_SHORT).show(); + } + } + + private void markNSFW() { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); + } + + Map params = new HashMap<>(); + params.put(APIUtils.ID_KEY, mPost.getFullName()); + mOauthRetrofit.create(RedditAPI.class).markNSFW(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); + } + + refresh(true, false); + showMessage(R.string.mark_nsfw_success); + } else { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); + } + + showMessage(R.string.mark_nsfw_failed); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); + } + + showMessage(R.string.mark_nsfw_failed); + } + }); + } + + private void unmarkNSFW() { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); + } + + Map params = new HashMap<>(); + params.put(APIUtils.ID_KEY, mPost.getFullName()); + mOauthRetrofit.create(RedditAPI.class).unmarkNSFW(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_mark_nsfw); + } + + refresh(true, false); + showMessage(R.string.unmark_nsfw_success); + } else { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); + } + + showMessage(R.string.unmark_nsfw_failed); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + if (mMenu != null) { + mMenu.findItem(R.id.action_nsfw_view_post_detail_activity).setTitle(R.string.action_unmark_nsfw); + } + + showMessage(R.string.unmark_nsfw_failed); + } + }); + } + + private void markSpoiler() { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); + } + + Map params = new HashMap<>(); + params.put(APIUtils.ID_KEY, mPost.getFullName()); + mOauthRetrofit.create(RedditAPI.class).markSpoiler(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); + } + + refresh(true, false); + showMessage(R.string.mark_spoiler_success); + } else { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); + } + + showMessage(R.string.mark_spoiler_failed); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); + } + + showMessage(R.string.mark_spoiler_failed); + } + }); + } + + private void unmarkSpoiler() { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); + } + + Map params = new HashMap<>(); + params.put(APIUtils.ID_KEY, mPost.getFullName()); + mOauthRetrofit.create(RedditAPI.class).unmarkSpoiler(APIUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_mark_spoiler); + } + + refresh(true, false); + showMessage(R.string.unmark_spoiler_success); + } else { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); + } + + showMessage(R.string.unmark_spoiler_failed); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + if (mMenu != null) { + mMenu.findItem(R.id.action_spoiler_view_post_detail_activity).setTitle(R.string.action_unmark_spoiler); + } + + showMessage(R.string.unmark_spoiler_failed); + } + }); + } + + public void deleteComment(String fullName, int position) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete_this_comment) + .setMessage(R.string.are_you_sure) + .setPositiveButton(R.string.delete, (dialogInterface, i) + -> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() { + @Override + public void deleteSuccess() { + Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); + mAdapter.deleteComment(position); + } + + @Override + public void deleteFailed() { + Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_failed, Toast.LENGTH_SHORT).show(); + } + })) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + public void showRemovedComment(Comment comment, int position) { + Toast.makeText(ViewPostDetailActivity.this, R.string.fetching_removed_comment, Toast.LENGTH_SHORT).show(); + FetchRemovedComment.fetchRemovedComment( + pushshiftRetrofit, + comment, + new FetchRemovedComment.FetchRemovedCommentListener() { + @Override + public void fetchSuccess(Comment comment) { + mAdapter.editComment(comment.getAuthor(), comment.getCommentMarkdown(), position); + } + + @Override + public void fetchFailed() { + Toast.makeText(ViewPostDetailActivity.this, R.string.show_removed_comment_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + + public void changeToNomalThreadMode() { + isSingleCommentThreadMode = false; + mSingleCommentId = null; + mRespectSubredditRecommendedSortType = mSharedPreferences.getBoolean(SharedPreferencesUtils.RESPECT_SUBREDDIT_RECOMMENDED_COMMENT_SORT_TYPE, false); + refresh(false, true); + } + + public void scrollToNextParentComment() { + if (mLinearLayoutManager != null) { + int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + if (mAdapter != null) { + int nextParentPosition = mAdapter.getNextParentCommentPosition(currentPosition); + if (nextParentPosition < 0) { + return; + } + mSmoothScroller.setTargetPosition(nextParentPosition); + if (mLinearLayoutManager != null) { + mIsSmoothScrolling = true; + mLinearLayoutManager.startSmoothScroll(mSmoothScroller); + } + } + } + } + + public void scrollToPreviousParentComment() { + if (mLinearLayoutManager != null) { + int currentPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + if (mAdapter != null) { + int nextParentPosition = mAdapter.getPreviousParentCommentPosition(currentPosition); + if (nextParentPosition < 0) { + return; + } + mSmoothScroller.setTargetPosition(nextParentPosition); + if (mLinearLayoutManager != null) { + mIsSmoothScrolling = true; + mLinearLayoutManager.startSmoothScroll(mSmoothScroller); + } + } + } + } + + public void delayTransition() { + TransitionManager.beginDelayedTransition(mRecyclerView, new AutoTransition()); + } + + @Subscribe + public void onPostUpdateEvent(PostUpdateEventToDetailActivity event) { + if (mPost.getId().equals(event.post.getId())) { + mPost.setVoteType(event.post.getVoteType()); + mPost.setSaved(event.post.isSaved()); + if (mMenu != null) { + if (event.post.isSaved()) { + mMenu.findItem(R.id.action_save_view_post_detail_activity).setIcon(mSavedIcon); + } else { + mMenu.findItem(R.id.action_save_view_post_detail_activity).setIcon(mUnsavedIcon); + } + } + mAdapter.updatePost(mPost); + } + } + + @Subscribe + public void onChangeNSFWBlurEvent(ChangeNSFWBlurEvent event) { + mAdapter.setBlurNSFW(event.needBlurNSFW); + refreshAdapter(); + } + + @Subscribe + public void onChangeSpoilerBlurEvent(ChangeSpoilerBlurEvent event) { + mAdapter.setBlurSpoiler(event.needBlurSpoiler); + refreshAdapter(); + } + + private void refreshAdapter() { + int previousPosition = -1; + if (mLinearLayoutManager != null) { + previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + } + + RecyclerView.LayoutManager layoutManager = mRecyclerView.getLayoutManager(); + mRecyclerView.setAdapter(null); + mRecyclerView.setLayoutManager(null); + mRecyclerView.setAdapter(mAdapter); + mRecyclerView.setLayoutManager(layoutManager); + + if (previousPosition > 0) { + mRecyclerView.scrollToPosition(previousPosition); + } + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + if (!getClass().getName().equals(event.excludeActivityClassName)) { + finish(); + } + } + + @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(); + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_post_detail_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + if (mPost != null) { + setupMenu(); + } + return true; + } + + public void showRemovedPost() { + Toast.makeText(ViewPostDetailActivity.this, R.string.fetching_removed_post, Toast.LENGTH_SHORT).show(); + FetchRemovedPost.fetchRemovedPost( + pushshiftRetrofit, + mPost, + new FetchRemovedPost.FetchRemovedPostListener() { + @Override + public void fetchSuccess(Post post) { + mPost = post; + mAdapter.updatePost(post); + } + + @Override + public void fetchFailed() { + Toast.makeText(ViewPostDetailActivity.this, R.string.show_removed_post_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.action_refresh_view_post_detail_activity: + refresh(true, true); + return true; + case R.id.action_comment_view_post_detail_activity: + if (mPost != null) { + if (mPost.isArchived()) { + showMessage(R.string.archived_post_reply_unavailable); + return true; + } + + if (mPost.isLocked()) { + showMessage(R.string.locked_post_comment_unavailable); + return true; + } + + if (mAccessToken == null) { + showMessage(R.string.login_first); + return true; + } + + Intent intent = new Intent(this, CommentActivity.class); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, mPost.getTitle()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY, mPost.getSelfText()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_KEY, mPost.getSelfTextPlain()); + intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mPost.getFullName()); + intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, 0); + intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, false); + startActivityForResult(intent, WRITE_COMMENT_REQUEST_CODE); + } + return true; + case R.id.action_save_view_post_detail_activity: + if (mPost != null && mAccessToken != null) { + if (mPost.isSaved()) { + item.setIcon(mUnsavedIcon); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + mPost.setSaved(false); + item.setIcon(mUnsavedIcon); + showMessage(R.string.post_unsaved_success); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + + @Override + public void failed() { + mPost.setSaved(true); + item.setIcon(mSavedIcon); + showMessage(R.string.post_unsaved_failed); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + }); + } else { + item.setIcon(mSavedIcon); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + mPost.setSaved(true); + item.setIcon(mSavedIcon); + showMessage(R.string.post_saved_success); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + + @Override + public void failed() { + mPost.setSaved(false); + item.setIcon(mUnsavedIcon); + showMessage(R.string.post_saved_failed); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + }); + } + } + return true; + case R.id.action_sort_view_post_detail_activity: + if (mPost != null) { + mPostCommentSortTypeBottomSheetFragment.show(getSupportFragmentManager(), mPostCommentSortTypeBottomSheetFragment.getTag()); + } + return true; + case R.id.action_view_crosspost_parent_view_post_detail_activity: + Intent crosspostIntent = new Intent(this, ViewPostDetailActivity.class); + crosspostIntent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, mPost.getCrosspostParentId()); + startActivity(crosspostIntent); + return true; + case R.id.action_hide_view_post_detail_activity: + if (mPost != null && mAccessToken != null) { + if (mPost.isHidden()) { + item.setTitle(R.string.action_hide_post); + + HidePost.unhidePost(mOauthRetrofit, mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { + @Override + public void success() { + mPost.setHidden(false); + item.setTitle(R.string.action_hide_post); + showMessage(R.string.post_unhide_success); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + + @Override + public void failed() { + mPost.setHidden(true); + item.setTitle(R.string.action_unhide_post); + showMessage(R.string.post_unhide_failed); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + }); + } else { + item.setTitle(R.string.action_unhide_post); + + HidePost.hidePost(mOauthRetrofit, mAccessToken, mPost.getFullName(), new HidePost.HidePostListener() { + @Override + public void success() { + mPost.setHidden(true); + item.setTitle(R.string.action_unhide_post); + showMessage(R.string.post_hide_success); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + + @Override + public void failed() { + mPost.setHidden(false); + item.setTitle(R.string.action_hide_post); + showMessage(R.string.post_hide_failed); + EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); + } + }); + } + } + return true; + case R.id.action_edit_view_post_detail_activity: + Intent editPostIntent = new Intent(this, EditPostActivity.class); + editPostIntent.putExtra(EditPostActivity.EXTRA_ACCESS_TOKEN, mAccessToken); + editPostIntent.putExtra(EditPostActivity.EXTRA_FULLNAME, mPost.getFullName()); + editPostIntent.putExtra(EditPostActivity.EXTRA_TITLE, mPost.getTitle()); + editPostIntent.putExtra(EditPostActivity.EXTRA_CONTENT, mPost.getSelfText()); + startActivityForResult(editPostIntent, EDIT_POST_REQUEST_CODE); + return true; + case R.id.action_delete_view_post_detail_activity: + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete_this_post) + .setMessage(R.string.are_you_sure) + .setPositiveButton(R.string.delete, (dialogInterface, i) + -> DeleteThing.delete(mOauthRetrofit, mPost.getFullName(), mAccessToken, new DeleteThing.DeleteThingListener() { + @Override + public void deleteSuccess() { + Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); + finish(); + } + + @Override + public void deleteFailed() { + showMessage(R.string.delete_post_failed); + } + })) + .setNegativeButton(R.string.cancel, null) + .show(); + return true; + case R.id.action_nsfw_view_post_detail_activity: + if (mPost.isNSFW()) { + unmarkNSFW(); + } else { + markNSFW(); + } + return true; + case R.id.action_spoiler_view_post_detail_activity: + if (mPost.isSpoiler()) { + unmarkSpoiler(); + } else { + markSpoiler(); + } + return true; + case R.id.action_edit_flair_view_post_detail_activity: + FlairBottomSheetFragment flairBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); + flairBottomSheetFragment.setArguments(bundle); + flairBottomSheetFragment.show(getSupportFragmentManager(), flairBottomSheetFragment.getTag()); + return true; + case R.id.action_give_award_view_post_detail_activity: + if (mAccessToken == null) { + Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return true; + } + + Intent giveAwardIntent = new Intent(this, GiveAwardActivity.class); + giveAwardIntent.putExtra(GiveAwardActivity.EXTRA_THING_FULLNAME, mPost.getFullName()); + giveAwardIntent.putExtra(GiveAwardActivity.EXTRA_ITEM_POSITION, 0); + startActivityForResult(giveAwardIntent, GIVE_AWARD_REQUEST_CODE); + return true; + case R.id.action_report_view_post_detail_activity: + if (mAccessToken == null) { + Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return true; + } + Intent intent = new Intent(this, ReportActivity.class); + intent.putExtra(ReportActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); + intent.putExtra(ReportActivity.EXTRA_THING_FULLNAME, mPost.getFullName()); + startActivity(intent); + return true; + case R.id.action_see_removed_view_post_detail_activity: + showRemovedPost(); + return true; + case R.id.action_crosspost_view_post_detail_activity: + Intent submitCrosspostIntent = new Intent(this, SubmitCrosspostActivity.class); + submitCrosspostIntent.putExtra(SubmitCrosspostActivity.EXTRA_POST, mPost); + startActivity(submitCrosspostIntent); + return true; + case android.R.id.home: + onBackPressed(); + return true; + } + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == WRITE_COMMENT_REQUEST_CODE) { + if (data != null && resultCode == RESULT_OK) { + if (data.hasExtra(RETURN_EXTRA_COMMENT_DATA_KEY)) { + Comment comment = data.getParcelableExtra(RETURN_EXTRA_COMMENT_DATA_KEY); + if (comment != null && comment.getDepth() == 0) { + mAdapter.addComment(comment); + } else { + String parentFullname = data.getStringExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY); + int parentPosition = data.getIntExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, -1); + if (parentFullname != null && parentPosition >= 0) { + mAdapter.addChildComment(comment, parentFullname, parentPosition); + } + } + } else { + Toast.makeText(this, R.string.send_comment_failed, Toast.LENGTH_SHORT).show(); + } + } + } else if (requestCode == EDIT_POST_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + refresh(true, false); + } + } else if (requestCode == EDIT_COMMENT_REQUEST_CODE) { + if (data != null && resultCode == RESULT_OK) { + mAdapter.editComment(null, + data.getStringExtra(EditCommentActivity.EXTRA_EDITED_COMMENT_CONTENT), + data.getExtras().getInt(EditCommentActivity.EXTRA_EDITED_COMMENT_POSITION)); + } + } else if (requestCode == GIVE_AWARD_REQUEST_CODE) { + if (data != null && resultCode == RESULT_OK) { + Toast.makeText(this, R.string.give_award_success, Toast.LENGTH_SHORT).show(); + int position = data.getIntExtra(GiveAwardActivity.EXTRA_RETURN_ITEM_POSITION, 0); + String newAwardsHTML = data.getStringExtra(GiveAwardActivity.EXTRA_RETURN_NEW_AWARDS); + int newAwardsCount = data.getIntExtra(GiveAwardActivity.EXTRA_RETURN_NEW_AWARDS_COUNT, 0); + if (mAdapter != null) { + mAdapter.giveAward(newAwardsHTML, newAwardsCount, position); + } + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + comments = mAdapter == null ? null : mAdapter.getVisibleComments(); + Bridge.saveInstanceState(this, outState); + } + + @Override + public void onBackPressed() { + if (orientation == getResources().getConfiguration().orientation) { + super.onBackPressed(); + } else { + finish(); + } + } + + @Override + protected void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + Bridge.clear(this); + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + if (mVolumeKeysNavigateComments) { + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + scrollToPreviousParentComment(); + return true; + case KeyEvent.KEYCODE_VOLUME_DOWN: + scrollToNextParentComment(); + return true; + } + } + return super.onKeyDown(keyCode, event); + } + + @Override + public void flairSelected(Flair flair) { + Map params = new HashMap<>(); + params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); + params.put(APIUtils.FLAIR_TEMPLATE_ID_KEY, flair.getId()); + params.put(APIUtils.LINK_KEY, mPost.getFullName()); + params.put(APIUtils.TEXT_KEY, flair.getText()); + + mOauthRetrofit.create(RedditAPI.class).selectFlair(mPost.getSubredditNamePrefixed(), + APIUtils.getOAuthHeader(mAccessToken), params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + refresh(true, false); + showMessage(R.string.update_flair_success); + } else { + showMessage(R.string.update_flair_failed); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + showMessage(R.string.update_flair_failed); + } + }); + } + + @Override + public void sortTypeSelected(SortType sortType) { + mFetchPostInfoLinearLayout.setVisibility(View.GONE); + mGlide.clear(mFetchPostInfoImageView); + mChildrenStartingIndex = 0; + if (children != null) { + children.clear(); + } + this.sortType = sortType.getType().value; + if (!mRespectSubredditRecommendedSortType) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT, sortType.getType().name()).apply(); + } + mRespectSubredditRecommendedSortType = false; + fetchCommentsRespectRecommendedSort(false, false, sortType.getType().value); + + mToolbar.setTitle(sortType.getType().fullName); + } + + public void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + public void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } + + @Override + public void onLongPress() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java new file mode 100644 index 00000000..d7072ab0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPrivateMessagesActivity.java @@ -0,0 +1,331 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.transition.AutoTransition; +import androidx.transition.TransitionManager; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.snackbar.Snackbar; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.adapters.PrivateMessagesDetailRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadUserDataAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RepliedToPrivateMessageEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.Message; +import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.message.ReplyMessage; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import retrofit2.Retrofit; + +public class ViewPrivateMessagesActivity extends BaseActivity implements ActivityToolbarInterface { + + public static final String EXTRA_PRIVATE_MESSAGE = "EPM"; + public static final String EXTRA_MESSAGE_POSITION = "EMP"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String USER_AVATAR_STATE = "UAS"; + @BindView(R.id.linear_layout_view_private_messages_activity) + LinearLayout mLinearLayout; + @BindView(R.id.coordinator_layout_view_private_messages_activity) + CoordinatorLayout mCoordinatorLayout; + @BindView(R.id.appbar_layout_view_private_messages_activity) + AppBarLayout mAppBarLayout; + @BindView(R.id.toolbar_view_private_messages_activity) + Toolbar mToolbar; + @BindView(R.id.recycler_view_view_private_messages) + RecyclerView mRecyclerView; + @BindView(R.id.edit_text_divider_view_private_messages_activity) + View mDivider; + @BindView(R.id.edit_text_view_private_messages_activity) + EditText mEditText; + @BindView(R.id.send_image_view_view_private_messages_activity) + ImageView mSendImageView; + @BindView(R.id.edit_text_wrapper_linear_layout_view_private_messages_activity) + LinearLayout mEditTextLinearLayout; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private LinearLayoutManager mLinearLayoutManager; + private PrivateMessagesDetailRecyclerViewAdapter mAdapter; + private Message privateMessage; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String mUserAvatar; + private ArrayList mProvideUserAvatarCallbacks; + private LoadUserDataAsyncTask mLoadUserDataAsyncTask; + private boolean isSendingMessage = false; + private int mSecondaryTextColor; + private int mSendMessageIconColor; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_view_private_messages); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(mAppBarLayout); + } + + Intent intent = getIntent(); + privateMessage = intent.getParcelableExtra(EXTRA_PRIVATE_MESSAGE); + + setSupportActionBar(mToolbar); + setToolbarGoToTop(mToolbar); + + mProvideUserAvatarCallbacks = new ArrayList<>(); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + mUserAvatar = savedInstanceState.getString(USER_AVATAR_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + getCurrentAccountAndBindView(); + } + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + bindView(); + }).execute(); + } + + private void bindView() { + if (privateMessage != null) { + if (privateMessage.getAuthor().equals(mAccountName)) { + mToolbar.setTitle(privateMessage.getDestination()); + mToolbar.setOnClickListener(view -> { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getDestination()); + startActivity(intent); + }); + } else { + mToolbar.setTitle(privateMessage.getAuthor()); + mToolbar.setOnClickListener(view -> { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, privateMessage.getAuthor()); + startActivity(intent); + }); + } + } + mAdapter = new PrivateMessagesDetailRecyclerViewAdapter(this, mSharedPreferences, + getResources().getConfiguration().locale, privateMessage, mAccountName, mCustomThemeWrapper); + mLinearLayoutManager = new LinearLayoutManager(this); + mLinearLayoutManager.setStackFromEnd(true); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + mRecyclerView.setAdapter(mAdapter); + goToBottom(); + mSendImageView.setOnClickListener(view -> { + if (!isSendingMessage) { + if (!mEditText.getText().toString().equals("")) { + //Send Message + if (privateMessage != null) { + Message replyTo; + ArrayList replies = privateMessage.getReplies(); + if (replies != null && !replies.isEmpty()) { + replyTo = replies.get(replies.size() - 1); + } else { + replyTo = privateMessage; + } + if (replyTo != null) { + isSendingMessage = true; + mSendImageView.setColorFilter(mSecondaryTextColor, android.graphics.PorterDuff.Mode.SRC_IN); + ReplyMessage.replyMessage(mEditText.getText().toString(), replyTo.getFullname(), + getResources().getConfiguration().locale, mOauthRetrofit, mAccessToken, + new ReplyMessage.ReplyMessageListener() { + @Override + public void replyMessageSuccess(Message message) { + if (mAdapter != null) { + mAdapter.addReply(message); + } + goToBottom(); + mEditText.setText(""); + mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + isSendingMessage = false; + EventBus.getDefault().post(new RepliedToPrivateMessageEvent(message, getIntent().getIntExtra(EXTRA_MESSAGE_POSITION, -1))); + } + + @Override + public void replyMessageFailed(String errorMessage) { + if (errorMessage != null && !errorMessage.equals("")) { + Snackbar.make(mCoordinatorLayout, errorMessage, Snackbar.LENGTH_LONG).show(); + } else { + Snackbar.make(mCoordinatorLayout, R.string.reply_message_failed, Snackbar.LENGTH_LONG).show(); + } + mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + isSendingMessage = false; + } + }); + StringBuilder fullnames = new StringBuilder(); + if (privateMessage.isNew()) { + fullnames.append(privateMessage.getFullname()).append(","); + } + if (replies != null && !replies.isEmpty()) { + for (Message m : replies) { + if (m.isNew()) { + fullnames.append(m).append(","); + } + } + } + if (fullnames.length() > 0) { + fullnames.deleteCharAt(fullnames.length() - 1); + ReadMessage.readMessage(mOauthRetrofit, mAccessToken, fullnames.toString(), + new ReadMessage.ReadMessageListener() { + @Override + public void readSuccess() {} + + @Override + public void readFailed() {} + }); + } + } else { + isSendingMessage = false; + Snackbar.make(mCoordinatorLayout, R.string.error_getting_message, Snackbar.LENGTH_LONG).show(); + } + } + } + } + }); + } + + public void fetchUserAvatar(String username, ProvideUserAvatarCallback provideUserAvatarCallback) { + if (mUserAvatar == null) { + mProvideUserAvatarCallbacks.add(provideUserAvatarCallback); + if (mLoadUserDataAsyncTask == null) { + mLoadUserDataAsyncTask = new LoadUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), username, mRetrofit, iconImageUrl -> { + mUserAvatar = iconImageUrl; + for (ProvideUserAvatarCallback provideUserAvatarCallbackInArrayList : mProvideUserAvatarCallbacks) { + provideUserAvatarCallbackInArrayList.fetchAvatarSuccess(iconImageUrl); + } + mProvideUserAvatarCallbacks.clear(); + }); + mLoadUserDataAsyncTask.execute(); + } + } else { + provideUserAvatarCallback.fetchAvatarSuccess(mUserAvatar); + } + } + + public void delayTransition() { + TransitionManager.beginDelayedTransition(mRecyclerView, new AutoTransition()); + } + + private void goToBottom() { + if (mLinearLayoutManager != null && mAdapter != null) { + mLinearLayoutManager.scrollToPositionWithOffset(mAdapter.getItemCount() - 1, 0); + } + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(USER_AVATAR_STATE, mUserAvatar); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + mLinearLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(mAppBarLayout, mToolbar); + mDivider.setBackgroundColor(mCustomThemeWrapper.getDividerColor()); + mEditText.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); + mSecondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + mEditText.setHintTextColor(mSecondaryTextColor); + mEditTextLinearLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + mSendMessageIconColor = mCustomThemeWrapper.getSendMessageIconColor(); + mSendImageView.setColorFilter(mSendMessageIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + + @Override + public void onLongPress() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } + + public interface ProvideUserAvatarCallback { + void fetchAvatarSuccess(String userAvatarUrl); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java new file mode 100644 index 00000000..0eaa24c9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewRedditGalleryActivity.java @@ -0,0 +1,242 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.SharedPreferences; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; +import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.viewpager.widget.ViewPager; + +import com.thefuntasty.hauler.DragDirection; +import com.thefuntasty.hauler.HaulerView; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.ContentFontStyle; +import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.FontStyle; +import ml.docilealligator.infinityforreddit.font.TitleFontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontStyle; +import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryImageOrGifFragment; +import ml.docilealligator.infinityforreddit.fragments.ViewRedditGalleryVideoFragment; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.WallpaperSetter; + +public class ViewRedditGalleryActivity extends AppCompatActivity implements SetAsWallpaperCallback { + + public static final String EXTRA_REDDIT_GALLERY = "ERG"; + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + + @BindView(R.id.hauler_view_view_reddit_gallery_activity) + HaulerView haulerView; + @BindView(R.id.view_pager_view_reddit_gallery_activity) + ViewPager viewPager; + private SectionsPagerAdapter sectionsPagerAdapter; + private ArrayList gallery; + private String subredditName; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ((Infinity) getApplication()).getAppComponent().inject(this); + + getTheme().applyStyle(R.style.Theme_Normal, true); + + getTheme().applyStyle(FontStyle.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.FONT_SIZE_KEY, FontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(TitleFontStyle.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY, TitleFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(ContentFontStyle.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY, ContentFontStyle.Normal.name())).getResId(), true); + + getTheme().applyStyle(FontFamily.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(TitleFontFamily.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(ContentFontFamily.valueOf(sharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); + + setContentView(R.layout.activity_view_reddit_gallery); + + ButterKnife.bind(this); + + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + + setTitle(" "); + + gallery = getIntent().getParcelableArrayListExtra(EXTRA_REDDIT_GALLERY); + if (gallery == null || gallery.isEmpty()) { + finish(); + return; + } + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + + haulerView.setOnDragDismissedListener(dragDirection -> { + int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; + finish(); + overridePendingTransition(0, slide); + }); + + setupViewPager(); + } + + private void setupViewPager() { + setToolbarTitle(0); + sectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager()); + viewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + setToolbarTitle(position); + } + }); + viewPager.setAdapter(sectionsPagerAdapter); + } + + private void setToolbarTitle(int position) { + if (gallery != null && position >= 0 && position < gallery.size()) { + if (gallery.get(position).mediaType == Post.Gallery.TYPE_IMAGE) { + setTitle(getString(R.string.view_reddit_gallery_activity_image_label, position + 1, gallery.size())); + } else if (gallery.get(position).mediaType == Post.Gallery.TYPE_GIF) { + setTitle(getString(R.string.view_reddit_gallery_activity_gif_label, position + 1, gallery.size())); + } else { + setTitle(getString(R.string.view_reddit_gallery_activity_video_label, position + 1, gallery.size())); + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + + return false; + } + + @Override + public void setToHomeScreen(int viewPagerPosition) { + if (gallery != null && viewPagerPosition >= 0 && viewPagerPosition < gallery.size()) { + WallpaperSetter.set(gallery.get(viewPagerPosition).url, WallpaperSetter.HOME_SCREEN, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewRedditGalleryActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewRedditGalleryActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + @Override + public void setToLockScreen(int viewPagerPosition) { + if (gallery != null && viewPagerPosition >= 0 && viewPagerPosition < gallery.size()) { + WallpaperSetter.set(gallery.get(viewPagerPosition).url, WallpaperSetter.LOCK_SCREEN, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewRedditGalleryActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewRedditGalleryActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + @Override + public void setToBoth(int viewPagerPosition) { + if (gallery != null && viewPagerPosition >= 0 && viewPagerPosition < gallery.size()) { + WallpaperSetter.set(gallery.get(viewPagerPosition).url, WallpaperSetter.BOTH_SCREENS, this, + new WallpaperSetter.SetWallpaperListener() { + @Override + public void success() { + Toast.makeText(ViewRedditGalleryActivity.this, R.string.wallpaper_set, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewRedditGalleryActivity.this, R.string.error_set_wallpaper, Toast.LENGTH_SHORT).show(); + } + }); + } + } + + public int getCurrentPagePosition() { + return viewPager.getCurrentItem(); + } + + private class SectionsPagerAdapter extends FragmentStatePagerAdapter { + + SectionsPagerAdapter(@NonNull FragmentManager fm) { + super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT); + } + + @NonNull + @Override + public Fragment getItem(int position) { + Post.Gallery media = gallery.get(position); + if (media.mediaType == Post.Gallery.TYPE_VIDEO) { + ViewRedditGalleryVideoFragment fragment = new ViewRedditGalleryVideoFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(ViewRedditGalleryVideoFragment.EXTRA_REDDIT_GALLERY_VIDEO, media); + bundle.putString(ViewRedditGalleryVideoFragment.EXTRA_SUBREDDIT_NAME, subredditName); + fragment.setArguments(bundle); + return fragment; + } else { + ViewRedditGalleryImageOrGifFragment fragment = new ViewRedditGalleryImageOrGifFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(ViewRedditGalleryImageOrGifFragment.EXTRA_REDDIT_GALLERY_MEDIA, media); + bundle.putString(ViewRedditGalleryImageOrGifFragment.EXTRA_SUBREDDIT_NAME, subredditName); + fragment.setArguments(bundle); + return fragment; + } + } + + @Override + public int getCount() { + return gallery.size(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java new file mode 100644 index 00000000..ff6b6875 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java @@ -0,0 +1,1324 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.graphics.Point; +import android.os.Build; +import android.os.Bundle; +import android.view.Display; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.Window; +import android.view.WindowManager; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +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.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.ViewModelProvider; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.bottomappbar.BottomAppBar; +import com.google.android.material.chip.Chip; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.text.SimpleDateFormat; +import java.util.Locale; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; +import ml.docilealligator.infinityforreddit.asynctasks.CheckIsSubscribedToSubredditAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.InsertSubredditDataAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FABMoreOptionsBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.RandomBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.GoBackToMainPageEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.fragments.SidebarFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditSubscription; +import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class ViewSubredditDetailActivity extends BaseActivity implements SortTypeSelectionCallback, + PostTypeBottomSheetFragment.PostTypeSelectionCallback, PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, + ActivityToolbarInterface, FABMoreOptionsBottomSheetFragment.FABOptionSelectionCallback, + RandomBottomSheetFragment.RandomOptionSelectionCallback { + + public static final String EXTRA_SUBREDDIT_NAME_KEY = "ESN"; + public static final String EXTRA_MESSAGE_FULLNAME = "ENF"; + public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; + public static final String EXTRA_VIEW_SIDEBAR = "EVSB"; + + private static final String FETCH_SUBREDDIT_INFO_STATE = "FSIS"; + private static final String CURRENT_ONLINE_SUBSCRIBERS_STATE = "COSS"; + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String MESSAGE_FULLNAME_STATE = "MFS"; + private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; + + @BindView(R.id.coordinator_layout_view_subreddit_detail_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.view_pager_view_subreddit_detail_activity) + ViewPager2 viewPager2; + @BindView(R.id.appbar_layout_view_subreddit_detail_activity) + AppBarLayout appBarLayout; + @BindView(R.id.collapsing_toolbar_layout_view_subreddit_detail_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.toolbar_linear_layout_view_subreddit_detail_activity) + LinearLayout linearLayout; + @BindView(R.id.toolbar) + Toolbar toolbar; + @BindView(R.id.tab_layout_view_subreddit_detail_activity) + TabLayout tabLayout; + @BindView(R.id.banner_image_view_view_subreddit_detail_activity) + GifImageView bannerImageView; + @BindView(R.id.icon_gif_image_view_view_subreddit_detail_activity) + GifImageView iconGifImageView; + @BindView(R.id.subscribe_subreddit_chip_view_subreddit_detail_activity) + Chip subscribeSubredditChip; + @BindView(R.id.subreddit_name_text_view_view_subreddit_detail_activity) + TextView subredditNameTextView; + @BindView(R.id.subscriber_count_text_view_view_subreddit_detail_activity) + TextView nSubscribersTextView; + @BindView(R.id.online_subscriber_count_text_view_view_subreddit_detail_activity) + TextView nOnlineSubscribersTextView; + @BindView(R.id.since_text_view_view_subreddit_detail_activity) + TextView sinceTextView; + @BindView(R.id.creation_time_text_view_view_subreddit_detail_activity) + TextView creationTimeTextView; + @BindView(R.id.description_text_view_view_subreddit_detail_activity) + TextView descriptionTextView; + @BindView(R.id.bottom_navigation_view_subreddit_detail_activity) + BottomAppBar bottomNavigationView; + @BindView(R.id.linear_layout_bottom_app_bar_view_subreddit_detail_activity) + LinearLayout linearLayoutBottomAppBar; + @BindView(R.id.option_1_bottom_app_bar_view_subreddit_detail_activity) + ImageView option1BottomAppBar; + @BindView(R.id.option_2_bottom_app_bar_view_subreddit_detail_activity) + ImageView option2BottomAppBar; + @BindView(R.id.option_3_bottom_app_bar_view_subreddit_detail_activity) + ImageView option3BottomAppBar; + @BindView(R.id.option_4_bottom_app_bar_view_subreddit_detail_activity) + ImageView option4BottomAppBar; + @BindView(R.id.fab_view_subreddit_detail_activity) + FloatingActionButton fab; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("bottom_app_bar") + SharedPreferences bottomAppBarSharedPreference; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + public SubredditViewModel mSubredditViewModel; + private FragmentManager fragmentManager; + private SectionsPagerAdapter sectionsPagerAdapter; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String subredditName; + private boolean mFetchSubredditInfoSuccess = false; + private int mNCurrentOnlineSubscribers = 0; + private boolean subscriptionReady = false; + private boolean isInLazyMode = false; + private boolean showToast = false; + private boolean showBottomAppBar; + private boolean lockBottomAppBar; + private String mMessageFullname; + private String mNewAccountName; + private RequestManager glide; + private Menu mMenu; + private AppBarLayout.LayoutParams params; + private PostTypeBottomSheetFragment postTypeBottomSheetFragment; + private SortTypeBottomSheetFragment sortTypeBottomSheetFragment; + private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + private FABMoreOptionsBottomSheetFragment fabMoreOptionsBottomSheetFragment; + private int expandedTabTextColor; + private int expandedTabBackgroundColor; + private int expandedTabIndicatorColor; + private int collapsedTabTextColor; + private int collapsedTabBackgroundColor; + private int collapsedTabIndicatorColor; + private int unsubscribedColor; + private int subscribedColor; + private SlidrInterface mSlidrInterface; + private MaterialAlertDialogBuilder nsfwWarningBuilder; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + setTransparentStatusBarAfterToolbarCollapsed(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_view_subreddit_detail); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + showToast = true; + + int navBarHeight = getNavBarHeight(); + if (navBarHeight > 0) { + CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); + params.bottomMargin += navBarHeight; + fab.setLayoutParams(params); + coordinatorLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + coordinatorLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); + + Display display = getWindowManager().getDefaultDisplay(); + Point size = new Point(); + display.getRealSize(size); + if (size.y == coordinatorLayout.getHeight()) { + linearLayoutBottomAppBar.setPadding(0, + linearLayoutBottomAppBar.getPaddingTop(), 0, navBarHeight); + } + } + }); + + showToast = true; + } + } + + View decorView = window.getDecorView(); + if (isChangeStatusBarIconColor()) { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, AppBarStateChangeListener.State state) { + if (state == State.COLLAPSED) { + decorView.setSystemUiVisibility(getSystemVisibilityToolbarCollapsed()); + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } else if (state == State.EXPANDED) { + decorView.setSystemUiVisibility(getSystemVisibilityToolbarExpanded()); + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } + } + }); + } else { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + if (state == State.COLLAPSED) { + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } else if (state == State.EXPANDED) { + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } + } + }); + } + } else { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + if (state == State.EXPANDED) { + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } else if (state == State.COLLAPSED) { + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } + } + }); + } + + showBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false); + lockBottomAppBar = mSharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR, false); + boolean hideSubredditDescription = mSharedPreferences.getBoolean(SharedPreferencesUtils.HIDE_SUBREDDIT_DESCRIPTION, false); + + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME_KEY); + + fragmentManager = getSupportFragmentManager(); + + if (savedInstanceState == null) { + mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); + getCurrentAccountAndBindView(); + } else { + mFetchSubredditInfoSuccess = savedInstanceState.getBoolean(FETCH_SUBREDDIT_INFO_STATE); + mNCurrentOnlineSubscribers = savedInstanceState.getInt(CURRENT_ONLINE_SUBSCRIBERS_STATE); + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); + mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + + if (mFetchSubredditInfoSuccess) { + nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, mNCurrentOnlineSubscribers)); + } + } + + fetchSubredditData(); + + postTypeBottomSheetFragment = new PostTypeBottomSheetFragment(); + + sortTypeBottomSheetFragment = new SortTypeBottomSheetFragment(); + Bundle bottomSheetBundle = new Bundle(); + bottomSheetBundle.putBoolean(SortTypeBottomSheetFragment.EXTRA_NO_BEST_TYPE, true); + sortTypeBottomSheetFragment.setArguments(bottomSheetBundle); + + sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + fabMoreOptionsBottomSheetFragment = new FABMoreOptionsBottomSheetFragment(); + + params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); + + String title = "r/" + subredditName; + subredditNameTextView.setText(title); + + toolbar.setTitle(title); + adjustToolbar(toolbar); + setSupportActionBar(toolbar); + setToolbarGoToTop(toolbar); + + glide = Glide.with(this); + Locale locale = getResources().getConfiguration().locale; + + mSubredditViewModel = new ViewModelProvider(this, + new SubredditViewModel.Factory(getApplication(), mRedditDataRoomDatabase, subredditName)) + .get(SubredditViewModel.class); + mSubredditViewModel.getSubredditLiveData().observe(this, subredditData -> { + if (subredditData != null) { + if (subredditData.getBannerUrl().equals("")) { + iconGifImageView.setOnClickListener(view -> { + //Do nothing as it has no image + }); + } else { + glide.load(subredditData.getBannerUrl()).into(bannerImageView); + bannerImageView.setOnClickListener(view -> { + Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, subredditData.getBannerUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, subredditName + "-banner.jpg"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, subredditName); + startActivity(intent); + }); + } + + if (subredditData.getIconUrl().equals("")) { + glide.load(getDrawable(R.drawable.subreddit_default_icon)) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) + .into(iconGifImageView); + iconGifImageView.setOnClickListener(view -> { + //Do nothing as it is a default icon + }); + } else { + glide.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); + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(ViewSubredditDetailActivity.this, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, subredditData.getIconUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, subredditName + "-icon.jpg"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, subredditName); + startActivity(intent); + }); + } + + String subredditFullName = "r/" + subredditData.getName(); + if (!title.equals(subredditFullName)) { + getSupportActionBar().setTitle(subredditFullName); + } + subredditNameTextView.setText(subredditFullName); + String nSubscribers = getString(R.string.subscribers_number_detail, subredditData.getNSubscribers()); + nSubscribersTextView.setText(nSubscribers); + creationTimeTextView.setText(new SimpleDateFormat("MMM d, yyyy", + locale).format(subredditData.getCreatedUTC())); + if (hideSubredditDescription || subredditData.getDescription().equals("")) { + descriptionTextView.setVisibility(View.GONE); + } else { + descriptionTextView.setVisibility(View.VISIBLE); + descriptionTextView.setText(subredditData.getDescription()); + } + + if (subredditData.isNSFW()) { + if (nsfwWarningBuilder == null + && !mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)) { + nsfwWarningBuilder = new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.warning) + .setMessage(R.string.this_is_a_nsfw_subreddit) + .setPositiveButton(R.string.leave, (dialogInterface, i) + -> { + finish(); + }) + .setNegativeButton(R.string.dismiss, null); + nsfwWarningBuilder.show(); + } + } + } + }); + } + + @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()); + collapsingToolbarLayout.setContentScrimColor(mCustomThemeWrapper.getColorPrimary()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + expandedTabTextColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTextColor(); + expandedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabIndicator(); + expandedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabBackground(); + collapsedTabTextColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor(); + collapsedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabIndicator(); + collapsedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabBackground(); + linearLayout.setBackgroundColor(expandedTabBackgroundColor); + subredditNameTextView.setTextColor(mCustomThemeWrapper.getSubreddit()); + subscribeSubredditChip.setTextColor(mCustomThemeWrapper.getChipTextColor()); + int primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + nSubscribersTextView.setTextColor(primaryTextColor); + nOnlineSubscribersTextView.setTextColor(primaryTextColor); + sinceTextView.setTextColor(primaryTextColor); + creationTimeTextView.setTextColor(primaryTextColor); + descriptionTextView.setTextColor(primaryTextColor); + bottomNavigationView.setBackgroundTint(ColorStateList.valueOf(mCustomThemeWrapper.getBottomAppBarBackgroundColor())); + int bottomAppBarIconColor = mCustomThemeWrapper.getBottomAppBarIconColor(); + option2BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option1BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option3BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + option4BottomAppBar.setColorFilter(bottomAppBarIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + applyTabLayoutTheme(tabLayout); + applyFABTheme(fab); + unsubscribedColor = mCustomThemeWrapper.getUnsubscribed(); + subscribedColor = mCustomThemeWrapper.getSubscribed(); + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (mNewAccountName != null) { + if (account == null || !account.getUsername().equals(mNewAccountName)) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { + EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); + Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); + + mNewAccountName = null; + if (newAccount == null) { + mNullAccessToken = true; + } else { + mAccessToken = newAccount.getAccessToken(); + mAccountName = newAccount.getUsername(); + } + + bindView(); + }).execute(); + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + bindView(); + } + } else { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + + bindView(); + } + }).execute(); + } + + private void fetchSubredditData() { + if (!mFetchSubredditInfoSuccess) { + FetchSubredditData.fetchSubredditData(mRetrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { + @Override + public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { + mNCurrentOnlineSubscribers = nCurrentOnlineSubscribers; + nOnlineSubscribersTextView.setText(getString(R.string.online_subscribers_number_detail, nCurrentOnlineSubscribers)); + new InsertSubredditDataAsyncTask(mRedditDataRoomDatabase, subredditData, () -> mFetchSubredditInfoSuccess = true).execute(); + } + + @Override + public void onFetchSubredditDataFail() { + makeSnackbar(R.string.cannot_fetch_subreddit_info, true); + mFetchSubredditInfoSuccess = false; + } + }); + } + } + + private void bottomAppBarOptionAction(int option) { + switch (option) { + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME: { + EventBus.getDefault().post(new GoBackToMainPageEvent()); + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: { + Intent intent = new Intent(this, SubscribedThingListingActivity.class); + startActivity(intent); + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX: { + Intent intent = new Intent(this, InboxActivity.class); + startActivity(intent); + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE: { + Intent intent = new Intent(this, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mAccountName); + startActivity(intent); + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: { + Intent intent = new Intent(this, SubscribedThingListingActivity.class); + intent.putExtra(SubscribedThingListingActivity.EXTRA_SHOW_MULTIREDDITS, true); + startActivity(intent); + break; + } + } + } + + private int getBottomAppBarOptionDrawableResource(int option) { + switch (option) { + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME: + return R.drawable.ic_home_black_24dp; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS: + return R.drawable.ic_subscritptions_bottom_app_bar_24dp; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX: + return R.drawable.ic_inbox_24dp; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_MULTIREDDITS: + return R.drawable.ic_multi_reddit_24dp; + default: + return R.drawable.ic_account_circle_24dp; + } + } + + private void bindView() { + if (mAccessToken != null) { + if (mMessageFullname != null) { + ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { + @Override + public void readSuccess() { + mMessageFullname = null; + } + + @Override + public void readFailed() { + + } + }); + } + + if (showBottomAppBar) { + int optionCount = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT, 4); + int option1 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME); + int option2 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS); + + bottomNavigationView.setVisibility(View.VISIBLE); + + if (optionCount == 2) { + linearLayoutBottomAppBar.setWeightSum(3); + option1BottomAppBar.setVisibility(View.GONE); + option3BottomAppBar.setVisibility(View.GONE); + + option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); + option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); + + option2BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option1); + }); + + option4BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option2); + }); + } else { + int option3 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX); + int option4 = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE); + + option1BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option1)); + option2BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option2)); + option3BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option3)); + option4BottomAppBar.setImageResource(getBottomAppBarOptionDrawableResource(option4)); + + option1BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option1); + }); + + option2BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option2); + }); + + option3BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option3); + }); + + option4BottomAppBar.setOnClickListener(view -> { + bottomAppBarOptionAction(option4); + }); + } + } else { + CoordinatorLayout.LayoutParams lp = (CoordinatorLayout.LayoutParams) fab.getLayoutParams(); + lp.setAnchorId(View.NO_ID); + lp.gravity = Gravity.END | Gravity.BOTTOM; + fab.setLayoutParams(lp); + } + + int fabOption = bottomAppBarSharedPreference.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB, SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS); + switch (fabOption) { + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_REFRESH: + fab.setImageResource(R.drawable.ic_refresh_24dp); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: + fab.setImageResource(R.drawable.ic_sort_toolbar_24dp); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: + fab.setImageResource(R.drawable.ic_post_layout_24dp); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SEARCH: + fab.setImageResource(R.drawable.ic_search_black_24dp); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: + fab.setImageResource(R.drawable.ic_subreddit_24dp); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_USER: + fab.setImageResource(R.drawable.ic_user_24dp); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_RANDOM: + fab.setImageResource(R.drawable.ic_random_24dp); + break; + default: + fab.setImageResource(R.drawable.ic_add_day_night_24dp); + break; + } + fab.setOnClickListener(view -> { + switch (fabOption) { + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_REFRESH: { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.refresh(); + } + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE: { + sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT: { + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SEARCH: { + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + break; + } + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT: + goToSubreddit(); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_USER: + goToUser(); + break; + case SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_RANDOM: + random(); + break; + default: + postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); + break; + } + }); + fab.setOnLongClickListener(view -> { + fabMoreOptionsBottomSheetFragment.show(getSupportFragmentManager(), fabMoreOptionsBottomSheetFragment.getTag()); + return true; + }); + + fab.setVisibility(View.VISIBLE); + } else { + bottomNavigationView.setVisibility(View.GONE); + fab.setVisibility(View.GONE); + } + + subscribeSubredditChip.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(ViewSubredditDetailActivity.this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (subscriptionReady) { + subscriptionReady = false; + if (subscribeSubredditChip.getText().equals(getResources().getString(R.string.subscribe))) { + SubredditSubscription.subscribeToSubreddit(mOauthRetrofit, mRetrofit, mAccessToken, + subredditName, mAccountName, mRedditDataRoomDatabase, + new SubredditSubscription.SubredditSubscriptionListener() { + @Override + public void onSubredditSubscriptionSuccess() { + subscribeSubredditChip.setText(R.string.unsubscribe); + subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); + makeSnackbar(R.string.subscribed, false); + subscriptionReady = true; + } + + @Override + public void onSubredditSubscriptionFail() { + makeSnackbar(R.string.subscribe_failed, false); + subscriptionReady = true; + } + }); + } else { + SubredditSubscription.unsubscribeToSubreddit(mOauthRetrofit, mAccessToken, + subredditName, mAccountName, mRedditDataRoomDatabase, + new SubredditSubscription.SubredditSubscriptionListener() { + @Override + public void onSubredditSubscriptionSuccess() { + subscribeSubredditChip.setText(R.string.subscribe); + subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); + makeSnackbar(R.string.unsubscribed, false); + subscriptionReady = true; + } + + @Override + public void onSubredditSubscriptionFail() { + makeSnackbar(R.string.unsubscribe_failed, false); + subscriptionReady = true; + } + }); + } + } + }); + + new CheckIsSubscribedToSubredditAsyncTask(mRedditDataRoomDatabase, subredditName, mAccountName, + new CheckIsSubscribedToSubredditAsyncTask.CheckIsSubscribedToSubredditListener() { + @Override + public void isSubscribed() { + subscribeSubredditChip.setText(R.string.unsubscribe); + subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); + subscriptionReady = true; + } + + @Override + public void isNotSubscribed() { + subscribeSubredditChip.setText(R.string.subscribe); + subscribeSubredditChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); + subscriptionReady = true; + } + }).execute(); + + sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + if (position == 0) { + unlockSwipeRightToGoBack(); + } else { + lockSwipeRightToGoBack(); + } + + if (mAccessToken != null) { + if (showBottomAppBar) { + bottomNavigationView.performShow(); + } + fab.show(); + } + + sectionsPagerAdapter.displaySortTypeInToolbar(); + } + }); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(2); + viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); + new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { + switch (position) { + case 0: + tab.setText(R.string.posts); + break; + case 1: + tab.setText(R.string.sidebar); + } + }).attach(); + fixViewPager2Sensitivity(viewPager2); + + boolean viewSidebar = getIntent().getBooleanExtra(EXTRA_VIEW_SIDEBAR, false); + if (viewSidebar) { + viewPager2.setCurrentItem(1, false); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_subreddit_detail_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_subreddit_detail_activity); + if (isInLazyMode) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } else { + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | + AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_sort_view_subreddit_detail_activity: + sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); + return true; + case R.id.action_search_view_subreddit_detail_activity: + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + return true; + case R.id.action_refresh_view_subreddit_detail_activity: + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_view_subreddit_detail_activity).setTitle(R.string.action_start_lazy_mode); + } + sectionsPagerAdapter.refresh(); + mFetchSubredditInfoSuccess = false; + fetchSubredditData(); + return true; + case R.id.action_lazy_mode_view_subreddit_detail_activity: + if (sectionsPagerAdapter != null) { + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_subreddit_detail_activity); + if (isInLazyMode) { + isInLazyMode = false; + sectionsPagerAdapter.stopLazyMode(); + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | + AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = true; + if (sectionsPagerAdapter.startLazyMode()) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + appBarLayout.setExpanded(false); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = false; + } + } + } + return true; + case R.id.action_change_post_layout_view_subreddit_detail_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + case R.id.action_select_user_flair_view_subreddit_detail_activity: + if (mAccessToken == null) { + Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return true; + } + Intent selectUserFlairIntent = new Intent(this, SelectUserFlairActivity.class); + selectUserFlairIntent.putExtra(SelectUserFlairActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(selectUserFlairIntent); + return true; + case R.id.action_share_view_subreddit_detail_activity: + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_TEXT, "https://www.reddit.com/r/" + subredditName); + if (shareIntent.resolveActivity(getPackageManager()) != null) { + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } else { + Toast.makeText(this, R.string.no_app, Toast.LENGTH_SHORT).show(); + } + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(FETCH_SUBREDDIT_INFO_STATE, mFetchSubredditInfoSuccess); + outState.putInt(CURRENT_ONLINE_SUBSCRIBERS_STATE, mNCurrentOnlineSubscribers); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); + outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + private void makeSnackbar(int resId, boolean retry) { + if (showToast) { + Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); + } else { + if (retry) { + Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).setAction(R.string.retry, + view -> fetchSubredditData()).show(); + } else { + Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).show(); + } + } + } + + @Override + public void sortTypeSelected(SortType sortType) { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.changeSortType(sortType); + } + } + + @Override + public void sortTypeSelected(String sortType) { + Bundle bundle = new Bundle(); + bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); + sortTimeBottomSheetFragment.setArguments(bundle); + sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); + } + + @Override + public void postTypeSelected(int postType) { + Intent intent; + switch (postType) { + case PostTypeBottomSheetFragment.TYPE_TEXT: + intent = new Intent(this, PostTextActivity.class); + intent.putExtra(PostTextActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_LINK: + intent = new Intent(this, PostLinkActivity.class); + intent.putExtra(PostLinkActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_IMAGE: + intent = new Intent(this, PostImageActivity.class); + intent.putExtra(PostImageActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_VIDEO: + intent = new Intent(this, PostVideoActivity.class); + intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + } + } + + @Override + public void postLayoutSelected(int postLayout) { + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + subredditName, postLayout).apply(); + sectionsPagerAdapter.changePostLayout(postLayout); + } + + public void contentScrollUp() { + if (mAccessToken != null) { + if (showBottomAppBar && !lockBottomAppBar) { + bottomNavigationView.performShow(); + } + if (!(showBottomAppBar && lockBottomAppBar)) { + fab.show(); + } + } + } + + public void contentScrollDown() { + if (mAccessToken != null) { + if (!(showBottomAppBar && lockBottomAppBar)) { + fab.hide(); + } + if (showBottomAppBar && !lockBottomAppBar) { + bottomNavigationView.performHide(); + } + } + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + if (!getClass().getName().equals(event.excludeActivityClassName)) { + finish(); + } + } + + @Subscribe + public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { + sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); + } + + @Subscribe + public void goBackToMainPageEvent(GoBackToMainPageEvent event) { + finish(); + } + + @Override + public void onLongPress() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.goBackToTop(); + } + } + + @Override + public void displaySortType() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.displaySortTypeInToolbar(); + } + } + + @Override + public void fabOptionSelected(int option) { + switch (option) { + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SUBMIT_POST: + postTypeBottomSheetFragment.show(getSupportFragmentManager(), postTypeBottomSheetFragment.getTag()); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_REFRESH: + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.refresh(); + } + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_SORT_TYPE: + sortTypeBottomSheetFragment.show(getSupportFragmentManager(), sortTypeBottomSheetFragment.getTag()); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_CHANGE_POST_LAYOUT: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_SEARCH: + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + break; + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_SUBREDDIT: { + goToSubreddit(); + break; + } + case FABMoreOptionsBottomSheetFragment.FAB_OPTION_GO_TO_USER: { + goToUser(); + break; + } + case FABMoreOptionsBottomSheetFragment.FAB_RANDOM: { + random(); + break; + } + } + } + + private void goToSubreddit() { + EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); + thingEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.go_to_subreddit) + .setView(thingEditText) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent subredditIntent = new Intent(this, ViewSubredditDetailActivity.class); + subredditIntent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, thingEditText.getText().toString()); + startActivity(subredditIntent); + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) + .show(); + } + + private void goToUser() { + EditText thingEditText = (EditText) getLayoutInflater().inflate(R.layout.dialog_go_to_thing_edit_text, null); + thingEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.go_to_user) + .setView(thingEditText) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + Intent userIntent = new Intent(this, ViewUserDetailActivity.class); + userIntent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, thingEditText.getText().toString()); + startActivity(userIntent); + }) + .setNegativeButton(R.string.cancel, null) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(thingEditText.getWindowToken(), 0); + } + }) + .show(); + } + + private void random() { + RandomBottomSheetFragment randomBottomSheetFragment = new RandomBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putBoolean(RandomBottomSheetFragment.EXTRA_IS_NSFW, mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)); + randomBottomSheetFragment.setArguments(bundle); + randomBottomSheetFragment.show(getSupportFragmentManager(), randomBottomSheetFragment.getTag()); + } + + @Override + public void randomOptionSelected(int option) { + Intent intent = new Intent(this, FetchRandomSubredditOrPostActivity.class); + intent.putExtra(FetchRandomSubredditOrPostActivity.EXTRA_RANDOM_OPTION, option); + startActivity(intent); + } + + private class SectionsPagerAdapter extends FragmentStateAdapter { + + SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { + super(fm, lifecycle); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + if (position == 0) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putString(PostFragment.EXTRA_NAME, subredditName); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + SidebarFragment fragment = new SidebarFragment(); + Bundle bundle = new Bundle(); + bundle.putString(SidebarFragment.EXTRA_SUBREDDIT_NAME, subredditName); + fragment.setArguments(bundle); + return fragment; + } + + @Nullable + private Fragment getCurrentFragment() { + if (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 SidebarFragment) { + ((SidebarFragment) fragment).fetchSubredditData(); + } + } + + boolean startLazyMode() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof FragmentCommunicator) { + return ((FragmentCommunicator) fragment).startLazyMode(); + } + return false; + } + + void stopLazyMode() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) fragment).stopLazyMode(); + } + } + + public void changeSortType(SortType sortType) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeSortType(sortType); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } + } + + public void changeNSFW(boolean nsfw) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeNSFW(nsfw); + } + } + + void changePostLayout(int postLayout) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changePostLayout(postLayout); + } + } + + void goBackToTop() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).goBackToTop(); + } else if (fragment instanceof SidebarFragment) { + ((SidebarFragment) fragment).goBackToTop(); + } + } + + void displaySortTypeInToolbar() { + if (fragmentManager != null) { + Fragment fragment = fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); + if (fragment instanceof PostFragment) { + SortType sortType = ((PostFragment) fragment).getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } + } + } + + @Override + public int getItemCount() { + return 2; + } + } + + private void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + private void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java new file mode 100644 index 00000000..f7b77dbe --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java @@ -0,0 +1,1025 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.net.Uri; +import android.os.AsyncTask; +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 android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +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.FragmentManager; +import androidx.lifecycle.Lifecycle; +import androidx.lifecycle.ViewModelProvider; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.appbar.CollapsingToolbarLayout; +import com.google.android.material.chip.Chip; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.tabs.TabLayout; +import com.google.android.material.tabs.TabLayoutMediator; +import com.r0adkll.slidr.Slidr; +import com.r0adkll.slidr.model.SlidrInterface; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.text.SimpleDateFormat; +import java.util.Locale; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.AppBarStateChangeListener; +import ml.docilealligator.infinityforreddit.asynctasks.CheckIsFollowingUserAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SwitchAccountAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.PostLayoutBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SortTimeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.UserThingSortTypeBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.DeleteThing; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.fragments.CommentsListingFragment; +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserDao; +import ml.docilealligator.infinityforreddit.user.BlockUser; +import ml.docilealligator.infinityforreddit.user.FetchUserData; +import ml.docilealligator.infinityforreddit.user.UserDao; +import ml.docilealligator.infinityforreddit.user.UserData; +import ml.docilealligator.infinityforreddit.user.UserFollowing; +import ml.docilealligator.infinityforreddit.user.UserViewModel; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class ViewUserDetailActivity extends BaseActivity implements SortTypeSelectionCallback, + PostLayoutBottomSheetFragment.PostLayoutSelectionCallback, ActivityToolbarInterface { + + public static final String EXTRA_USER_NAME_KEY = "EUNK"; + public static final String EXTRA_MESSAGE_FULLNAME = "ENF"; + public static final String EXTRA_NEW_ACCOUNT_NAME = "ENAN"; + public static final int GIVE_AWARD_REQUEST_CODE = 200; + public static final int EDIT_COMMENT_REQUEST_CODE = 300; + + private static final String FETCH_USER_INFO_STATE = "FSIS"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String MESSAGE_FULLNAME_STATE = "MFS"; + private static final String NEW_ACCOUNT_NAME_STATE = "NANS"; + + @BindView(R.id.coordinator_layout_view_user_detail_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.view_pager_view_user_detail_activity) + ViewPager2 viewPager2; + @BindView(R.id.appbar_layout_view_user_detail) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_view_user_detail_activity) + Toolbar toolbar; + @BindView(R.id.toolbar_linear_layout_view_user_detail_activity) + LinearLayout linearLayout; + @BindView(R.id.tab_layout_view_user_detail_activity) + TabLayout tabLayout; + @BindView(R.id.collapsing_toolbar_layout_view_user_detail_activity) + CollapsingToolbarLayout collapsingToolbarLayout; + @BindView(R.id.banner_image_view_view_user_detail_activity) + GifImageView bannerImageView; + @BindView(R.id.icon_gif_image_view_view_user_detail_activity) + GifImageView iconGifImageView; + @BindView(R.id.user_name_text_view_view_user_detail_activity) + TextView userNameTextView; + @BindView(R.id.subscribe_user_chip_view_user_detail_activity) + Chip subscribeUserChip; + @BindView(R.id.karma_text_view_view_user_detail_activity) + TextView karmaTextView; + @BindView(R.id.cakeday_text_view_view_user_detail_activity) + TextView cakedayTextView; + @BindView(R.id.description_text_view_view_user_detail_activity) + TextView descriptionTextView; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + public UserViewModel userViewModel; + private FragmentManager fragmentManager; + private SectionsPagerAdapter sectionsPagerAdapter; + private SubscribedUserDao subscribedUserDao; + private RequestManager glide; + private Menu mMenu; + private AppBarLayout.LayoutParams params; + private UserThingSortTypeBottomSheetFragment userThingSortTypeBottomSheetFragment; + private SortTimeBottomSheetFragment sortTimeBottomSheetFragment; + private PostLayoutBottomSheetFragment postLayoutBottomSheetFragment; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private String username; + private boolean subscriptionReady = false; + private boolean mFetchUserInfoSuccess = false; + private boolean isInLazyMode = false; + private int expandedTabTextColor; + private int expandedTabBackgroundColor; + private int expandedTabIndicatorColor; + private int collapsedTabTextColor; + private int collapsedTabBackgroundColor; + private int collapsedTabIndicatorColor; + private int unsubscribedColor; + private int subscribedColor; + private boolean showToast = false; + private String mMessageFullname; + private String mNewAccountName; + private SlidrInterface mSlidrInterface; + private MaterialAlertDialogBuilder nsfwWarningBuilder; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + setTransparentStatusBarAfterToolbarCollapsed(); + + super.onCreate(savedInstanceState); + + setContentView(R.layout.activity_view_user_detail); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + mSlidrInterface = Slidr.attach(this); + } + + username = getIntent().getStringExtra(EXTRA_USER_NAME_KEY); + + fragmentManager = getSupportFragmentManager(); + + if (savedInstanceState == null) { + mMessageFullname = getIntent().getStringExtra(EXTRA_MESSAGE_FULLNAME); + mNewAccountName = getIntent().getStringExtra(EXTRA_NEW_ACCOUNT_NAME); + getCurrentAccountAndInitializeViewPager(); + } else { + mFetchUserInfoSuccess = savedInstanceState.getBoolean(FETCH_USER_INFO_STATE); + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + mMessageFullname = savedInstanceState.getString(MESSAGE_FULLNAME_STATE); + mNewAccountName = savedInstanceState.getString(NEW_ACCOUNT_NAME_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndInitializeViewPager(); + } else { + initializeViewPager(); + } + } + + fetchUserInfo(); + + params = (AppBarLayout.LayoutParams) collapsingToolbarLayout.getLayoutParams(); + + Resources resources = getResources(); + + adjustToolbar(toolbar); + + String title = "u/" + username; + userNameTextView.setText(title); + toolbar.setTitle(title); + + setSupportActionBar(toolbar); + setToolbarGoToTop(toolbar); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Window window = getWindow(); + if (isImmersiveInterface()) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + coordinatorLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); + } else { + window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS); + } + showToast = true; + } + + View decorView = window.getDecorView(); + if (isChangeStatusBarIconColor()) { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + if (state == State.COLLAPSED) { + decorView.setSystemUiVisibility(getSystemVisibilityToolbarCollapsed()); + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } else if (state == State.EXPANDED) { + decorView.setSystemUiVisibility(getSystemVisibilityToolbarExpanded()); + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } + } + }); + } else { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + if (state == State.COLLAPSED) { + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } else if (state == State.EXPANDED) { + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } + } + }); + } + } else { + appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() { + @Override + public void onStateChanged(AppBarLayout appBarLayout, State state) { + if (state == State.EXPANDED) { + tabLayout.setTabTextColors(expandedTabTextColor, expandedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(expandedTabIndicatorColor); + tabLayout.setBackgroundColor(expandedTabBackgroundColor); + } else if (state == State.COLLAPSED) { + tabLayout.setTabTextColors(collapsedTabTextColor, collapsedTabTextColor); + tabLayout.setSelectedTabIndicatorColor(collapsedTabIndicatorColor); + tabLayout.setBackgroundColor(collapsedTabBackgroundColor); + } + } + }); + } + + subscribedUserDao = mRedditDataRoomDatabase.subscribedUserDao(); + glide = Glide.with(this); + Locale locale = getResources().getConfiguration().locale; + + userViewModel = new ViewModelProvider(this, new UserViewModel.Factory(getApplication(), mRedditDataRoomDatabase, username)) + .get(UserViewModel.class); + userViewModel.getUserLiveData().observe(this, userData -> { + if (userData != null) { + if (userData.getBanner().equals("")) { + bannerImageView.setOnClickListener(null); + } else { + glide.load(userData.getBanner()).into(bannerImageView); + bannerImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, userData.getBanner()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, username + "-banner.jpg"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, username); + startActivity(intent); + }); + } + + if (userData.getIconUrl().equals("")) { + glide.load(getDrawable(R.drawable.subreddit_default_icon)) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(216, 0))) + .into(iconGifImageView); + iconGifImageView.setOnClickListener(null); + } else { + glide.load(userData.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); + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, userData.getIconUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, username + "-icon.jpg"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, username); + startActivity(intent); + }); + } + + if (userData.isCanBeFollowed()) { + subscribeUserChip.setVisibility(View.VISIBLE); + subscribeUserChip.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(ViewUserDetailActivity.this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (subscriptionReady) { + subscriptionReady = false; + if (subscribeUserChip.getText().equals(resources.getString(R.string.follow))) { + UserFollowing.followUser(mOauthRetrofit, mRetrofit, mAccessToken, + username, mAccountName, subscribedUserDao, new UserFollowing.UserFollowingListener() { + @Override + public void onUserFollowingSuccess() { + subscribeUserChip.setText(R.string.unfollow); + subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); + showMessage(R.string.followed, false); + subscriptionReady = true; + } + + @Override + public void onUserFollowingFail() { + showMessage(R.string.follow_failed, false); + subscriptionReady = true; + } + }); + } else { + UserFollowing.unfollowUser(mOauthRetrofit, mRetrofit, mAccessToken, + username, mAccountName, subscribedUserDao, new UserFollowing.UserFollowingListener() { + @Override + public void onUserFollowingSuccess() { + subscribeUserChip.setText(R.string.follow); + subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); + showMessage(R.string.unfollowed, false); + subscriptionReady = true; + } + + @Override + public void onUserFollowingFail() { + showMessage(R.string.unfollow_failed, false); + subscriptionReady = true; + } + }); + } + } + }); + + new CheckIsFollowingUserAsyncTask(subscribedUserDao, username, mAccountName, new CheckIsFollowingUserAsyncTask.CheckIsFollowingUserListener() { + @Override + public void isSubscribed() { + subscribeUserChip.setText(R.string.unfollow); + subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(subscribedColor)); + subscriptionReady = true; + } + + @Override + public void isNotSubscribed() { + subscribeUserChip.setText(R.string.follow); + subscribeUserChip.setChipBackgroundColor(ColorStateList.valueOf(unsubscribedColor)); + subscriptionReady = true; + } + }).execute(); + } else { + subscribeUserChip.setVisibility(View.GONE); + } + + String userFullName = "u/" + userData.getName(); + userNameTextView.setText(userFullName); + if (!title.equals(userFullName)) { + getSupportActionBar().setTitle(userFullName); + } + String karma = getString(R.string.karma_info_user_detail, userData.getTotalKarma(), userData.getLinkKarma(), userData.getCommentKarma()); + karmaTextView.setText(karma); + cakedayTextView.setText(getString(R.string.cakeday_info, new SimpleDateFormat("MMM d, yyyy", + locale).format(userData.getCakeday()))); + + if (userData.getDescription() == null || userData.getDescription().equals("")) { + descriptionTextView.setVisibility(View.GONE); + } else { + descriptionTextView.setVisibility(View.VISIBLE); + descriptionTextView.setText(userData.getDescription()); + } + + if (userData.isNSFW()) { + if (nsfwWarningBuilder == null + && !mNsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.NSFW_BASE, false)) { + nsfwWarningBuilder = new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.warning) + .setMessage(R.string.this_user_has_nsfw_content) + .setPositiveButton(R.string.leave, (dialogInterface, i) + -> { + finish(); + }) + .setNegativeButton(R.string.dismiss, null); + nsfwWarningBuilder.show(); + } + } + } + }); + + userThingSortTypeBottomSheetFragment = new UserThingSortTypeBottomSheetFragment(); + sortTimeBottomSheetFragment = new SortTimeBottomSheetFragment(); + postLayoutBottomSheetFragment = new PostLayoutBottomSheetFragment(); + } + + @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()); + collapsingToolbarLayout.setContentScrimColor(mCustomThemeWrapper.getColorPrimary()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + expandedTabTextColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTextColor(); + expandedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabIndicator(); + expandedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithExpandedCollapsingToolbarTabBackground(); + collapsedTabTextColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTextColor(); + collapsedTabIndicatorColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabIndicator(); + collapsedTabBackgroundColor = mCustomThemeWrapper.getTabLayoutWithCollapsedCollapsingToolbarTabBackground(); + linearLayout.setBackgroundColor(expandedTabBackgroundColor); + unsubscribedColor = mCustomThemeWrapper.getUnsubscribed(); + subscribedColor = mCustomThemeWrapper.getSubscribed(); + userNameTextView.setTextColor(mCustomThemeWrapper.getUsername()); + karmaTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); + cakedayTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); + descriptionTextView.setTextColor(mCustomThemeWrapper.getPrimaryTextColor()); + subscribeUserChip.setTextColor(mCustomThemeWrapper.getChipTextColor()); + applyTabLayoutTheme(tabLayout); + } + + private void getCurrentAccountAndInitializeViewPager() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (mNewAccountName != null) { + if (account == null || !account.getUsername().equals(mNewAccountName)) { + new SwitchAccountAsyncTask(mRedditDataRoomDatabase, mNewAccountName, newAccount -> { + EventBus.getDefault().post(new SwitchAccountEvent(getClass().getName())); + Toast.makeText(this, R.string.account_switched, Toast.LENGTH_SHORT).show(); + + mNewAccountName = null; + if (newAccount == null) { + mNullAccessToken = true; + } else { + mAccessToken = newAccount.getAccessToken(); + mAccountName = newAccount.getUsername(); + } + + initializeViewPager(); + }).execute(); + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + initializeViewPager(); + } + } else { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + + initializeViewPager(); + } + }).execute(); + } + + private void initializeViewPager() { + sectionsPagerAdapter = new SectionsPagerAdapter(fragmentManager, getLifecycle()); + viewPager2.setAdapter(sectionsPagerAdapter); + viewPager2.setOffscreenPageLimit(2); + viewPager2.setUserInputEnabled(!mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS, false)); + new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> { + switch (position) { + case 0: + tab.setText(R.string.posts); + break; + case 1: + tab.setText(R.string.comments); + break; + } + }).attach(); + + viewPager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { + @Override + public void onPageSelected(int position) { + if (position == 0) { + unlockSwipeRightToGoBack(); + } else { + lockSwipeRightToGoBack(); + } + sectionsPagerAdapter.displaySortTypeInToolbar(); + } + }); + + fixViewPager2Sensitivity(viewPager2); + + if (mAccessToken != null && mMessageFullname != null) { + ReadMessage.readMessage(mOauthRetrofit, mAccessToken, mMessageFullname, new ReadMessage.ReadMessageListener() { + @Override + public void readSuccess() { + mMessageFullname = null; + } + + @Override + public void readFailed() { + + } + }); + } + } + + private void fetchUserInfo() { + if (!mFetchUserInfoSuccess) { + FetchUserData.fetchUserData(mRetrofit, username, new FetchUserData.FetchUserDataListener() { + @Override + public void onFetchUserDataSuccess(UserData userData) { + new ViewUserDetailActivity.InsertUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), userData, + () -> mFetchUserInfoSuccess = true).execute(); + } + + @Override + public void onFetchUserDataFailed() { + showMessage(R.string.cannot_fetch_user_info, true); + mFetchUserInfoSuccess = false; + } + }); + } + } + + public void deleteComment(String fullName) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete_this_comment) + .setMessage(R.string.are_you_sure) + .setPositiveButton(R.string.delete, (dialogInterface, i) + -> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() { + @Override + public void deleteSuccess() { + Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void deleteFailed() { + Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_failed, Toast.LENGTH_SHORT).show(); + } + })) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_user_detail_activity, menu); + applyMenuItemTheme(menu); + mMenu = menu; + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_user_detail_activity); + if (isInLazyMode) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } else { + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | + AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } + + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_sort_view_user_detail_activity: + userThingSortTypeBottomSheetFragment.show(getSupportFragmentManager(), userThingSortTypeBottomSheetFragment.getTag()); + return true; + case R.id.action_search_view_user_detail_activity: + Intent intent = new Intent(this, SearchActivity.class); + intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_NAME, username); + intent.putExtra(SearchActivity.EXTRA_SUBREDDIT_IS_USER, true); + startActivity(intent); + return true; + case R.id.action_refresh_view_user_detail_activity: + if (mMenu != null) { + mMenu.findItem(R.id.action_lazy_mode_view_user_detail_activity).setTitle(R.string.action_start_lazy_mode); + } + sectionsPagerAdapter.refresh(); + mFetchUserInfoSuccess = false; + fetchUserInfo(); + return true; + case R.id.action_lazy_mode_view_user_detail_activity: + MenuItem lazyModeItem = mMenu.findItem(R.id.action_lazy_mode_view_user_detail_activity); + if (isInLazyMode) { + isInLazyMode = false; + sectionsPagerAdapter.stopLazyMode(); + lazyModeItem.setTitle(R.string.action_start_lazy_mode); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS | + AppBarLayout.LayoutParams.SCROLL_FLAG_ENTER_ALWAYS_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = true; + if (sectionsPagerAdapter.startLazyMode()) { + lazyModeItem.setTitle(R.string.action_stop_lazy_mode); + appBarLayout.setExpanded(false); + params.setScrollFlags(AppBarLayout.LayoutParams.SCROLL_FLAG_SCROLL | AppBarLayout.LayoutParams.SCROLL_FLAG_EXIT_UNTIL_COLLAPSED); + collapsingToolbarLayout.setLayoutParams(params); + } else { + isInLazyMode = false; + } + } + return true; + case R.id.action_change_post_layout_view_user_detail_activity: + postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); + return true; + case R.id.action_share_view_user_detail_activity: + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.setType("text/plain"); + shareIntent.putExtra(Intent.EXTRA_TEXT, "https://www.reddit.com/user/" + username); + if (shareIntent.resolveActivity(getPackageManager()) != null) { + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } else { + Toast.makeText(this, R.string.no_app, Toast.LENGTH_SHORT).show(); + } + return true; + case R.id.action_send_private_message_view_user_detail_activity: + if (mAccessToken == null) { + Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return true; + } + + Intent pmIntent = new Intent(this, SendPrivateMessageActivity.class); + pmIntent.putExtra(SendPrivateMessageActivity.EXTRA_RECIPIENT_USERNAME, username); + startActivity(pmIntent); + return true; + case R.id.action_report_view_user_detail_activity: + Intent reportIntent = new Intent(this, LinkResolverActivity.class); + reportIntent.setData(Uri.parse("https://www.reddithelp.com/en/categories/rules-reporting/account-and-community-restrictions/what-should-i-do-if-i-see-something-i")); + startActivity(reportIntent); + return true; + case R.id.action_block_user_view_user_detail_activity: + if (mAccessToken == null) { + Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return true; + } + + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.block_user) + .setMessage(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> BlockUser.blockUser(mOauthRetrofit, mAccessToken, username, new BlockUser.BlockUserListener() { + @Override + public void success() { + Toast.makeText(ViewUserDetailActivity.this, R.string.block_user_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + Toast.makeText(ViewUserDetailActivity.this, R.string.block_user_failed, Toast.LENGTH_SHORT).show(); + } + })) + .setNegativeButton(R.string.no, null) + .show(); + return true; + } + return false; + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == RESULT_OK) { + if (requestCode == GIVE_AWARD_REQUEST_CODE) { + Toast.makeText(this, R.string.give_award_success, Toast.LENGTH_SHORT).show(); + int position = data.getIntExtra(GiveAwardActivity.EXTRA_RETURN_ITEM_POSITION, 0); + String newAwardsHTML = data.getStringExtra(GiveAwardActivity.EXTRA_RETURN_NEW_AWARDS); + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.giveAward(newAwardsHTML, position); + } + } else if (requestCode == EDIT_COMMENT_REQUEST_CODE) { + if (data != null) { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.editComment( + data.getStringExtra(EditCommentActivity.EXTRA_EDITED_COMMENT_CONTENT), + data.getExtras().getInt(EditCommentActivity.EXTRA_EDITED_COMMENT_POSITION)); + } + } + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(FETCH_USER_INFO_STATE, mFetchUserInfoSuccess); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putString(MESSAGE_FULLNAME_STATE, mMessageFullname); + outState.putString(NEW_ACCOUNT_NAME_STATE, mNewAccountName); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + private void showMessage(int resId, boolean retry) { + if (showToast) { + Toast.makeText(this, resId, Toast.LENGTH_SHORT).show(); + } else { + if (retry) { + Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).setAction(R.string.retry, + view -> fetchUserInfo()).show(); + } else { + Snackbar.make(coordinatorLayout, resId, Snackbar.LENGTH_SHORT).show(); + } + } + } + + @Override + public void sortTypeSelected(SortType sortType) { + sectionsPagerAdapter.changeSortType(sortType); + } + + @Override + public void sortTypeSelected(String sortType) { + Bundle bundle = new Bundle(); + bundle.putString(SortTimeBottomSheetFragment.EXTRA_SORT_TYPE, sortType); + sortTimeBottomSheetFragment.setArguments(bundle); + sortTimeBottomSheetFragment.show(getSupportFragmentManager(), sortTimeBottomSheetFragment.getTag()); + } + + @Override + public void postLayoutSelected(int postLayout) { + sectionsPagerAdapter.changePostLayout(postLayout); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + if (!getClass().getName().equals(event.excludeActivityClassName)) { + finish(); + } + } + + @Subscribe + public void onChangeNSFWEvent(ChangeNSFWEvent changeNSFWEvent) { + sectionsPagerAdapter.changeNSFW(changeNSFWEvent.nsfw); + } + + @Override + public void onLongPress() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.goBackToTop(); + } + } + + @Override + public void displaySortType() { + if (sectionsPagerAdapter != null) { + sectionsPagerAdapter.displaySortTypeInToolbar(); + } + } + + private static class InsertUserDataAsyncTask extends AsyncTask { + + private UserDao userDao; + private UserData subredditData; + private InsertUserDataAsyncTaskListener insertUserDataAsyncTaskListener; + InsertUserDataAsyncTask(UserDao userDao, UserData userData, + InsertUserDataAsyncTaskListener insertUserDataAsyncTaskListener) { + this.userDao = userDao; + this.subredditData = userData; + this.insertUserDataAsyncTaskListener = insertUserDataAsyncTaskListener; + } + + @Override + protected Void doInBackground(final Void... params) { + userDao.insert(subredditData); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + insertUserDataAsyncTaskListener.insertSuccess(); + } + + interface InsertUserDataAsyncTaskListener { + void insertSuccess(); + } + } + + private class SectionsPagerAdapter extends FragmentStateAdapter { + + SectionsPagerAdapter(FragmentManager fm, Lifecycle lifecycle) { + super(fm, lifecycle); + } + + @NonNull + @Override + public Fragment createFragment(int position) { + if (position == 0) { + PostFragment fragment = new PostFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(PostFragment.EXTRA_POST_TYPE, PostDataSource.TYPE_USER); + bundle.putString(PostFragment.EXTRA_USER_NAME, username); + bundle.putString(PostFragment.EXTRA_USER_WHERE, PostDataSource.USER_WHERE_SUBMITTED); + bundle.putInt(PostFragment.EXTRA_FILTER, PostFragment.EXTRA_NO_FILTER); + bundle.putString(PostFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(PostFragment.EXTRA_ACCOUNT_NAME, mAccountName); + fragment.setArguments(bundle); + return fragment; + } + CommentsListingFragment fragment = new CommentsListingFragment(); + Bundle bundle = new Bundle(); + bundle.putString(CommentsListingFragment.EXTRA_USERNAME, username); + bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); + bundle.putBoolean(CommentsListingFragment.EXTRA_ARE_SAVED_COMMENTS, false); + fragment.setArguments(bundle); + return fragment; + } + + @Override + public int getItemCount() { + return 2; + } + + @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(); + } + } + + boolean startLazyMode() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof FragmentCommunicator) { + return ((FragmentCommunicator) fragment).startLazyMode(); + } + return false; + } + + void stopLazyMode() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof FragmentCommunicator) { + ((FragmentCommunicator) fragment).stopLazyMode(); + } + } + + public void changeSortType(SortType sortType) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeSortType(sortType); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } else if (fragment instanceof CommentsListingFragment) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_USER_COMMENT, sortType.getType().name()).apply(); + if(sortType.getTime() != null) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_USER_COMMENT, sortType.getTime().name()).apply(); + } + ((CommentsListingFragment) fragment).changeSortType(sortType); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } + } + + public void changeNSFW(boolean nsfw) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changeNSFW(nsfw); + } + } + + void changePostLayout(int postLayout) { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).changePostLayout(postLayout); + } + } + + void goBackToTop() { + Fragment fragment = getCurrentFragment(); + if (fragment instanceof PostFragment) { + ((PostFragment) fragment).goBackToTop(); + } else if (fragment instanceof CommentsListingFragment) { + ((CommentsListingFragment) fragment).goBackToTop(); + } + } + + void displaySortTypeInToolbar() { + if (fragmentManager != null) { + Fragment fragment = fragmentManager.findFragmentByTag("f" + viewPager2.getCurrentItem()); + if (fragment instanceof PostFragment) { + SortType sortType = ((PostFragment) fragment).getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } else if (fragment instanceof CommentsListingFragment) { + SortType sortType = ((CommentsListingFragment) fragment).getSortType(); + Utils.displaySortTypeInToolbar(sortType, toolbar); + } + } + } + + void giveAward(String awardsHTML, int position) { + if (fragmentManager != null) { + Fragment fragment = fragmentManager.findFragmentByTag("f1"); + if (fragment instanceof CommentsListingFragment) { + ((CommentsListingFragment) fragment).giveAward(awardsHTML, position); + } + } + } + + void editComment(String commentMarkdown, int position) { + if (fragmentManager != null) { + Fragment fragment = fragmentManager.findFragmentByTag("f1"); + if (fragment instanceof CommentsListingFragment) { + ((CommentsListingFragment) fragment).editComment(commentMarkdown, position); + } + } + } + } + + private void lockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.lock(); + } + } + + private void unlockSwipeRightToGoBack() { + if (mSlidrInterface != null) { + mSlidrInterface.unlock(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java new file mode 100644 index 00000000..66bd7b73 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewVideoActivity.java @@ -0,0 +1,508 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.Manifest; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.Html; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.source.ProgressiveMediaSource; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.source.hls.HlsMediaSource; +import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelection; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.ui.PlayerView; +import com.google.android.exoplayer2.ui.TrackSelectionDialogBuilder; +import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory; +import com.google.android.exoplayer2.util.Util; +import com.google.android.material.snackbar.Snackbar; +import com.thefuntasty.hauler.DragDirection; +import com.thefuntasty.hauler.HaulerView; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; +import ml.docilealligator.infinityforreddit.font.ContentFontFamily; +import ml.docilealligator.infinityforreddit.font.FontFamily; +import ml.docilealligator.infinityforreddit.font.TitleFontFamily; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.services.DownloadMediaService; +import ml.docilealligator.infinityforreddit.services.DownloadRedditVideoService; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + +public class ViewVideoActivity extends AppCompatActivity { + + 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_PROGRESS_SECONDS = "EPS"; + public static final String EXTRA_VIDEO_TYPE = "EVT"; + public static final String EXTRA_GFYCAT_ID = "EGI"; + public static final String EXTRA_IS_NSFW = "EIN"; + public static final int VIDEO_TYPE_DIRECT = 3; + public static final int VIDEO_TYPE_REDGIFS = 2; + public static final int VIDEO_TYPE_GFYCAT = 1; + private static final int VIDEO_TYPE_NORMAL = 0; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; + private static final String IS_MUTE_STATE = "IMS"; + private static final String VIDEO_DOWNLOAD_URL_STATE = "VDUS"; + private static final String VIDEO_URI_STATE = "VUS"; + @BindView(R.id.hauler_view_view_video_activity) + HaulerView haulerView; + @BindView(R.id.coordinator_layout_view_video_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.progress_bar_view_video_activity) + ProgressBar progressBar; + @BindView(R.id.player_view_view_video_activity) + PlayerView videoPlayerView; + @BindView(R.id.mute_exo_playback_control_view) + ImageButton muteButton; + @BindView(R.id.hd_exo_playback_control_view) + ImageButton hdButton; + + private Uri mVideoUri; + private SimpleExoPlayer player; + private DefaultTrackSelector trackSelector; + private DataSource.Factory dataSourceFactory; + + private String videoDownloadUrl; + private String videoFileName; + private String subredditName; + private String id; + private boolean wasPlaying; + private boolean isDownloading = false; + private boolean isMute = false; + private String postTitle; + private boolean isNSFW; + private long resumePosition = -1; + private int videoType; + private boolean isDataSavingMode; + private boolean isHd; + + @Inject + @Named("gfycat") + Retrofit gfycatRetrofit; + + @Inject + @Named("redgifs") + Retrofit redgifsRetrofit; + + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ((Infinity) getApplication()).getAppComponent().inject(this); + + getTheme().applyStyle(R.style.Theme_Normal, true); + + getTheme().applyStyle(FontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.FONT_FAMILY_KEY, FontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(TitleFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY, TitleFontFamily.Default.name())).getResId(), true); + + getTheme().applyStyle(ContentFontFamily.valueOf(mSharedPreferences + .getString(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY, ContentFontFamily.Default.name())).getResId(), true); + + setContentView(R.layout.activity_view_video); + + ButterKnife.bind(this); + setVolumeControlStream(AudioManager.STREAM_MUSIC); + + ActionBar actionBar = getSupportActionBar(); + Drawable upArrow = getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp); + actionBar.setHomeAsUpIndicator(upArrow); + actionBar.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.transparentActionBarAndExoPlayerControllerColor))); + + String dataSavingModeString = mSharedPreferences.getString(SharedPreferencesUtils.DATA_SAVING_MODE, SharedPreferencesUtils.DATA_SAVING_MODE_OFF); + int networkType = Utils.getConnectedNetwork(this); + if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ALWAYS)) { + isDataSavingMode = true; + } else if (dataSavingModeString.equals(SharedPreferencesUtils.DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA)) { + isDataSavingMode = networkType == Utils.NETWORK_TYPE_CELLULAR; + } + isHd = !isDataSavingMode; + + if (!mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_IGNORE_NAV_BAR, false)) { + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { + //Set player controller bottom margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); + params.bottomMargin = getResources().getDimensionPixelSize(resourceId); + } else { + //Set player controller right margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + LinearLayout controllerLinearLayout = findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); + params.rightMargin = getResources().getDimensionPixelSize(resourceId); + } + } + + haulerView.setOnDragDismissedListener(dragDirection -> { + int slide = dragDirection == DragDirection.UP ? R.anim.slide_out_up : R.anim.slide_out_down; + finish(); + overridePendingTransition(0, slide); + }); + + Intent intent = getIntent(); + mVideoUri = intent.getData(); + postTitle = intent.getStringExtra(EXTRA_POST_TITLE); + isNSFW = intent.getBooleanExtra(EXTRA_IS_NSFW, false); + if (savedInstanceState == null) { + resumePosition = intent.getLongExtra(EXTRA_PROGRESS_SECONDS, -1); + } + + + if (postTitle != null) { + setTitle(Html.fromHtml(String.format("%s", postTitle))); + } else { + setTitle(""); + } + + videoPlayerView.setControllerVisibilityListener(visibility -> { + switch (visibility) { + case View.GONE: + getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE); + break; + case View.VISIBLE: + getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } + }); + + TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); + trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); + player = ExoPlayerFactory.newSimpleInstance(this, trackSelector); + videoPlayerView.setPlayer(player); + videoType = getIntent().getIntExtra(EXTRA_VIDEO_TYPE, VIDEO_TYPE_NORMAL); + if (videoType == VIDEO_TYPE_GFYCAT || videoType == VIDEO_TYPE_REDGIFS) { + if (savedInstanceState != null) { + String videoUrl = savedInstanceState.getString(VIDEO_URI_STATE); + if (videoUrl != null) { + mVideoUri = Uri.parse(videoUrl); + } + videoDownloadUrl = savedInstanceState.getString(VIDEO_DOWNLOAD_URL_STATE); + } else { + mVideoUri = intent.getData(); + videoDownloadUrl = intent.getStringExtra(EXTRA_VIDEO_DOWNLOAD_URL); + } + + String gfycatId = intent.getStringExtra(EXTRA_GFYCAT_ID); + if (gfycatId != null && gfycatId.contains("-")) { + gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); + } + if (videoType == VIDEO_TYPE_GFYCAT) { + videoFileName = "Gfycat-" + gfycatId + ".mp4"; + } else { + videoFileName = "Redgifs-" + gfycatId + ".mp4"; + } + + if (mVideoUri == null) { + if (videoType == VIDEO_TYPE_GFYCAT) { + loadGfycatOrRedgifsVideo(gfycatRetrofit, gfycatId, savedInstanceState, true); + } else { + loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false); + } + } else { + dataSourceFactory = new DefaultDataSourceFactory(ViewVideoActivity.this, + Util.getUserAgent(ViewVideoActivity.this, "Infinity")); + player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); + preparePlayer(savedInstanceState); + } + } else if (videoType == VIDEO_TYPE_DIRECT) { + videoDownloadUrl = mVideoUri.toString(); + videoFileName = videoDownloadUrl.substring(videoDownloadUrl.lastIndexOf('/') + 1); + // Produces DataSource instances through which media data is loaded. + dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity")); + // Prepare the player with the source. + player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); + } else { + videoDownloadUrl = intent.getStringExtra(EXTRA_VIDEO_DOWNLOAD_URL); + subredditName = intent.getStringExtra(EXTRA_SUBREDDIT); + id = intent.getStringExtra(EXTRA_ID); + videoFileName = subredditName + "-" + id + ".mp4"; + // Produces DataSource instances through which media data is loaded. + dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "Infinity")); + // Prepare the player with the source. + player.prepare(new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); + } + + preparePlayer(savedInstanceState); + } + + private void preparePlayer(Bundle savedInstanceState) { + player.setRepeatMode(Player.REPEAT_MODE_ALL); + if (resumePosition > 0) { + player.seekTo(resumePosition); + } + player.setPlayWhenReady(true); + wasPlaying = true; + + boolean muteVideo = mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_VIDEO, false) || + (mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_NSFW_VIDEO, false) && isNSFW); + + if (savedInstanceState != null) { + isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); + if (isMute) { + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + } else if (muteVideo) { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + + player.addListener(new Player.EventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + if (videoType == VIDEO_TYPE_NORMAL) { + if (isDataSavingMode) { + trackSelector.setParameters( + trackSelector.buildUponParameters() + .setMaxVideoSize(720, 720)); + } + + hdButton.setVisibility(View.VISIBLE); + hdButton.setOnClickListener(view -> { + TrackSelectionDialogBuilder build = new TrackSelectionDialogBuilder(ViewVideoActivity.this, getString(R.string.select_video_quality), trackSelector, 0); + build.setShowDisableOption(true); + build.setAllowAdaptiveSelections(false); + build.build().show(); + }); + } + + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + muteButton.setVisibility(View.VISIBLE); + muteButton.setOnClickListener(view -> { + if (isMute) { + isMute = false; + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } else { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } + }); + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + }); + } + + private void loadGfycatOrRedgifsVideo(Retrofit retrofit, String gfycatId, Bundle savedInstanceState, boolean needErrorHandling) { + progressBar.setVisibility(View.VISIBLE); + FetchGfycatOrRedgifsVideoLinks.fetchGfycatOrRedgifsVideoLinks(retrofit, gfycatId, + new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { + @Override + public void success(String webm, String mp4) { + progressBar.setVisibility(View.GONE); + mVideoUri = Uri.parse(webm); + videoDownloadUrl = mp4; + dataSourceFactory = new DefaultDataSourceFactory(ViewVideoActivity.this, + Util.getUserAgent(ViewVideoActivity.this, "Infinity")); + player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(mVideoUri)); + preparePlayer(savedInstanceState); + } + + @Override + public void failed(int errorCode) { + progressBar.setVisibility(View.GONE); + if (videoType == VIDEO_TYPE_GFYCAT) { + if (errorCode == 404 && needErrorHandling) { + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.AUTOMATICALLY_TRY_REDGIFS, true)) { + loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false); + } else { + Snackbar.make(coordinatorLayout, R.string.load_video_in_redgifs, Snackbar.LENGTH_INDEFINITE).setAction(R.string.yes, + view -> loadGfycatOrRedgifsVideo(redgifsRetrofit, gfycatId, savedInstanceState, false)).show(); + } + } else { + Toast.makeText(ViewVideoActivity.this, R.string.fetch_gfycat_video_failed, Toast.LENGTH_SHORT).show(); + } + } else { + Toast.makeText(ViewVideoActivity.this, R.string.fetch_redgifs_video_failed, Toast.LENGTH_SHORT).show(); + } + } + }); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.view_video, menu); + return true; + } + + @Override + protected void onDestroy() { + super.onDestroy(); + player.release(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case android.R.id.home: + finish(); + return true; + case R.id.action_download_view_video_activity: + if (isDownloading) { + return false; + } + + if (videoDownloadUrl == null) { + Toast.makeText(this, R.string.fetching_video_info_please_wait, Toast.LENGTH_SHORT).show(); + return true; + } + + isDownloading = true; + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(this, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + return true; + } + + return false; + } + + @Override + protected void onStart() { + super.onStart(); + if (wasPlaying) { + player.setPlayWhenReady(true); + } + } + + @Override + protected void onStop() { + super.onStop(); + wasPlaying = player.getPlayWhenReady(); + player.setPlayWhenReady(false); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + isDownloading = false; + } + } + + private void download() { + isDownloading = false; + + if (videoType != VIDEO_TYPE_NORMAL) { + Intent intent = new Intent(this, DownloadMediaService.class); + intent.putExtra(DownloadMediaService.EXTRA_URL, videoDownloadUrl); + intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_VIDEO); + intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, videoFileName); + intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, subredditName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + } else { + Intent intent = new Intent(this, DownloadRedditVideoService.class); + intent.putExtra(DownloadRedditVideoService.EXTRA_VIDEO_URL, videoDownloadUrl); + intent.putExtra(DownloadRedditVideoService.EXTRA_POST_ID, id); + intent.putExtra(DownloadRedditVideoService.EXTRA_SUBREDDIT, subredditName); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + startForegroundService(intent); + } else { + startService(intent); + } + } + Toast.makeText(this, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_MUTE_STATE, isMute); + if (mVideoUri != null) { + outState.putString(VIDEO_URI_STATE, mVideoUri.toString()); + outState.putString(VIDEO_DOWNLOAD_URL_STATE, videoDownloadUrl); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AcknowledgementRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AcknowledgementRecyclerViewAdapter.java new file mode 100644 index 00000000..c6f7ee56 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AcknowledgementRecyclerViewAdapter.java @@ -0,0 +1,70 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.Intent; +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.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.settings.Acknowledgement; + +public class AcknowledgementRecyclerViewAdapter extends RecyclerView.Adapter { + private ArrayList acknowledgements; + private Context context; + + public AcknowledgementRecyclerViewAdapter(Context context, ArrayList acknowledgements) { + this.context = context; + this.acknowledgements = acknowledgements; + } + + @NonNull + @Override + public AcknowledgementViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new AcknowledgementViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_acknowledgement, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull AcknowledgementViewHolder holder, int position) { + Acknowledgement acknowledgement = acknowledgements.get(holder.getAdapterPosition()); + if (acknowledgement != null) { + holder.nameTextView.setText(acknowledgement.getName()); + holder.introductionTextView.setText(acknowledgement.getIntroduction()); + holder.itemView.setOnClickListener(view -> { + if (context != null) { + Intent intent = new Intent(context, LinkResolverActivity.class); + intent.setData(acknowledgement.getLink()); + context.startActivity(intent); + } + }); + } + } + + @Override + public int getItemCount() { + return acknowledgements == null ? 0 : acknowledgements.size(); + } + + class AcknowledgementViewHolder extends RecyclerView.ViewHolder { + View itemView; + @BindView(R.id.name_text_view_item_acknowledgement) + TextView nameTextView; + @BindView(R.id.introduction_text_view_item_acknowledgement) + TextView introductionTextView; + + AcknowledgementViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + this.itemView = itemView; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AwardRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AwardRecyclerViewAdapter.java new file mode 100644 index 00000000..5f233a53 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/AwardRecyclerViewAdapter.java @@ -0,0 +1,98 @@ +package ml.docilealligator.infinityforreddit.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 com.bumptech.glide.RequestManager; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.award.Award; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import pl.droidsonroids.gif.GifImageView; + +public class AwardRecyclerViewAdapter extends RecyclerView.Adapter { + + private ArrayList awards; + private RequestManager glide; + private ItemOnClickListener itemOnClickListener; + private int primaryTextColor; + private int secondaryTextColor; + + public interface ItemOnClickListener { + void onClick(Award award); + } + + public AwardRecyclerViewAdapter(RequestManager glide, CustomThemeWrapper customThemeWrapper, + ItemOnClickListener itemOnClickListener) { + awards = Award.getAvailableAwards(); + this.glide = glide; + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + this.itemOnClickListener = itemOnClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new AwardViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_award, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof AwardViewHolder) { + Award award = awards.get(position); + glide.load(award.getIconUrl()).into(((AwardViewHolder) holder).iconImageView); + ((AwardViewHolder) holder).nameTextView.setText(award.getName()); + ((AwardViewHolder) holder).desctiptionTextView.setText(award.getDescription()); + ((AwardViewHolder) holder).coinTextView.setText(Integer.toString(award.getCoinPrice())); + } + } + + @Override + public int getItemCount() { + return awards.size(); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof AwardViewHolder) { + glide.clear(((AwardViewHolder) holder).iconImageView); + ((AwardViewHolder) holder).nameTextView.setText(""); + ((AwardViewHolder) holder).desctiptionTextView.setText(""); + } + } + + class AwardViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.icon_image_view_item_award) + GifImageView iconImageView; + @BindView(R.id.name_text_view_item_award) + TextView nameTextView; + @BindView(R.id.description_text_view_item_award) + TextView desctiptionTextView; + @BindView(R.id.coin_text_view_item_award) + TextView coinTextView; + + public AwardViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + nameTextView.setTextColor(primaryTextColor); + desctiptionTextView.setTextColor(secondaryTextColor); + coinTextView.setTextColor(primaryTextColor); + + itemView.setOnClickListener(view -> { + itemOnClickListener.onClick(awards.get(getAdapterPosition())); + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java new file mode 100644 index 00000000..ed9c50df --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentAndPostRecyclerViewAdapter.java @@ -0,0 +1,3887 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Color; +import android.graphics.ColorFilter; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +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.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.constraintlayout.widget.ConstraintSet; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.RequestBuilder; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.Target; +import com.google.android.exoplayer2.metadata.Metadata; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.text.Cue; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; +import com.google.android.exoplayer2.ui.PlayerView; +import com.libRG.CustomTextView; +import com.lsjwzh.widget.materialloadingprogressbar.CircleProgressBar; + +import org.commonmark.ext.gfm.tables.TableBlock; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import butterknife.BindView; +import butterknife.ButterKnife; +import im.ene.toro.CacheManager; +import im.ene.toro.ToroPlayer; +import im.ene.toro.ToroUtil; +import im.ene.toro.exoplayer.ExoCreator; +import im.ene.toro.exoplayer.ExoPlayerViewHelper; +import im.ene.toro.exoplayer.Playable; +import im.ene.toro.media.PlaybackInfo; +import im.ene.toro.widget.Container; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.recycler.MarkwonAdapter; +import io.noties.markwon.recycler.table.TableEntry; +import io.noties.markwon.recycler.table.TableEntryPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import jp.wasabeef.glide.transformations.BlurTransformation; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.activities.CommentActivity; +import ml.docilealligator.infinityforreddit.activities.FilteredThingActivity; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewImageOrGifActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewRedditGalleryActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewVideoActivity; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIconAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadUserDataAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CommentMoreBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CopyTextBottomSheetFragment; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.ShareLinkBottomSheetFragment; +import ml.docilealligator.infinityforreddit.comment.Comment; +import ml.docilealligator.infinityforreddit.comment.FetchComment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; +import ml.docilealligator.infinityforreddit.customviews.MarkwonLinearLayoutManager; +import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SaveThing; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import ml.docilealligator.infinityforreddit.VoteThing; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +import static ml.docilealligator.infinityforreddit.activities.CommentActivity.WRITE_COMMENT_REQUEST_CODE; + +public class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter implements CacheManager { + private static final int VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY = 1; + private static final int VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW = 2; + private static final int VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY = 3; + private static final int VIEW_TYPE_POST_DETAIL_LINK = 4; + private static final int VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK = 5; + private static final int VIEW_TYPE_POST_DETAIL_GALLERY = 6; + private static final int VIEW_TYPE_POST_DETAIL_TEXT_TYPE = 7; + private static final int VIEW_TYPE_FIRST_LOADING = 8; + private static final int VIEW_TYPE_FIRST_LOADING_FAILED = 9; + private static final int VIEW_TYPE_NO_COMMENT_PLACEHOLDER = 10; + private static final int VIEW_TYPE_COMMENT = 11; + private static final int VIEW_TYPE_COMMENT_FULLY_COLLAPSED = 12; + private static final int VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS = 13; + private static final int VIEW_TYPE_IS_LOADING_MORE_COMMENTS = 14; + private static final int VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED = 15; + private static final int VIEW_TYPE_VIEW_ALL_COMMENTS = 16; + + private AppCompatActivity mActivity; + private Retrofit mRetrofit; + private Retrofit mOauthRetrofit; + private Retrofit mGfycatRetrofit; + private Retrofit mRedgifsRetrofit; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private RequestManager mGlide; + private Markwon mPostDetailMarkwon; + private Markwon mCommentMarkwon; + private final MarkwonAdapter mMarkwonAdapter; + private int mImageViewWidth; + private String mAccessToken; + private String mAccountName; + private Post mPost; + private ArrayList mVisibleComments; + private String mSubredditNamePrefixed; + private Locale mLocale; + private String mSingleCommentId; + private boolean mIsSingleCommentThreadMode; + private boolean mNeedBlurNsfw; + private boolean mNeedBlurSpoiler; + private boolean mVoteButtonsOnTheRight; + private boolean mShowElapsedTime; + private String mTimeFormatPattern; + private boolean mExpandChildren; + private boolean mCommentToolbarHidden; + private boolean mCommentToolbarHideOnClick; + private boolean mSwapTapAndLong; + private boolean mShowCommentDivider; + private boolean mShowAbsoluteNumberOfVotes; + private boolean mAutoplay = false; + private boolean mAutoplayNsfwVideos; + private boolean mMuteAutoplayingVideos; + private boolean mFullyCollapseComment; + private double mStartAutoplayVisibleAreaOffset; + private boolean mMuteNSFWVideo; + private boolean mAutomaticallyTryRedgifs; + private boolean mDataSavingMode; + private boolean mDisableImagePreview; + private CommentRecyclerViewAdapterCallback mCommentRecyclerViewAdapterCallback; + private boolean isInitiallyLoading; + private boolean isInitiallyLoadingFailed; + private boolean mHasMoreComments; + private boolean loadMoreCommentsFailed; + + private int mColorPrimaryLightTheme; + private int mColorAccent; + private int mCircularProgressBarBackgroundColor; + private int mCardViewColor; + private int mSecondaryTextColor; + private int mPostTitleColor; + private int mPrimaryTextColor; + private int mCommentTextColor; + private int mCommentBackgroundColor; + private int mPostTypeBackgroundColor; + private int mPostTypeTextColor; + private int mDividerColor; + private int mSubredditColor; + private int mUsernameColor; + private int mSubmitterColor; + private int mModeratorColor; + private int mAuthorFlairTextColor; + private int mSpoilerBackgroundColor; + private int mSpoilerTextColor; + private int mFlairBackgroundColor; + private int mFlairTextColor; + private int mNSFWBackgroundColor; + private int mNSFWTextColor; + private int mArchivedTintColor; + private int mLockedTintColor; + private int mCrosspostTintColor; + private int mNoPreviewPostTypeBackgroundColor; + private int mNoPreviewPostTypeIconTint; + private int mUpvotedColor; + private int mDownvotedColor; + private int mCommentVerticalBarColor1; + private int mCommentVerticalBarColor2; + private int mCommentVerticalBarColor3; + private int mCommentVerticalBarColor4; + private int mCommentVerticalBarColor5; + private int mCommentVerticalBarColor6; + private int mCommentVerticalBarColor7; + private int mSingleCommentThreadBackgroundColor; + private int mVoteAndReplyUnavailableVoteButtonColor; + private int mButtonTextColor; + private int mPostIconAndInfoColor; + private int mCommentIconAndInfoColor; + private int mFullyCollapsedCommentBackgroundColor; + private int mAwardedCommentBackgroundColor; + + private Drawable mCommentIcon; + private float mScale; + private ShareLinkBottomSheetFragment mShareLinkBottomSheetFragment; + private CopyTextBottomSheetFragment mCopyTextBottomSheetFragment; + private ExoCreator mExoCreator; + + public CommentAndPostRecyclerViewAdapter(AppCompatActivity activity, CustomThemeWrapper customThemeWrapper, + Retrofit retrofit, Retrofit oauthRetrofit, Retrofit gfycatRetrofit, + Retrofit redgifsRetrofit, + RedditDataRoomDatabase redditDataRoomDatabase, RequestManager glide, + int imageViewWidth, String accessToken, String accountName, + Post post, Locale locale, String singleCommentId, + boolean isSingleCommentThreadMode, + SharedPreferences sharedPreferences, + SharedPreferences nsfwAndSpoilerSharedPreferences, ExoCreator exoCreator, + CommentRecyclerViewAdapterCallback commentRecyclerViewAdapterCallback) { + mActivity = activity; + mRetrofit = retrofit; + mOauthRetrofit = oauthRetrofit; + mGfycatRetrofit = gfycatRetrofit; + mRedgifsRetrofit = redgifsRetrofit; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mGlide = glide; + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + mCommentTextColor = customThemeWrapper.getCommentColor(); + int commentSpoilerBackgroundColor = mCommentTextColor | 0xFF000000; + int markdownColor = customThemeWrapper.getPostContentColor(); + int postSpoilerBackgroundColor = markdownColor | 0xFF000000; + int linkColor = customThemeWrapper.getLinkColor(); + mPostDetailMarkwon = Markwon.builder(mActivity) + .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + StringBuilder markdownStringBuilder = new StringBuilder(markdown); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + while (matcher.find()) { + markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); + } + return super.processMarkdown(markdownStringBuilder.toString()); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + textView.setHighlightColor(Color.TRANSPARENT); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + ClickableSpan clickableSpan = new ClickableSpan() { + private boolean isShowing = false; + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + ds.setColor(markdownColor); + } else { + ds.bgColor = postSpoilerBackgroundColor; + ds.setColor(markdownColor); + } + ds.setUnderlineText(false); + } + + @Override + public void onClick(@NonNull View view) { + isShowing = !isShowing; + view.invalidate(); + } + }; + markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcher.end() - 4; + } + if (find) { + textView.setText(markdownStringBuilder); + } + } + + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + textView.setTextColor(markdownColor); + textView.setOnLongClickListener(view -> { + Bundle bundle = new Bundle(); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, mPost.getSelfTextPlain()); + bundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, mPost.getSelfText()); + mCopyTextBottomSheetFragment.setArguments(bundle); + mCopyTextBottomSheetFragment.show(mActivity.getSupportFragmentManager(), mCopyTextBottomSheetFragment.getTag()); + return true; + }); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .usePlugin(TableEntryPlugin.create(mActivity)) + .build(); + mCommentMarkwon = Markwon.builder(mActivity) + .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + StringBuilder markdownStringBuilder = new StringBuilder(markdown); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + while (matcher.find()) { + markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); + } + return super.processMarkdown(markdownStringBuilder.toString()); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + ClickableSpan clickableSpan = new ClickableSpan() { + private boolean isShowing = false; + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + ds.setColor(mCommentTextColor); + } else { + ds.bgColor = commentSpoilerBackgroundColor; + ds.setColor(mCommentTextColor); + } + ds.setUnderlineText(false); + } + + @Override + public void onClick(@NonNull View view) { + isShowing = !isShowing; + view.invalidate(); + } + }; + markdownStringBuilder.setSpan(clickableSpan, matcher.start(), matcher.end() - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcher.end() - 4; + } + if (find) { + textView.setText(markdownStringBuilder); + } + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(linkColor); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .build(); + mMarkwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) + .include(TableBlock.class, TableEntry.create(builder -> builder + .tableLayout(R.layout.adapter_table_block, R.id.table_layout) + .textLayoutIsRoot(R.layout.view_table_entry_cell))) + .build(); + mImageViewWidth = imageViewWidth; + mAccessToken = accessToken; + mAccountName = accountName; + mPost = post; + mVisibleComments = new ArrayList<>(); + mSubredditNamePrefixed = post.getSubredditNamePrefixed(); + mLocale = locale; + mSingleCommentId = singleCommentId; + mIsSingleCommentThreadMode = isSingleCommentThreadMode; + + mNeedBlurNsfw = nsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, true); + mNeedBlurSpoiler = nsfwAndSpoilerSharedPreferences.getBoolean((mAccountName == null ? "" : mAccountName) + 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); + mExpandChildren = !sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_TOP_LEVEL_COMMENTS_FIRST, false); + mCommentToolbarHidden = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDDEN, false); + mCommentToolbarHideOnClick = sharedPreferences.getBoolean(SharedPreferencesUtils.COMMENT_TOOLBAR_HIDE_ON_CLICK, true); + mSwapTapAndLong = sharedPreferences.getBoolean(SharedPreferencesUtils.SWAP_TAP_AND_LONG_COMMENTS, false); + mShowCommentDivider = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_COMMENT_DIVIDER, false); + 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); + mFullyCollapseComment = sharedPreferences.getBoolean(SharedPreferencesUtils.FULLY_COLLAPSE_COMMENT, 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); + + 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); + + mCommentRecyclerViewAdapterCallback = commentRecyclerViewAdapterCallback; + isInitiallyLoading = true; + isInitiallyLoadingFailed = false; + mHasMoreComments = false; + loadMoreCommentsFailed = false; + mScale = resources.getDisplayMetrics().density; + + mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); + mColorAccent = customThemeWrapper.getColorAccent(); + mCircularProgressBarBackgroundColor = customThemeWrapper.getCircularProgressBarBackground(); + mCardViewColor = customThemeWrapper.getCardViewBackgroundColor(); + mPostTitleColor = customThemeWrapper.getPostTitleColor(); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mDividerColor = customThemeWrapper.getDividerColor(); + mCommentBackgroundColor = customThemeWrapper.getCommentBackgroundColor(); + mPostTypeBackgroundColor = customThemeWrapper.getPostTypeBackgroundColor(); + mPostTypeTextColor = customThemeWrapper.getPostTypeTextColor(); + mSubmitterColor = customThemeWrapper.getSubmitter(); + mModeratorColor = customThemeWrapper.getModerator(); + mAuthorFlairTextColor = customThemeWrapper.getAuthorFlairTextColor(); + mSpoilerBackgroundColor = customThemeWrapper.getSpoilerBackgroundColor(); + mSpoilerTextColor = customThemeWrapper.getSpoilerTextColor(); + mNSFWBackgroundColor = customThemeWrapper.getNsfwBackgroundColor(); + mNSFWTextColor = customThemeWrapper.getNsfwTextColor(); + mArchivedTintColor = customThemeWrapper.getArchivedIconTint(); + mLockedTintColor = customThemeWrapper.getLockedIconTint(); + mCrosspostTintColor = customThemeWrapper.getCrosspostIconTint(); + mNoPreviewPostTypeBackgroundColor = customThemeWrapper.getNoPreviewPostTypeBackgroundColor(); + mNoPreviewPostTypeIconTint = customThemeWrapper.getNoPreviewPostTypeIconTint(); + mFlairBackgroundColor = customThemeWrapper.getFlairBackgroundColor(); + mFlairTextColor = customThemeWrapper.getFlairTextColor(); + mSubredditColor = customThemeWrapper.getSubreddit(); + mUsernameColor = customThemeWrapper.getUsername(); + mUpvotedColor = customThemeWrapper.getUpvoted(); + mDownvotedColor = customThemeWrapper.getDownvoted(); + mCommentVerticalBarColor1 = customThemeWrapper.getCommentVerticalBarColor1(); + mCommentVerticalBarColor2 = customThemeWrapper.getCommentVerticalBarColor2(); + mCommentVerticalBarColor3 = customThemeWrapper.getCommentVerticalBarColor3(); + mCommentVerticalBarColor4 = customThemeWrapper.getCommentVerticalBarColor4(); + mCommentVerticalBarColor5 = customThemeWrapper.getCommentVerticalBarColor5(); + mCommentVerticalBarColor6 = customThemeWrapper.getCommentVerticalBarColor6(); + mCommentVerticalBarColor7 = customThemeWrapper.getCommentVerticalBarColor7(); + mSingleCommentThreadBackgroundColor = customThemeWrapper.getSingleCommentThreadBackgroundColor(); + mVoteAndReplyUnavailableVoteButtonColor = customThemeWrapper.getVoteAndReplyUnavailableButtonColor(); + mButtonTextColor = customThemeWrapper.getButtonTextColor(); + mPostIconAndInfoColor = customThemeWrapper.getPostIconAndInfoColor(); + mCommentIconAndInfoColor = customThemeWrapper.getCommentIconAndInfoColor(); + mFullyCollapsedCommentBackgroundColor = customThemeWrapper.getFullyCollapsedCommentBackgroundColor(); + mAwardedCommentBackgroundColor = customThemeWrapper.getAwardedCommentBackgroundColor(); + + mCommentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); + if (mCommentIcon != null) { + DrawableCompat.setTint(mCommentIcon, mPostIconAndInfoColor); + } + + mShareLinkBottomSheetFragment = new ShareLinkBottomSheetFragment(); + mCopyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); + mExoCreator = exoCreator; + } + + @Override + public int getItemViewType(int position) { + if (position == 0) { + switch (mPost.getPostType()) { + case Post.VIDEO_TYPE: + if (mAutoplay) { + if (!mAutoplayNsfwVideos && mPost.isNSFW()) { + return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; + } + return VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY; + } else { + return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; + } + case Post.GIF_TYPE: + if (mAutoplay) { + if (!mAutoplayNsfwVideos && mPost.isNSFW()) { + return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; + } + return VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY; + } else { + return VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW; + } + case Post.IMAGE_TYPE: + return VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY; + case Post.LINK_TYPE: + return VIEW_TYPE_POST_DETAIL_LINK; + case Post.NO_PREVIEW_LINK_TYPE: + return VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK; + case Post.GALLERY_TYPE: + return VIEW_TYPE_POST_DETAIL_GALLERY; + default: + return VIEW_TYPE_POST_DETAIL_TEXT_TYPE; + } + } + + if (mVisibleComments.size() == 0) { + if (position == 1) { + if (isInitiallyLoading) { + return VIEW_TYPE_FIRST_LOADING; + } else if (isInitiallyLoadingFailed) { + return VIEW_TYPE_FIRST_LOADING_FAILED; + } else { + return VIEW_TYPE_NO_COMMENT_PLACEHOLDER; + } + } + } + + if (mIsSingleCommentThreadMode) { + if (position == 1) { + return VIEW_TYPE_VIEW_ALL_COMMENTS; + } + + if (position == mVisibleComments.size() + 2) { + if (mHasMoreComments) { + return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; + } else { + return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; + } + } + + Comment comment = mVisibleComments.get(position - 2); + if (!comment.isPlaceHolder()) { + if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { + return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; + } + return VIEW_TYPE_COMMENT; + } else { + return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; + } + } else { + if (position == mVisibleComments.size() + 1) { + if (mHasMoreComments) { + return VIEW_TYPE_IS_LOADING_MORE_COMMENTS; + } else { + return VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED; + } + } + + Comment comment = mVisibleComments.get(position - 1); + if (!comment.isPlaceHolder()) { + if (mFullyCollapseComment && !comment.isExpanded() && comment.hasExpandedBefore()) { + return VIEW_TYPE_COMMENT_FULLY_COLLAPSED; + } + return VIEW_TYPE_COMMENT; + } else { + return VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS; + } + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_POST_DETAIL_VIDEO_AUTOPLAY: + if (mDataSavingMode) { + if (mDisableImagePreview) { + return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); + } + return new PostDetailVideoAndGifPreviewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_video_and_gif_preview, parent, false)); + } + return new PostDetailVideoAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_video_autoplay, parent, false)); + case VIEW_TYPE_POST_DETAIL_VIDEO_AND_GIF_PREVIEW: + if (mDataSavingMode && mDisableImagePreview) { + return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); + } + return new PostDetailVideoAndGifPreviewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_video_and_gif_preview, parent, false)); + case VIEW_TYPE_POST_DETAIL_IMAGE_AND_GIF_AUTOPLAY: + if (mDataSavingMode && mDisableImagePreview) { + return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); + } + return new PostDetailImageAndGifAutoplayViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_image_and_gif_autoplay, parent, false)); + case VIEW_TYPE_POST_DETAIL_LINK: + if (mDataSavingMode && mDisableImagePreview) { + return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); + } + return new PostDetailLinkViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_link, parent, false)); + case VIEW_TYPE_POST_DETAIL_NO_PREVIEW_LINK: + return new PostDetailNoPreviewViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_no_preview, parent, false)); + case VIEW_TYPE_POST_DETAIL_GALLERY: + return new PostDetailGalleryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_gallery, parent, false)); + case VIEW_TYPE_POST_DETAIL_TEXT_TYPE: + return new PostDetailTextViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_detail_text, parent, false)); + case VIEW_TYPE_FIRST_LOADING: + return new LoadCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments, parent, false)); + case VIEW_TYPE_FIRST_LOADING_FAILED: + return new LoadCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_comments_failed_placeholder, parent, false)); + case VIEW_TYPE_NO_COMMENT_PLACEHOLDER: + return new NoCommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_no_comment_placeholder, parent, false)); + case VIEW_TYPE_COMMENT: + return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); + case VIEW_TYPE_COMMENT_FULLY_COLLAPSED: + return new CommentFullyCollapsedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_fully_collapsed, parent, false)); + case VIEW_TYPE_LOAD_MORE_CHILD_COMMENTS: + return new LoadMoreChildCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_load_more_comments_placeholder, parent, false)); + case VIEW_TYPE_IS_LOADING_MORE_COMMENTS: + return new IsLoadingMoreCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_loading, parent, false)); + case VIEW_TYPE_LOAD_MORE_COMMENTS_FAILED: + return new LoadMoreCommentsFailedViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment_footer_error, parent, false)); + default: + return new ViewAllCommentsViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_view_all_comments, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof PostDetailBaseViewHolder) { + ((PostDetailBaseViewHolder) holder).mTitleTextView.setText(mPost.getTitle()); + if (mPost.getSubredditNamePrefixed().startsWith("u/")) { + if (mPost.getAuthorIconUrl() == null) { + String authorName = mPost.getAuthor().equals("[deleted]") ? mPost.getSubredditNamePrefixed().substring(2) : mPost.getAuthor(); + new LoadUserDataAsyncTask(mRedditDataRoomDatabase.userDao(), authorName, mOauthRetrofit, iconImageUrl -> { + if (mActivity != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + mPost.setAuthorIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!mPost.getAuthorIconUrl().equals("")) { + mGlide.load(mPost.getAuthorIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } + } else { + if (mPost.getSubredditIconUrl() == null) { + new LoadSubredditIconAsyncTask( + mRedditDataRoomDatabase, mPost.getSubredditNamePrefixed().substring(2), + mRetrofit, iconImageUrl -> { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } + + mPost.setSubredditIconUrl(iconImageUrl); + }).execute(); + } else if (!mPost.getSubredditIconUrl().equals("")) { + mGlide.load(mPost.getSubredditIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostDetailBaseViewHolder) holder).mIconGifImageView); + } + } + + if (mPost.getAuthorFlairHTML() != null && !mPost.getAuthorFlairHTML().equals("")) { + ((PostDetailBaseViewHolder) holder).mAuthorFlairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mAuthorFlairTextView, mPost.getAuthorFlairHTML(), true); + } else if (mPost.getAuthorFlair() != null && !mPost.getAuthorFlair().equals("")) { + ((PostDetailBaseViewHolder) holder).mAuthorFlairTextView.setVisibility(View.VISIBLE); + ((PostDetailBaseViewHolder) holder).mAuthorFlairTextView.setText(mPost.getAuthorFlair()); + } + + switch (mPost.getVoteType()) { + case 1: + //Upvote + ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mUpvotedColor, PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mUpvotedColor); + break; + case -1: + //Downvote + ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mDownvotedColor, PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mDownvotedColor); + break; + case 0: + ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mPostIconAndInfoColor); + } + + if (mPost.isArchived()) { + ((PostDetailBaseViewHolder) holder).mUpvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mDownvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (mPost.isCrosspost()) { + ((PostDetailBaseViewHolder) holder).mCrosspostImageView.setVisibility(View.VISIBLE); + } + + ((PostDetailBaseViewHolder) holder).mSubredditTextView.setText(mPost.getSubredditNamePrefixed()); + ((PostDetailBaseViewHolder) holder).mUserTextView.setText(mPost.getAuthorNamePrefixed()); + + if (mShowElapsedTime) { + ((PostDetailBaseViewHolder) holder).mPostTimeTextView.setText( + Utils.getElapsedTime(mActivity, mPost.getPostTimeMillis())); + } else { + ((PostDetailBaseViewHolder) holder).mPostTimeTextView.setText(Utils.getFormattedTime(mLocale, mPost.getPostTimeMillis(), mTimeFormatPattern)); + } + + if (mPost.isArchived()) { + ((PostDetailBaseViewHolder) holder).mArchivedImageView.setVisibility(View.VISIBLE); + } + + if (mPost.isLocked()) { + ((PostDetailBaseViewHolder) holder).mLockedImageView.setVisibility(View.VISIBLE); + } + + if (mPost.isSpoiler()) { + ((PostDetailBaseViewHolder) holder).mSpoilerTextView.setVisibility(View.VISIBLE); + } + + if (mPost.getFlair() != null && !mPost.getFlair().equals("")) { + ((PostDetailBaseViewHolder) holder).mFlairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mFlairTextView, mPost.getFlair(), false); + } + + if (mPost.getAwards() != null && !mPost.getAwards().equals("")) { + ((PostDetailBaseViewHolder) holder).mAwardsTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostDetailBaseViewHolder) holder).mAwardsTextView, mPost.getAwards(), true); + } + + if (mPost.isNSFW()) { + ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.VISIBLE); + } else { + ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.GONE); + } + + ((PostDetailBaseViewHolder) holder).mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, mPost.getScore() + mPost.getVoteType())); + + ((PostDetailBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(mPost.getNComments())); + + if (mPost.isSaved()) { + ((PostDetailBaseViewHolder) holder).mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((PostDetailBaseViewHolder) holder).mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + + if (holder instanceof PostDetailVideoAutoplayViewHolder) { + ((PostDetailVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); + Post.Preview preview = getSuitablePreview(mPost.getPreviews()); + if (preview != null) { + ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); + if (mImageViewWidth > preview.getPreviewWidth()) { + mGlide.load(preview.getPreviewUrl()).override(Target.SIZE_ORIGINAL).into(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); + } else { + mGlide.load(preview.getPreviewUrl()).into(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); + } + } else { + ((PostDetailVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); + } + ((PostDetailVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (mPost.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + + if (mPost.isGfycat() || mPost.isRedgifs() && !mPost.isLoadGfyOrRedgifsVideoSuccess()) { + ((PostDetailVideoAutoplayViewHolder) holder).mTypeTextView.setText("GFYCAT"); + ((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks = new FetchGfycatOrRedgifsVideoLinks(new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { + @Override + public void success(String webm, String mp4) { + mPost.setVideoDownloadUrl(mp4); + mPost.setVideoUrl(webm); + mPost.setLoadGfyOrRedgifsVideoSuccess(true); + ((PostDetailVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(mPost.getVideoUrl())); + } + + @Override + public void failed(int errorCode) { + ((PostDetailVideoAutoplayViewHolder) holder).mErrorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + }); + ((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks + .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mGfycatRetrofit, mRedgifsRetrofit, + mPost.getGfycatId(), mPost.isGfycat(), mAutomaticallyTryRedgifs); + } else { + ((PostDetailVideoAutoplayViewHolder) holder).mTypeTextView.setText("VIDEO"); + ((PostDetailVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(mPost.getVideoUrl())); + } + } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { + if (mPost.getPostType() == Post.GIF_TYPE) { + ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.gif)); + } else { + ((PostDetailVideoAndGifPreviewHolder) holder).mTypeTextView.setText(mActivity.getString(R.string.video)); + } + Post.Preview preview = getSuitablePreview(mPost.getPreviews()); + if (preview != null) { + ((PostDetailVideoAndGifPreviewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / (float) preview.getPreviewWidth()); + loadImage((PostDetailVideoAndGifPreviewHolder) holder, preview); + } + } else if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { + if (mPost.getPostType() == Post.IMAGE_TYPE) { + ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.image); + } else { + ((PostDetailImageAndGifAutoplayViewHolder) holder).mTypeTextView.setText(R.string.gif); + } + + Post.Preview preview = getSuitablePreview(mPost.getPreviews()); + if (preview != null) { + if (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0) { + ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.getLayoutParams().height = (int) (400 * mScale); + } else { + ((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / (float) preview.getPreviewWidth()); + } + loadImage((PostDetailImageAndGifAutoplayViewHolder) holder, preview); + } + } else if (holder instanceof PostDetailLinkViewHolder) { + String domain = Uri.parse(mPost.getUrl()).getHost(); + ((PostDetailLinkViewHolder) holder).mLinkTextView.setText(domain); + Post.Preview preview = getSuitablePreview(mPost.getPreviews()); + if (preview != null) { + ((PostDetailLinkViewHolder) holder).mImageView.setRatio((float) preview.getPreviewHeight() / (float) preview.getPreviewWidth()); + loadImage((PostDetailLinkViewHolder) holder, preview); + } + + } else if (holder instanceof PostDetailNoPreviewViewHolder) { + if (mPost.getPostType() == Post.LINK_TYPE || mPost.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + String noPreviewLinkDomain = Uri.parse(mPost.getUrl()).getHost(); + ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setVisibility(View.VISIBLE); + ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setText(noPreviewLinkDomain); + } else { + ((PostDetailNoPreviewViewHolder) holder).mLinkTextView.setVisibility(View.GONE); + switch (mPost.getPostType()) { + case Post.VIDEO_TYPE: + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.video); + ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_outline_video_24dp); + break; + case Post.IMAGE_TYPE: + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.image); + ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_image_24dp); + break; + case Post.GIF_TYPE: + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gif); + ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_image_24dp); + break; + case Post.LINK_TYPE: + case Post.NO_PREVIEW_LINK_TYPE: + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.link); + break; + case Post.GALLERY_TYPE: + ((PostDetailNoPreviewViewHolder) holder).mTypeTextView.setText(R.string.gallery); + ((PostDetailNoPreviewViewHolder) holder).mNoPreviewPostTypeImageView.setImageResource(R.drawable.ic_gallery_24dp); + break; + } + } + + if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) { + ((PostDetailNoPreviewViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); + LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { + @Override + public void onScrolledLeft() { + ((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack(); + } + + @Override + public void onScrolledRight() { + ((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack(); + } + }); + ((PostDetailNoPreviewViewHolder) holder).mContentMarkdownView.setLayoutManager(linearLayoutManager); + ((PostDetailNoPreviewViewHolder) holder).mContentMarkdownView.setAdapter(mMarkwonAdapter); + mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, mPost.getSelfText()); + mMarkwonAdapter.notifyDataSetChanged(); + } + } else if (holder instanceof PostDetailGalleryViewHolder) { + Post.Preview preview = getSuitablePreview(mPost.getPreviews()); + if (preview != null) { + ((PostDetailGalleryViewHolder) holder).mRelativeLayout.setVisibility(View.VISIBLE); + ((PostDetailGalleryViewHolder) holder).mImageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + + loadImage((PostDetailGalleryViewHolder) holder, preview); + } else { + ((PostDetailGalleryViewHolder) holder).mNoPreviewPostTypeImageView.setVisibility(View.VISIBLE); + } + } else if (holder instanceof PostDetailTextViewHolder) { + if (mPost.getSelfText() != null && !mPost.getSelfText().equals("")) { + ((PostDetailTextViewHolder) holder).mContentMarkdownView.setVisibility(View.VISIBLE); + LinearLayoutManager linearLayoutManager = new MarkwonLinearLayoutManager(mActivity, new MarkwonLinearLayoutManager.HorizontalScrollViewScrolledListener() { + @Override + public void onScrolledLeft() { + ((ViewPostDetailActivity) mActivity).lockSwipeRightToGoBack(); + } + + @Override + public void onScrolledRight() { + ((ViewPostDetailActivity) mActivity).unlockSwipeRightToGoBack(); + } + }); + ((PostDetailTextViewHolder) holder).mContentMarkdownView.setLayoutManager(linearLayoutManager); + ((PostDetailTextViewHolder) holder).mContentMarkdownView.setAdapter(mMarkwonAdapter); + mMarkwonAdapter.setMarkdown(mPostDetailMarkwon, mPost.getSelfText()); + mMarkwonAdapter.notifyDataSetChanged(); + } + } + } else if (holder instanceof CommentViewHolder) { + Comment comment; + if (mIsSingleCommentThreadMode) { + comment = mVisibleComments.get(holder.getAdapterPosition() - 2); + } else { + comment = mVisibleComments.get(holder.getAdapterPosition() - 1); + } + + if (mIsSingleCommentThreadMode && comment.getId().equals(mSingleCommentId)) { + ((CommentViewHolder) holder).itemView.setBackgroundColor(mSingleCommentThreadBackgroundColor); + } else if (comment.getAwards() != null && !comment.getAwards().equals("")) { + ((CommentViewHolder) holder).itemView.setBackgroundColor(mAwardedCommentBackgroundColor); + } + + String authorPrefixed = "u/" + comment.getAuthor(); + ((CommentViewHolder) holder).authorTextView.setText(authorPrefixed); + + if (comment.getAuthorFlairHTML() != null && !comment.getAuthorFlairHTML().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).authorFlairTextView, comment.getAuthorFlairHTML(), true); + } else if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + ((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair()); + } + + if (comment.isSubmitter()) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mSubmitterColor); + Drawable submitterDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_mic_14dp, mSubmitterColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + submitterDrawable, null, null, null); + } else if (comment.isModerator()) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mModeratorColor); + Drawable moderatorDrawable = Utils.getTintedDrawable(mActivity, R.drawable.ic_verified_user_14dp, mModeratorColor); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds( + moderatorDrawable, null, null, null); + } + + if (mShowElapsedTime) { + ((CommentViewHolder) holder).commentTimeTextView.setText( + Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); + } else { + ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); + } + + if (mCommentToolbarHidden) { + ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = 0; + ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.VISIBLE); + } else { + ((CommentViewHolder) holder).bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; + ((CommentViewHolder) holder).topScoreTextView.setVisibility(View.GONE); + } + + if (comment.getAwards() != null && !comment.getAwards().equals("")) { + ((CommentViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).awardsTextView, comment.getAwards(), true); + } + + mCommentMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentMarkdown()); + ((CommentViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + ((CommentViewHolder) holder).topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + + ((CommentViewHolder) holder).itemView.setPadding(comment.getDepth() * 8, 0, 0, 0); + if (comment.getDepth() > 0) { + switch (comment.getDepth() % 7) { + case 0: + ((CommentViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor7); + break; + case 1: + ((CommentViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor1); + break; + case 2: + ((CommentViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor2); + break; + case 3: + ((CommentViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor3); + break; + case 4: + ((CommentViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor4); + break; + case 5: + ((CommentViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor5); + break; + case 6: + ((CommentViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor6); + break; + } + ViewGroup.LayoutParams params = ((CommentViewHolder) holder).verticalBlock.getLayoutParams(); + params.width = 8; + ((CommentViewHolder) holder).verticalBlock.setLayoutParams(params); + } + + if (comment.hasReply()) { + if (comment.isExpanded()) { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); + } else { + ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); + } + ((CommentViewHolder) holder).expandButton.setVisibility(View.VISIBLE); + } + + switch (comment.getVoteType()) { + case Comment.VOTE_TYPE_UPVOTE: + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + break; + case Comment.VOTE_TYPE_DOWNVOTE: + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + break; + } + + if (mPost.isArchived()) { + ((CommentViewHolder) holder).replyButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (mPost.isLocked()) { + ((CommentViewHolder) holder).replyButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, + android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (comment.isSaved()) { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + } else if (holder instanceof CommentFullyCollapsedViewHolder) { + Comment comment; + if (mIsSingleCommentThreadMode) { + comment = mVisibleComments.get(holder.getAdapterPosition() - 2); + } else { + comment = mVisibleComments.get(holder.getAdapterPosition() - 1); + } + + String authorWithPrefix = "u/" + comment.getAuthor(); + ((CommentFullyCollapsedViewHolder) holder).usernameTextView.setText(authorWithPrefix); + if (mShowElapsedTime) { + ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getElapsedTime(mActivity, comment.getCommentTimeMillis())); + } else { + ((CommentFullyCollapsedViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); + } + ((CommentFullyCollapsedViewHolder) holder).scoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, comment.getScore() + comment.getVoteType()))); + + ((CommentFullyCollapsedViewHolder) holder).itemView.setPadding(comment.getDepth() * 8, 0, 0, 0); + if (comment.getDepth() > 0) { + switch (comment.getDepth() % 7) { + case 0: + ((CommentFullyCollapsedViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor7); + break; + case 1: + ((CommentFullyCollapsedViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor1); + break; + case 2: + ((CommentFullyCollapsedViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor2); + break; + case 3: + ((CommentFullyCollapsedViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor3); + break; + case 4: + ((CommentFullyCollapsedViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor4); + break; + case 5: + ((CommentFullyCollapsedViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor5); + break; + case 6: + ((CommentFullyCollapsedViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor6); + break; + } + ViewGroup.LayoutParams params = ((CommentFullyCollapsedViewHolder) holder).verticalBlock.getLayoutParams(); + params.width = 8; + ((CommentFullyCollapsedViewHolder) holder).verticalBlock.setLayoutParams(params); + } + } else if (holder instanceof LoadMoreChildCommentsViewHolder) { + Comment placeholder; + placeholder = mIsSingleCommentThreadMode ? mVisibleComments.get(holder.getAdapterPosition() - 2) + : mVisibleComments.get(holder.getAdapterPosition() - 1); + + ((LoadMoreChildCommentsViewHolder) holder).itemView.setPadding(placeholder.getDepth() * 8, 0, 0, 0); + if (placeholder.getDepth() > 0) { + switch (placeholder.getDepth() % 7) { + case 0: + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor7); + break; + case 1: + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor1); + break; + case 2: + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor2); + break; + case 3: + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor3); + break; + case 4: + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor4); + break; + case 5: + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor5); + break; + case 6: + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock + .setBackgroundColor(mCommentVerticalBarColor6); + break; + } + + ViewGroup.LayoutParams params = ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.getLayoutParams(); + params.width = 8; + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.setLayoutParams(params); + } + + if (placeholder.isLoadingMoreChildren()) { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); + } else if (placeholder.isLoadMoreChildrenFailed()) { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } else { + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); + } + + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setOnClickListener(view -> { + int commentPosition = mIsSingleCommentThreadMode ? holder.getAdapterPosition() - 2 : holder.getAdapterPosition() - 1; + int parentPosition = getParentPosition(commentPosition); + if (parentPosition >= 0) { + Comment parentComment = mVisibleComments.get(parentPosition); + + mVisibleComments.get(commentPosition).setLoadingMoreChildren(true); + mVisibleComments.get(commentPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.loading); + + Retrofit retrofit = mAccessToken == null ? mRetrofit : mOauthRetrofit; + FetchComment.fetchMoreComment(retrofit, mAccessToken, parentComment.getMoreChildrenFullnames(), + parentComment.getMoreChildrenStartingIndex(), parentComment.getDepth() + 1, + mExpandChildren, mLocale, + new FetchComment.FetchMoreCommentListener() { + @Override + public void onFetchMoreCommentSuccess(ArrayList expandedComments, + int childrenStartingIndex) { + if (mVisibleComments.size() > parentPosition + && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { + if (mVisibleComments.get(parentPosition).isExpanded()) { + if (mVisibleComments.get(parentPosition).getChildren().size() > childrenStartingIndex) { + mVisibleComments.get(parentPosition).setMoreChildrenStartingIndex(childrenStartingIndex); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadMoreChildrenFailed(false); + + int placeholderPosition = commentPosition; + if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } + } else { + mVisibleComments.get(parentPosition).getChildren() + .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); + mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); + + int placeholderPosition = commentPosition; + if (mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; + } + } + } + + mVisibleComments.remove(placeholderPosition); + if (mIsSingleCommentThreadMode) { + notifyItemRemoved(placeholderPosition + 2); + } else { + notifyItemRemoved(placeholderPosition + 1); + } + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } + } + } else { + if (mVisibleComments.get(parentPosition).hasReply() && mVisibleComments.get(parentPosition).getChildren().size() <= childrenStartingIndex) { + mVisibleComments.get(parentPosition).getChildren() + .remove(mVisibleComments.get(parentPosition).getChildren().size() - 1); + mVisibleComments.get(parentPosition).removeMoreChildrenFullnames(); + } + } + + mVisibleComments.get(parentPosition).addChildren(expandedComments); + } else { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + if (mVisibleComments.get(i).isExpanded()) { + int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); + + if (!mVisibleComments.get(i).getFullName() + .equals(mVisibleComments.get(placeholderPosition).getFullName())) { + for (int j = i + 1; j < mVisibleComments.size(); j++) { + if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { + placeholderPosition = j; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(false); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments); + + mVisibleComments.addAll(placeholderPosition, expandedComments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(placeholderPosition + 2, expandedComments.size()); + } else { + notifyItemRangeInserted(placeholderPosition + 1, expandedComments.size()); + } + } + + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1) + .setLoadMoreChildrenFailed(false); + mVisibleComments.get(i).addChildren(expandedComments); + + break; + } + } + } + } + + @Override + public void onFetchMoreCommentFailed() { + if (parentPosition < mVisibleComments.size() + && parentComment.getFullName().equals(mVisibleComments.get(parentPosition).getFullName())) { + if (mVisibleComments.get(parentPosition).isExpanded()) { + int commentPosition = mIsSingleCommentThreadMode ? holder.getAdapterPosition() - 2 : holder.getAdapterPosition() - 1; + int placeholderPosition = commentPosition; + if (commentPosition >= mVisibleComments.size() || commentPosition < 0 || !mVisibleComments.get(commentPosition).getFullName().equals(parentComment.getFullName())) { + for (int i = parentPosition + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + placeholderPosition = i; + break; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } + + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadingMoreChildren(false); + mVisibleComments.get(parentPosition).getChildren().get(mVisibleComments.get(parentPosition).getChildren().size() - 1) + .setLoadMoreChildrenFailed(true); + } else { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getFullName().equals(parentComment.getFullName())) { + if (mVisibleComments.get(i).isExpanded()) { + int placeholderPosition = i + mVisibleComments.get(i).getChildren().size(); + if (!mVisibleComments.get(placeholderPosition).getFullName().equals(mVisibleComments.get(i).getFullName())) { + for (int j = i + 1; j < mVisibleComments.size(); j++) { + if (mVisibleComments.get(j).getFullName().equals(mVisibleComments.get(i).getFullName())) { + placeholderPosition = j; + break; + } + } + } + + mVisibleComments.get(placeholderPosition).setLoadingMoreChildren(false); + mVisibleComments.get(placeholderPosition).setLoadMoreChildrenFailed(true); + ((LoadMoreChildCommentsViewHolder) holder).placeholderTextView.setText(R.string.comment_load_more_comments_failed); + } + + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadingMoreChildren(false); + mVisibleComments.get(i).getChildren().get(mVisibleComments.get(i).getChildren().size() - 1).setLoadMoreChildrenFailed(true); + + break; + } + } + } + } + }); + } + }); + } + } + + @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() >= 65 * 1000 * 1000) { + for (int i = previews.size() - 1; i >= 1; i--) { + preview = previews.get(i); + if (mImageViewWidth >= preview.getPreviewWidth()) { + if (preview.getPreviewWidth() * preview.getPreviewHeight() <= 75 * 1000 * 1000) { + return preview; + } + } else { + int height = mImageViewWidth / preview.getPreviewWidth() * preview.getPreviewHeight(); + if (mImageViewWidth * height <= 75 * 1000 * 1000) { + return preview; + } + } + } + } + + int divisor = 2; + while (preview.getPreviewWidth() * preview.getPreviewHeight() / divisor / divisor > 75 * 1000 * 1000) { + preview.setPreviewWidth(preview.getPreviewWidth() / divisor); + preview.setPreviewHeight(preview.getPreviewHeight() / divisor); + divisor *= 2; + } + + return preview; + } + + return null; + } + + private void loadImage(PostDetailBaseViewHolder holder, @NonNull Post.Preview preview) { + if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { + String url = mPost.getPostType() == Post.IMAGE_TYPE ? preview.getPreviewUrl() : mPost.getUrl(); + RequestBuilder imageRequestBuilder = mGlide.load(url) + .listener(new RequestListener() { + @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); + loadImage(holder, preview); + }); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((PostDetailImageAndGifAutoplayViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); + return false; + } + }); + + if ((mPost.isNSFW() && mNeedBlurNsfw && !(mPost.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); + } else { + if (mImageViewWidth > preview.getPreviewWidth()) { + imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); + } else { + imageRequestBuilder.into(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); + } + } + } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { + RequestBuilder imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) + .listener(new RequestListener() { + @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); + loadImage(holder, preview); + }); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((PostDetailVideoAndGifPreviewHolder) holder).mLoadWrapper.setVisibility(View.GONE); + return false; + } + }); + + if ((mPost.isNSFW() && mNeedBlurNsfw) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) + .into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); + } else { + if (mImageViewWidth > preview.getPreviewWidth()) { + imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); + } else { + imageRequestBuilder.into(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); + } + } + } else if (holder instanceof PostDetailLinkViewHolder) { + RequestBuilder imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) + .listener(new RequestListener() { + @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); + loadImage(holder, preview); + }); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((PostDetailLinkViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); + return false; + } + }); + + if ((mPost.isNSFW() && mNeedBlurNsfw) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) + .into(((PostDetailLinkViewHolder) holder).mImageView); + } else { + if (mImageViewWidth > preview.getPreviewWidth()) { + imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailLinkViewHolder) holder).mImageView); + } else { + imageRequestBuilder.into(((PostDetailLinkViewHolder) holder).mImageView); + } + } + } else if (holder instanceof PostDetailGalleryViewHolder) { + RequestBuilder imageRequestBuilder = mGlide.load(preview.getPreviewUrl()) + .listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + ((PostDetailGalleryViewHolder) holder).mLoadImageProgressBar.setVisibility(View.GONE); + ((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.VISIBLE); + ((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setOnClickListener(view -> { + ((PostDetailGalleryViewHolder) holder).mLoadImageProgressBar.setVisibility(View.VISIBLE); + ((PostDetailGalleryViewHolder) holder).mLoadImageErrorTextView.setVisibility(View.GONE); + loadImage(holder, preview); + }); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((PostDetailGalleryViewHolder) holder).mLoadWrapper.setVisibility(View.GONE); + return false; + } + }); + + if ((mPost.isNSFW() && mNeedBlurNsfw && !(mPost.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || (mPost.isSpoiler() && mNeedBlurSpoiler)) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))).into(((PostDetailGalleryViewHolder) holder).mImageView); + } else { + if (mImageViewWidth > preview.getPreviewWidth()) { + imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostDetailGalleryViewHolder) holder).mImageView); + } else { + imageRequestBuilder.into(((PostDetailGalleryViewHolder) holder).mImageView); + } + } + } + } + + public void updatePost(Post post) { + mPost = post; + notifyItemChanged(0); + } + + private int getParentPosition(int position) { + if (position >= 0 && position < mVisibleComments.size()) { + int childDepth = mVisibleComments.get(position).getDepth(); + for (int i = position; i >= 0; i--) { + if (mVisibleComments.get(i).getDepth() < childDepth) { + return i; + } + } + } + return -1; + } + + private void expandChildren(ArrayList comments, ArrayList newList, int position) { + if (comments != null && comments.size() > 0) { + newList.addAll(position, comments); + for (int i = 0; i < comments.size(); i++) { + position++; + if (comments.get(i).getChildren() != null && comments.get(i).getChildren().size() > 0) { + expandChildren(comments.get(i).getChildren(), newList, position); + position = position + comments.get(i).getChildren().size(); + } + comments.get(i).setExpanded(true); + } + } + } + + private void collapseChildren(int position) { + mVisibleComments.get(position).setExpanded(false); + int depth = mVisibleComments.get(position).getDepth(); + int allChildrenSize = 0; + for (int i = position + 1; i < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i).getDepth() > depth) { + allChildrenSize++; + } else { + break; + } + } + + if (allChildrenSize > 0) { + mVisibleComments.subList(position + 1, position + 1 + allChildrenSize).clear(); + } + if (mIsSingleCommentThreadMode) { + if (mFullyCollapseComment) { + notifyItemChanged(position + 2); + } + notifyItemRangeRemoved(position + 3, allChildrenSize); + } else { + if (mFullyCollapseComment) { + notifyItemChanged(position + 1); + } + notifyItemRangeRemoved(position + 2, allChildrenSize); + } + } + + public void addComments(@NonNull ArrayList comments, boolean hasMoreComments) { + if (mVisibleComments.size() == 0) { + isInitiallyLoading = false; + isInitiallyLoadingFailed = false; + if (comments.size() == 0) { + notifyItemChanged(1); + } else { + notifyItemRemoved(1); + } + } + + int sizeBefore = mVisibleComments.size(); + mVisibleComments.addAll(comments); + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(sizeBefore + 2, comments.size()); + } else { + notifyItemRangeInserted(sizeBefore + 1, comments.size()); + } + + if (mHasMoreComments != hasMoreComments) { + if (hasMoreComments) { + if (mIsSingleCommentThreadMode) { + notifyItemInserted(mVisibleComments.size() + 2); + } else { + notifyItemInserted(mVisibleComments.size() + 1); + } + } else { + if (mIsSingleCommentThreadMode) { + notifyItemRemoved(mVisibleComments.size() + 2); + } else { + notifyItemRemoved(mVisibleComments.size() + 1); + } + } + } + mHasMoreComments = hasMoreComments; + } + + public void addComment(Comment comment) { + if (mVisibleComments.size() == 0 || isInitiallyLoadingFailed) { + notifyItemRemoved(1); + } + + mVisibleComments.add(0, comment); + + if (isInitiallyLoading) { + notifyItemInserted(2); + } else { + notifyItemInserted(1); + } + } + + public void addChildComment(Comment comment, String parentFullname, int parentPosition) { + if (!parentFullname.equals(mVisibleComments.get(parentPosition).getFullName())) { + for (int i = 0; i < mVisibleComments.size(); i++) { + if (parentFullname.equals(mVisibleComments.get(i).getFullName())) { + parentPosition = i; + break; + } + } + } + + mVisibleComments.get(parentPosition).addChild(comment); + mVisibleComments.get(parentPosition).setHasReply(true); + if (!mVisibleComments.get(parentPosition).isExpanded()) { + ArrayList newList = new ArrayList<>(); + expandChildren(mVisibleComments.get(parentPosition).getChildren(), newList, 0); + mVisibleComments.get(parentPosition).setExpanded(true); + mVisibleComments.addAll(parentPosition + 1, newList); + if (mIsSingleCommentThreadMode) { + notifyItemChanged(parentPosition + 2); + notifyItemRangeInserted(parentPosition + 3, newList.size()); + } else { + notifyItemChanged(parentPosition + 1); + notifyItemRangeInserted(parentPosition + 2, newList.size()); + } + } else { + mVisibleComments.add(parentPosition + 1, comment); + if (mIsSingleCommentThreadMode) { + notifyItemInserted(parentPosition + 3); + } else { + notifyItemInserted(parentPosition + 2); + } + } + } + + public void setSingleComment(String singleCommentId, boolean isSingleCommentThreadMode) { + mSingleCommentId = singleCommentId; + mIsSingleCommentThreadMode = isSingleCommentThreadMode; + } + + public ArrayList getVisibleComments() { + return mVisibleComments; + } + + public void initiallyLoading() { + if (mVisibleComments.size() != 0) { + int previousSize = mVisibleComments.size(); + mVisibleComments.clear(); + if (mIsSingleCommentThreadMode) { + notifyItemRangeRemoved(1, previousSize + 1); + } else { + notifyItemRangeRemoved(1, previousSize); + } + } + + if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { + isInitiallyLoading = true; + isInitiallyLoadingFailed = false; + notifyItemChanged(1); + } else { + isInitiallyLoading = true; + isInitiallyLoadingFailed = false; + notifyItemInserted(1); + } + } + + public void initiallyLoadCommentsFailed() { + isInitiallyLoading = false; + isInitiallyLoadingFailed = true; + notifyItemChanged(1); + } + + public void loadMoreCommentsFailed() { + loadMoreCommentsFailed = true; + if (mIsSingleCommentThreadMode) { + notifyItemChanged(mVisibleComments.size() + 2); + } else { + notifyItemChanged(mVisibleComments.size() + 1); + } + } + + public void editComment(String commentAuthor, String commentContentMarkdown, int position) { + if (commentAuthor != null) + mVisibleComments.get(position).setAuthor(commentAuthor); + + mVisibleComments.get(position).setCommentMarkdown(commentContentMarkdown); + if (mIsSingleCommentThreadMode) { + notifyItemChanged(position + 2); + } else { + notifyItemChanged(position + 1); + } + } + + public void deleteComment(int position) { + if (mVisibleComments != null && position >= 0 && position < mVisibleComments.size()) { + if (mVisibleComments.get(position).hasReply()) { + mVisibleComments.get(position).setAuthor("[deleted]"); + mVisibleComments.get(position).setCommentMarkdown("[deleted]"); + if (mIsSingleCommentThreadMode) { + notifyItemChanged(position + 2); + } else { + notifyItemChanged(position + 1); + } + } else { + mVisibleComments.remove(position); + if (mIsSingleCommentThreadMode) { + notifyItemRemoved(position + 2); + } else { + notifyItemRemoved(position + 1); + } + } + } + } + + public void setBlurNSFW(boolean needBlurNSFW) { + mNeedBlurNsfw = needBlurNSFW; + } + + public void setBlurSpoiler(boolean needBlurSpoiler) { + mNeedBlurSpoiler = needBlurSpoiler; + } + + public int getNextParentCommentPosition(int currentPosition) { + if (mVisibleComments != null && !mVisibleComments.isEmpty()) { + if (mIsSingleCommentThreadMode) { + for (int i = currentPosition + 1; i - 2 < mVisibleComments.size() && i - 2 >= 0; i++) { + if (mVisibleComments.get(i - 2).getDepth() == 0) { + return i; + } + } + } else { + for (int i = currentPosition + 1; i - 1 < mVisibleComments.size(); i++) { + if (mVisibleComments.get(i - 1).getDepth() == 0) { + return i; + } + } + } + } + return -1; + } + + public int getPreviousParentCommentPosition(int currentPosition) { + if (mVisibleComments != null && !mVisibleComments.isEmpty()) { + if (mIsSingleCommentThreadMode) { + for (int i = currentPosition + 1; i - 2 >= 0; i--) { + if (mVisibleComments.get(i - 2).getDepth() == 0) { + return i; + } + } + } else { + for (int i = currentPosition - 1; i - 1 >= 0; i--) { + if (mVisibleComments.get(i - 1).getDepth() == 0) { + return i; + } + } + } + } + return -1; + } + + public void setAutoplay(boolean autoplay) { + mAutoplay = autoplay; + } + + public void setDataSavingMode(boolean dataSavingMode) { + mDataSavingMode = dataSavingMode; + } + + public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) { + if (viewHolder instanceof PostDetailBaseViewHolder) { + if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((PostDetailBaseViewHolder) viewHolder).mUpvoteButton.performClick(); + } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((PostDetailBaseViewHolder) viewHolder).mDownvoteButton.performClick(); + } + } else { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((PostDetailBaseViewHolder) viewHolder).mUpvoteButton.performClick(); + } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((PostDetailBaseViewHolder) viewHolder).mDownvoteButton.performClick(); + } + } + } else if (viewHolder instanceof CommentViewHolder) { + if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((CommentViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((CommentViewHolder) viewHolder).downvoteButton.performClick(); + } + } else { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((CommentViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((CommentViewHolder) viewHolder).downvoteButton.performClick(); + } + } + } + } + + public void giveAward(String awardsHTML, int awardCount, int position) { + if (position == 0) { + if (mPost != null) { + mPost.addAwards(awardsHTML); + mPost.addAwards(awardCount); + notifyItemChanged(0); + } + } else { + position = mIsSingleCommentThreadMode ? position + 2 : position + 1; + Comment comment = getCurrentComment(position); + if (comment != null) { + comment.addAwards(awardsHTML); + notifyItemChanged(position); + } + } + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if (holder instanceof CommentViewHolder) { + ((CommentViewHolder) holder).authorTextView.setTextColor(mUsernameColor); + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); + ((CommentViewHolder) holder).authorTextView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null); + ((CommentViewHolder) holder).awardsTextView.setText(""); + ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); + ((CommentViewHolder) holder).expandButton.setVisibility(View.GONE); + ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); + ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ViewGroup.LayoutParams params = ((CommentViewHolder) holder).verticalBlock.getLayoutParams(); + params.width = 0; + ((CommentViewHolder) holder).verticalBlock.setLayoutParams(params); + ((CommentViewHolder) holder).itemView.setPadding(0, 0, 0, 0); + ((CommentViewHolder) holder).itemView.setBackgroundColor(mCommentBackgroundColor); + } else if (holder instanceof CommentFullyCollapsedViewHolder) { + ViewGroup.LayoutParams params = ((CommentFullyCollapsedViewHolder) holder).verticalBlock.getLayoutParams(); + params.width = 0; + ((CommentFullyCollapsedViewHolder) holder).verticalBlock.setLayoutParams(params); + ((CommentFullyCollapsedViewHolder) holder).itemView.setPadding(0, 0, 0, 0); + } else if (holder instanceof PostDetailBaseViewHolder) { + ((PostDetailBaseViewHolder) holder).mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mScoreTextView.setTextColor(mPostIconAndInfoColor); + ((PostDetailBaseViewHolder) holder).mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostDetailBaseViewHolder) holder).mFlairTextView.setVisibility(View.GONE); + ((PostDetailBaseViewHolder) holder).mSpoilerTextView.setVisibility(View.GONE); + ((PostDetailBaseViewHolder) holder).mNSFWTextView.setVisibility(View.GONE); + + if (holder instanceof PostDetailVideoAutoplayViewHolder) { + if (((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks != null) { + ((PostDetailVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks.cancel(); + } + ((PostDetailVideoAutoplayViewHolder) holder).mErrorLoadingGfycatImageView.setVisibility(View.GONE); + ((PostDetailVideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); + ((PostDetailVideoAutoplayViewHolder) holder).resetVolume(); + mGlide.clear(((PostDetailVideoAutoplayViewHolder) holder).previewImageView); + ((PostDetailVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); + } else if (holder instanceof PostDetailVideoAndGifPreviewHolder) { + mGlide.clear(((PostDetailVideoAndGifPreviewHolder) holder).mImageView); + } else if (holder instanceof PostDetailImageAndGifAutoplayViewHolder) { + mGlide.clear(((PostDetailImageAndGifAutoplayViewHolder) holder).mImageView); + } else if (holder instanceof PostDetailLinkViewHolder) { + mGlide.clear(((PostDetailLinkViewHolder) holder).mImageView); + } + } else if (holder instanceof LoadMoreChildCommentsViewHolder) { + ((LoadMoreChildCommentsViewHolder) holder).itemView.setPadding(0, 0, 0, 0); + ViewGroup.LayoutParams params = ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.getLayoutParams(); + params.width = 0; + ((LoadMoreChildCommentsViewHolder) holder).verticalBlock.setLayoutParams(params); + } + } + + @Override + public int getItemCount() { + if (isInitiallyLoading || isInitiallyLoadingFailed || mVisibleComments.size() == 0) { + return 2; + } + + if (mHasMoreComments || loadMoreCommentsFailed) { + if (mIsSingleCommentThreadMode) { + return mVisibleComments.size() + 3; + } else { + return mVisibleComments.size() + 2; + } + } + + if (mIsSingleCommentThreadMode) { + return mVisibleComments.size() + 2; + } else { + return mVisibleComments.size() + 1; + } + } + + @Nullable + @Override + public Object getKeyForOrder(int order) { + return mPost; + } + + @Nullable + @Override + public Integer getOrderForKey(@NonNull Object key) { + return 0; + } + + public interface CommentRecyclerViewAdapterCallback { + void updatePost(Post post); + + void retryFetchingComments(); + + void retryFetchingMoreComments(); + } + + public class PostDetailBaseViewHolder extends RecyclerView.ViewHolder { + AspectRatioGifImageView mIconGifImageView; + TextView mSubredditTextView; + TextView mUserTextView; + TextView mAuthorFlairTextView; + TextView mPostTimeTextView; + TextView mTitleTextView; + CustomTextView mTypeTextView; + ImageView mCrosspostImageView; + ImageView mArchivedImageView; + ImageView mLockedImageView; + CustomTextView mNSFWTextView; + CustomTextView mSpoilerTextView; + CustomTextView mFlairTextView; + TextView mAwardsTextView; + ConstraintLayout mBottomConstraintLayout; + ImageView mUpvoteButton; + TextView mScoreTextView; + ImageView mDownvoteButton; + TextView commentsCountTextView; + ImageView mSaveButton; + ImageView mShareButton; + + PostDetailBaseViewHolder(@NonNull View itemView) { + super(itemView); + } + + void setBaseView(AspectRatioGifImageView mIconGifImageView, + TextView mSubredditTextView, + TextView mUserTextView, + TextView mAuthorFlairTextView, + TextView mPostTimeTextView, + TextView mTitleTextView, + CustomTextView mTypeTextView, + ImageView mCrosspostImageView, + ImageView mArchivedImageView, + ImageView mLockedImageView, + CustomTextView mNSFWTextView, + CustomTextView mSpoilerTextView, + CustomTextView mFlairTextView, + TextView mAwardsTextView, + ConstraintLayout mBottomConstraintLayout, + ImageView mUpvoteButton, + TextView mScoreTextView, + ImageView mDownvoteButton, + TextView commentsCountTextView, + ImageView mSaveButton, + ImageView mShareButton) { + this.mIconGifImageView = mIconGifImageView; + this.mSubredditTextView = mSubredditTextView; + this.mUserTextView = mUserTextView; + this.mAuthorFlairTextView = mAuthorFlairTextView; + this.mPostTimeTextView = mPostTimeTextView; + this.mTitleTextView = mTitleTextView; + this.mTypeTextView = mTypeTextView; + this.mCrosspostImageView = mCrosspostImageView; + this.mArchivedImageView = mArchivedImageView; + this.mLockedImageView = mLockedImageView; + this.mNSFWTextView = mNSFWTextView; + this.mSpoilerTextView = mSpoilerTextView; + this.mFlairTextView = mFlairTextView; + this.mAwardsTextView = mAwardsTextView; + this.mBottomConstraintLayout = mBottomConstraintLayout; + this.mUpvoteButton = mUpvoteButton; + this.mScoreTextView = mScoreTextView; + this.mDownvoteButton = mDownvoteButton; + this.commentsCountTextView = commentsCountTextView; + this.mSaveButton = mSaveButton; + this.mShareButton = mShareButton; + + mIconGifImageView.setOnClickListener(view -> mSubredditTextView.performClick()); + + mSubredditTextView.setOnClickListener(view -> { + Intent intent; + if (mPost.getSubredditNamePrefixed().equals("u/" + mPost.getAuthor())) { + intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mPost.getAuthor()); + } else { + intent = new Intent(mActivity, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, + mPost.getSubredditNamePrefixed().substring(2)); + } + mActivity.startActivity(intent); + }); + + mUserTextView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mPost.getAuthor()); + mActivity.startActivity(intent); + }); + + mAuthorFlairTextView.setOnClickListener(view -> mUserTextView.performClick()); + + mCrosspostImageView.setOnClickListener(view -> { + Intent crosspostIntent = new Intent(mActivity, ViewPostDetailActivity.class); + crosspostIntent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, mPost.getCrosspostParentId()); + mActivity.startActivity(crosspostIntent); + }); + + mTypeTextView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, mPost.getPostType()); + mActivity.startActivity(intent); + }); + + mNSFWTextView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, mSubredditNamePrefixed.substring(2)); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, Post.NSFW_TYPE); + mActivity.startActivity(intent); + }); + + mUpvoteButton.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter(); + int previousScoreTextViewColor = mScoreTextView.getCurrentTextColor(); + + int previousVoteType = mPost.getVoteType(); + String newVoteType; + + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != 1) { + //Not upvoted before + mPost.setVoteType(1); + newVoteType = APIUtils.DIR_UPVOTE; + mUpvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + mPost.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mPostIconAndInfoColor); + } + + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingWithoutPositionListener() { + @Override + public void onVoteThingSuccess() { + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + mPost.setVoteType(1); + mUpvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mUpvotedColor); + } else { + mPost.setVoteType(0); + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mPostIconAndInfoColor); + } + + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + + @Override + public void onVoteThingFail() { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + mPost.setVoteType(previousVoteType); + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + previousVoteType)); + mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + mScoreTextView.setTextColor(previousScoreTextViewColor); + + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + }, mPost.getFullName(), newVoteType); + }); + + mDownvoteButton.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = mUpvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = mDownvoteButton.getColorFilter(); + int previousScoreTextViewColor = mScoreTextView.getCurrentTextColor(); + + int previousVoteType = mPost.getVoteType(); + String newVoteType; + + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != -1) { + //Not upvoted before + mPost.setVoteType(-1); + newVoteType = APIUtils.DIR_DOWNVOTE; + mDownvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mDownvotedColor); + } else { + //Upvoted before + mPost.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mPostIconAndInfoColor); + } + + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingWithoutPositionListener() { + @Override + public void onVoteThingSuccess() { + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + mPost.setVoteType(-1); + mDownvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mDownvotedColor); + } else { + mPost.setVoteType(0); + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mPostIconAndInfoColor); + } + + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + mPost.getVoteType())); + + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + + @Override + public void onVoteThingFail() { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + mPost.setVoteType(previousVoteType); + mScoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + mPost.getScore() + previousVoteType)); + mUpvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + mDownvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + mScoreTextView.setTextColor(previousScoreTextViewColor); + + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + }, mPost.getFullName(), newVoteType); + }); + + commentsCountTextView.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_comment_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mPost.isLocked()) { + Toast.makeText(mActivity, R.string.locked_post_comment_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + Intent intent = new Intent(mActivity, CommentActivity.class); + intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, mPost.getFullName()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, mPost.getTitle()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_MARKDOWN_KEY, mPost.getSelfText()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_BODY_KEY, mPost.getSelfTextPlain()); + intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, false); + intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, 0); + mActivity.startActivityForResult(intent, WRITE_COMMENT_REQUEST_CODE); + }); + + mSaveButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (mPost.isSaved()) { + mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + mPost.setSaved(false); + mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mActivity, R.string.post_unsaved_success, Toast.LENGTH_SHORT).show(); + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + + @Override + public void failed() { + mPost.setSaved(true); + mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + }); + } else { + mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, mPost.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + mPost.setSaved(true); + mSaveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + + @Override + public void failed() { + mPost.setSaved(false); + mSaveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mActivity, R.string.post_saved_failed, Toast.LENGTH_SHORT).show(); + mCommentRecyclerViewAdapterCallback.updatePost(mPost); + } + }); + } + }); + + mShareButton.setOnClickListener(view -> { + Bundle bundle = new Bundle(); + bundle.putString(ShareLinkBottomSheetFragment.EXTRA_POST_LINK, mPost.getPermalink()); + if (mPost.getPostType() != Post.TEXT_TYPE) { + bundle.putInt(ShareLinkBottomSheetFragment.EXTRA_MEDIA_TYPE, mPost.getPostType()); + switch (mPost.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, mPost.getUrl()); + break; + case Post.VIDEO_TYPE: + bundle.putString(ShareLinkBottomSheetFragment.EXTRA_MEDIA_LINK, mPost.getVideoDownloadUrl()); + break; + } + } + mShareLinkBottomSheetFragment.setArguments(bundle); + mShareLinkBottomSheetFragment.show(mActivity.getSupportFragmentManager(), mShareLinkBottomSheetFragment.getTag()); + }); + + if (mVoteButtonsOnTheRight) { + ConstraintSet constraintSet = new ConstraintSet(); + constraintSet.clone(mBottomConstraintLayout); + constraintSet.clear(mUpvoteButton.getId(), ConstraintSet.START); + constraintSet.clear(mScoreTextView.getId(), ConstraintSet.START); + constraintSet.clear(mDownvoteButton.getId(), ConstraintSet.START); + constraintSet.clear(mSaveButton.getId(), ConstraintSet.END); + constraintSet.clear(mShareButton.getId(), ConstraintSet.END); + constraintSet.connect(mUpvoteButton.getId(), ConstraintSet.END, mScoreTextView.getId(), ConstraintSet.START); + constraintSet.connect(mScoreTextView.getId(), ConstraintSet.END, mDownvoteButton.getId(), ConstraintSet.START); + constraintSet.connect(mDownvoteButton.getId(), ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END); + constraintSet.connect(commentsCountTextView.getId(), ConstraintSet.START, mSaveButton.getId(), ConstraintSet.END); + constraintSet.connect(commentsCountTextView.getId(), ConstraintSet.END, mUpvoteButton.getId(), ConstraintSet.START); + constraintSet.connect(mSaveButton.getId(), ConstraintSet.START, mShareButton.getId(), ConstraintSet.END); + constraintSet.connect(mShareButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); + constraintSet.setHorizontalBias(commentsCountTextView.getId(), 0); + constraintSet.applyTo(mBottomConstraintLayout); + } + + itemView.setBackgroundColor(mCardViewColor); + mSubredditTextView.setTextColor(mSubredditColor); + mUserTextView.setTextColor(mUsernameColor); + mAuthorFlairTextView.setTextColor(mAuthorFlairTextColor); + mPostTimeTextView.setTextColor(mSecondaryTextColor); + mTitleTextView.setTextColor(mPostTitleColor); + mTypeTextView.setBackgroundColor(mPostTypeBackgroundColor); + mTypeTextView.setBorderColor(mPostTypeBackgroundColor); + mTypeTextView.setTextColor(mPostTypeTextColor); + mSpoilerTextView.setBackgroundColor(mSpoilerBackgroundColor); + mSpoilerTextView.setBorderColor(mSpoilerBackgroundColor); + mSpoilerTextView.setTextColor(mSpoilerTextColor); + mNSFWTextView.setBackgroundColor(mNSFWBackgroundColor); + mNSFWTextView.setBorderColor(mNSFWBackgroundColor); + mNSFWTextView.setTextColor(mNSFWTextColor); + mFlairTextView.setBackgroundColor(mFlairBackgroundColor); + mFlairTextView.setBorderColor(mFlairBackgroundColor); + mFlairTextView.setTextColor(mFlairTextColor); + mArchivedImageView.setColorFilter(mArchivedTintColor, PorterDuff.Mode.SRC_IN); + mLockedImageView.setColorFilter(mLockedTintColor, PorterDuff.Mode.SRC_IN); + mCrosspostImageView.setColorFilter(mCrosspostTintColor, PorterDuff.Mode.SRC_IN); + mAwardsTextView.setTextColor(mSecondaryTextColor); + mUpvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mScoreTextView.setTextColor(mPostIconAndInfoColor); + mDownvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + commentsCountTextView.setTextColor(mPostIconAndInfoColor); + commentsCountTextView.setCompoundDrawablesWithIntrinsicBounds(mCommentIcon, null, null, null); + mSaveButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + mShareButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + } + + class PostDetailVideoAutoplayViewHolder extends PostDetailBaseViewHolder implements ToroPlayer { + @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.user_text_view_item_post_detail_video_autoplay) + TextView mUserTextView; + @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.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.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.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 + ExoPlayerViewHelper helper; + private Uri mediaUri; + private float volume; + public FetchGfycatOrRedgifsVideoLinks fetchGfycatOrRedgifsVideoLinks; + + public PostDetailVideoAutoplayViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(mIconGifImageView, + mSubredditTextView, + mUserTextView, + mAuthorFlairTextView, + mPostTimeTextView, + mTitleTextView, + mTypeTextView, + mCrosspostImageView, + mArchivedImageView, + mLockedImageView, + mNSFWTextView, + mSpoilerTextView, + mFlairTextView, + mAwardsTextView, + mBottomConstraintLayout, + mUpvoteButton, + mScoreTextView, + mDownvoteButton, + commentsCountTextView, + mSaveButton, + mShareButton); + + aspectRatioFrameLayout.setOnClickListener(null); + + muteButton.setOnClickListener(view -> { + if (helper != null) { + if (helper.getVolume() != 0) { + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + helper.setVolume(0f); + volume = 0f; + } else { + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + helper.setVolume(1f); + volume = 1f; + } + } + }); + + fullscreenButton.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + if (mPost.isGfycat()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); + if (mPost.isLoadGfyOrRedgifsVideoSuccess()) { + intent.setData(Uri.parse(mPost.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); + } + } else if (mPost.isRedgifs()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); + if (mPost.isLoadGfyOrRedgifsVideoSuccess()) { + intent.setData(Uri.parse(mPost.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); + } + } else { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); + intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName()); + intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId()); + } + intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, mPost.getTitle()); + if (helper != null) { + intent.putExtra(ViewVideoActivity.EXTRA_PROGRESS_SECONDS, helper.getLatestPlaybackInfo().getResumePosition()); + } + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + }); + + previewImageView.setOnLongClickListener(view -> fullscreenButton.performClick()); + playerView.setOnLongClickListener(view -> fullscreenButton.performClick()); + } + + void bindVideoUri(Uri videoUri) { + mediaUri = videoUri; + } + + void setVolume(float volume) { + this.volume = volume; + } + + void resetVolume() { + volume = 0f; + } + + @NonNull + @Override + public View getPlayerView() { + return playerView; + } + + @NonNull + @Override + public PlaybackInfo getCurrentPlaybackInfo() { + return helper != null && mediaUri != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo(); + } + + @Override + public void initialize(@NonNull Container container, @NonNull PlaybackInfo playbackInfo) { + if (mediaUri == null) { + return; + } + if (helper == null) { + helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); + helper.addEventListener(new Playable.EventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + helper.setVolume(volume); + muteButton.setVisibility(View.VISIBLE); + if (volume != 0f) { + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + } else { + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + } + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + + @Override + public void onMetadata(Metadata metadata) { + + } + + @Override + public void onCues(List cues) { + + } + + @Override + public void onRenderedFirstFrame() { + mGlide.clear(previewImageView); + previewImageView.setVisibility(View.GONE); + } + }); + } + helper.initialize(container, playbackInfo); + } + + @Override + public void play() { + if (helper != null && mediaUri != null) helper.play(); + } + + @Override + public void pause() { + if (helper != null) helper.pause(); + } + + @Override + public boolean isPlaying() { + return helper != null && helper.isPlaying(); + } + + @Override + public void release() { + if (helper != null) { + helper.release(); + helper = null; + } + } + + @Override + public boolean wantsToPlay() { + return ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= mStartAutoplayVisibleAreaOffset; + } + + @Override + public int getPlayerOrder() { + return getAdapterPosition(); + } + } + + class PostDetailVideoAndGifPreviewHolder extends PostDetailBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_detail_video_and_gif_preview) + AspectRatioGifImageView mIconGifImageView; + @BindView(R.id.subreddit_text_view_item_post_detail_video_and_gif_preview) + TextView mSubredditTextView; + @BindView(R.id.user_text_view_item_post_detail_video_and_gif_preview) + TextView mUserTextView; + @BindView(R.id.author_flair_text_view_item_post_detail_video_and_gif_preview) + TextView mAuthorFlairTextView; + @BindView(R.id.post_time_text_view_item_post_detail_video_and_gif_preview) + TextView mPostTimeTextView; + @BindView(R.id.title_text_view_item_post_detail_video_and_gif_preview) + TextView mTitleTextView; + @BindView(R.id.type_text_view_item_post_detail_video_and_gif_preview) + CustomTextView mTypeTextView; + @BindView(R.id.crosspost_image_view_item_post_detail_video_and_gif_preview) + ImageView mCrosspostImageView; + @BindView(R.id.archived_image_view_item_post_detail_video_and_gif_preview) + ImageView mArchivedImageView; + @BindView(R.id.locked_image_view_item_post_detail_video_and_gif_preview) + ImageView mLockedImageView; + @BindView(R.id.nsfw_text_view_item_post_detail_video_and_gif_preview) + CustomTextView mNSFWTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_detail_video_and_gif_preview) + CustomTextView mSpoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_detail_video_and_gif_preview) + CustomTextView mFlairTextView; + @BindView(R.id.awards_text_view_item_post_detail_video_and_gif_preview) + TextView mAwardsTextView; + @BindView(R.id.load_wrapper_item_post_detail_video_and_gif_preview) + RelativeLayout mLoadWrapper; + @BindView(R.id.progress_bar_item_post_detail_video_and_gif_preview) + ProgressBar mLoadImageProgressBar; + @BindView(R.id.load_image_error_text_view_item_post_detail_video_and_gif_preview) + TextView mLoadImageErrorTextView; + @BindView(R.id.image_view_item_post_detail_video_and_gif_preview) + AspectRatioGifImageView mImageView; + @BindView(R.id.bottom_constraint_layout_item_post_detail_video_and_gif_preview) + ConstraintLayout mBottomConstraintLayout; + @BindView(R.id.plus_button_item_post_detail_video_and_gif_preview) + ImageView mUpvoteButton; + @BindView(R.id.score_text_view_item_post_detail_video_and_gif_preview) + TextView mScoreTextView; + @BindView(R.id.minus_button_item_post_detail_video_and_gif_preview) + ImageView mDownvoteButton; + @BindView(R.id.comments_count_item_post_detail_video_and_gif_preview) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_detail_video_and_gif_preview) + ImageView mSaveButton; + @BindView(R.id.share_button_item_post_detail_video_and_gif_preview) + ImageView mShareButton; + + PostDetailVideoAndGifPreviewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(mIconGifImageView, + mSubredditTextView, + mUserTextView, + mAuthorFlairTextView, + mPostTimeTextView, + mTitleTextView, + mTypeTextView, + mCrosspostImageView, + mArchivedImageView, + mLockedImageView, + mNSFWTextView, + mSpoilerTextView, + mFlairTextView, + mAwardsTextView, + mBottomConstraintLayout, + mUpvoteButton, + mScoreTextView, + mDownvoteButton, + commentsCountTextView, + mSaveButton, + mShareButton); + + mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); + + mImageView.setOnClickListener(view -> { + if (mPost.getPostType() == Post.VIDEO_TYPE) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + if (mPost.isGfycat()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); + } else if (mPost.isRedgifs()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); + } else { + intent.setData(Uri.parse(mPost.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName()); + intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId()); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); + } + intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, mPost.getTitle()); + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + } else if (mPost.getPostType() == Post.GIF_TYPE) { + Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() + + "-" + mPost.getId() + ".gif"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, mPost.getVideoUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); + mActivity.startActivity(intent); + } + }); + } + } + + class PostDetailImageAndGifAutoplayViewHolder extends PostDetailBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_detail_image_and_gif_autoplay) + AspectRatioGifImageView mIconGifImageView; + @BindView(R.id.subreddit_text_view_item_post_detail_image_and_gif_autoplay) + TextView mSubredditTextView; + @BindView(R.id.user_text_view_item_post_detail_image_and_gif_autoplay) + TextView mUserTextView; + @BindView(R.id.author_flair_text_view_item_post_detail_image_and_gif_autoplay) + TextView mAuthorFlairTextView; + @BindView(R.id.post_time_text_view_item_post_detail_image_and_gif_autoplay) + TextView mPostTimeTextView; + @BindView(R.id.title_text_view_item_post_detail_image_and_gif_autoplay) + TextView mTitleTextView; + @BindView(R.id.type_text_view_item_post_detail_image_and_gif_autoplay) + CustomTextView mTypeTextView; + @BindView(R.id.crosspost_image_view_item_post_detail_image_and_gif_autoplay) + ImageView mCrosspostImageView; + @BindView(R.id.archived_image_view_item_post_detail_image_and_gif_autoplay) + ImageView mArchivedImageView; + @BindView(R.id.locked_image_view_item_post_detail_image_and_gif_autoplay) + ImageView mLockedImageView; + @BindView(R.id.nsfw_text_view_item_post_detail_image_and_gif_autoplay) + CustomTextView mNSFWTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_detail_image_and_gif_autoplay) + CustomTextView mSpoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_detail_image_and_gif_autoplay) + CustomTextView mFlairTextView; + @BindView(R.id.awards_text_view_item_post_detail_image_and_gif_autoplay) + TextView mAwardsTextView; + @BindView(R.id.image_view_wrapper_item_post_detail_image_and_gif_autoplay) + RelativeLayout mRelativeLayout; + @BindView(R.id.load_wrapper_item_post_detail_image_and_gif_autoplay) + RelativeLayout mLoadWrapper; + @BindView(R.id.progress_bar_item_post_detail_image_and_gif_autoplay) + ProgressBar mLoadImageProgressBar; + @BindView(R.id.load_image_error_text_view_item_post_detail_image_and_gif_autoplay) + TextView mLoadImageErrorTextView; + @BindView(R.id.image_view_item_post_detail_image_and_gif_autoplay) + AspectRatioGifImageView mImageView; + @BindView(R.id.bottom_constraint_layout_item_post_detail_image_and_gif_autoplay) + ConstraintLayout mBottomConstraintLayout; + @BindView(R.id.plus_button_item_post_detail_image_and_gif_autoplay) + ImageView mUpvoteButton; + @BindView(R.id.score_text_view_item_post_detail_image_and_gif_autoplay) + TextView mScoreTextView; + @BindView(R.id.minus_button_item_post_detail_image_and_gif_autoplay) + ImageView mDownvoteButton; + @BindView(R.id.comments_count_item_post_detail_image_and_gif_autoplay) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_detail_image_and_gif_autoplay) + ImageView mSaveButton; + @BindView(R.id.share_button_item_post_detail_image_and_gif_autoplay) + ImageView mShareButton; + + PostDetailImageAndGifAutoplayViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(mIconGifImageView, + mSubredditTextView, + mUserTextView, + mAuthorFlairTextView, + mPostTimeTextView, + mTitleTextView, + mTypeTextView, + mCrosspostImageView, + mArchivedImageView, + mLockedImageView, + mNSFWTextView, + mSpoilerTextView, + mFlairTextView, + mAwardsTextView, + mBottomConstraintLayout, + mUpvoteButton, + mScoreTextView, + mDownvoteButton, + commentsCountTextView, + mSaveButton, + mShareButton); + + mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); + + mImageView.setOnClickListener(view -> { + if (mPost.getPostType() == Post.IMAGE_TYPE) { + Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, mPost.getUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditNamePrefixed().substring(2) + + "-" + mPost.getId().substring(3) + ".jpg"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); + mActivity.startActivity(intent); + } else if (mPost.getPostType() == Post.GIF_TYPE) { + Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() + + "-" + mPost.getId() + ".gif"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, mPost.getVideoUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); + mActivity.startActivity(intent); + } + }); + } + } + + class PostDetailLinkViewHolder extends PostDetailBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_detail_link) + AspectRatioGifImageView mIconGifImageView; + @BindView(R.id.subreddit_text_view_item_post_detail_link) + TextView mSubredditTextView; + @BindView(R.id.user_text_view_item_post_detail_link) + TextView mUserTextView; + @BindView(R.id.author_flair_text_view_item_post_detail_link) + TextView mAuthorFlairTextView; + @BindView(R.id.post_time_text_view_item_post_detail_link) + TextView mPostTimeTextView; + @BindView(R.id.title_text_view_item_post_detail_link) + TextView mTitleTextView; + @BindView(R.id.type_text_view_item_post_detail_link) + CustomTextView mTypeTextView; + @BindView(R.id.crosspost_image_view_item_post_detail_link) + ImageView mCrosspostImageView; + @BindView(R.id.archived_image_view_item_post_detail_link) + ImageView mArchivedImageView; + @BindView(R.id.locked_image_view_item_post_detail_link) + ImageView mLockedImageView; + @BindView(R.id.nsfw_text_view_item_post_detail_link) + CustomTextView mNSFWTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_detail_link) + CustomTextView mSpoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_detail_link) + CustomTextView mFlairTextView; + @BindView(R.id.awards_text_view_item_post_detail_link) + TextView mAwardsTextView; + @BindView(R.id.link_text_view_item_post_detail_link) + TextView mLinkTextView; + @BindView(R.id.image_view_wrapper_item_post_detail_link) + RelativeLayout mRelativeLayout; + @BindView(R.id.load_wrapper_item_post_detail_link) + RelativeLayout mLoadWrapper; + @BindView(R.id.progress_bar_item_post_detail_link) + ProgressBar mLoadImageProgressBar; + @BindView(R.id.load_image_error_text_view_item_post_detail_link) + TextView mLoadImageErrorTextView; + @BindView(R.id.image_view_item_post_detail_link) + AspectRatioGifImageView mImageView; + @BindView(R.id.bottom_constraint_layout_item_post_detail_link) + ConstraintLayout mBottomConstraintLayout; + @BindView(R.id.plus_button_item_post_detail_link) + ImageView mUpvoteButton; + @BindView(R.id.score_text_view_item_post_detail_link) + TextView mScoreTextView; + @BindView(R.id.minus_button_item_post_detail_link) + ImageView mDownvoteButton; + @BindView(R.id.comments_count_item_post_detail_link) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_detail_link) + ImageView mSaveButton; + @BindView(R.id.share_button_item_post_detail_link) + ImageView mShareButton; + + PostDetailLinkViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(mIconGifImageView, + mSubredditTextView, + mUserTextView, + mAuthorFlairTextView, + mPostTimeTextView, + mTitleTextView, + mTypeTextView, + mCrosspostImageView, + mArchivedImageView, + mLockedImageView, + mNSFWTextView, + mSpoilerTextView, + mFlairTextView, + mAwardsTextView, + mBottomConstraintLayout, + mUpvoteButton, + mScoreTextView, + mDownvoteButton, + commentsCountTextView, + mSaveButton, + mShareButton); + + mLinkTextView.setTextColor(mSecondaryTextColor); + mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); + + mImageView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(mPost.getUrl()); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(mPost.getUrl())); + } else { + intent.setData(uri); + } + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + }); + } + } + + class PostDetailNoPreviewViewHolder extends PostDetailBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_detail_no_preview_link) + AspectRatioGifImageView mIconGifImageView; + @BindView(R.id.subreddit_text_view_item_post_detail_no_preview_link) + TextView mSubredditTextView; + @BindView(R.id.user_text_view_item_post_detail_no_preview_link) + TextView mUserTextView; + @BindView(R.id.author_flair_text_view_item_post_detail_no_preview_link) + TextView mAuthorFlairTextView; + @BindView(R.id.post_time_text_view_item_post_detail_no_preview_link) + TextView mPostTimeTextView; + @BindView(R.id.title_text_view_item_post_detail_no_preview_link) + TextView mTitleTextView; + @BindView(R.id.content_markdown_view_item_post_detail_no_preview_link) + RecyclerView mContentMarkdownView; + @BindView(R.id.type_text_view_item_post_detail_no_preview_link) + CustomTextView mTypeTextView; + @BindView(R.id.crosspost_image_view_item_post_detail_no_preview_link) + ImageView mCrosspostImageView; + @BindView(R.id.archived_image_view_item_post_detail_no_preview_link) + ImageView mArchivedImageView; + @BindView(R.id.locked_image_view_item_post_detail_no_preview_link) + ImageView mLockedImageView; + @BindView(R.id.nsfw_text_view_item_post_detail_no_preview_link) + CustomTextView mNSFWTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_detail_no_preview_link) + CustomTextView mSpoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_detail_no_preview_link) + CustomTextView mFlairTextView; + @BindView(R.id.awards_text_view_item_post_detail_no_preview_link) + TextView mAwardsTextView; + @BindView(R.id.link_text_view_item_post_detail_no_preview_link) + TextView mLinkTextView; + @BindView(R.id.image_view_no_preview_post_type_item_post_detail_no_preview_link) + ImageView mNoPreviewPostTypeImageView; + @BindView(R.id.bottom_constraint_layout_item_post_detail_no_preview_link) + ConstraintLayout mBottomConstraintLayout; + @BindView(R.id.plus_button_item_post_detail_no_preview_link) + ImageView mUpvoteButton; + @BindView(R.id.score_text_view_item_post_detail_no_preview_link) + TextView mScoreTextView; + @BindView(R.id.minus_button_item_post_detail_no_preview_link) + ImageView mDownvoteButton; + @BindView(R.id.comments_count_item_post_detail_no_preview_link) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_detail_no_preview_link) + ImageView mSaveButton; + @BindView(R.id.share_button_item_post_detail_no_preview_link) + ImageView mShareButton; + + PostDetailNoPreviewViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(mIconGifImageView, + mSubredditTextView, + mUserTextView, + mAuthorFlairTextView, + mPostTimeTextView, + mTitleTextView, + mTypeTextView, + mCrosspostImageView, + mArchivedImageView, + mLockedImageView, + mNSFWTextView, + mSpoilerTextView, + mFlairTextView, + mAwardsTextView, + mBottomConstraintLayout, + mUpvoteButton, + mScoreTextView, + mDownvoteButton, + commentsCountTextView, + mSaveButton, + mShareButton); + + mLinkTextView.setTextColor(mSecondaryTextColor); + mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + + mNoPreviewPostTypeImageView.setOnClickListener(view -> { + if (mPost != null) { + if (mPost.getPostType() == Post.VIDEO_TYPE) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + if (mPost.isGfycat()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); + } else if (mPost.isRedgifs()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_REDGIFS); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, mPost.getGfycatId()); + } else { + intent.setData(Uri.parse(mPost.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_SUBREDDIT, mPost.getSubredditName()); + intent.putExtra(ViewVideoActivity.EXTRA_ID, mPost.getId()); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, mPost.getVideoDownloadUrl()); + } + intent.putExtra(ViewVideoActivity.EXTRA_POST_TITLE, mPost.getTitle()); + intent.putExtra(ViewVideoActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + } else if (mPost.getPostType() == Post.IMAGE_TYPE) { + Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_IMAGE_URL_KEY, mPost.getUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() + + "-" + mPost.getId() + ".jpg"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); + mActivity.startActivity(intent); + } else if (mPost.getPostType() == Post.GIF_TYPE){ + Intent intent = new Intent(mActivity, ViewImageOrGifActivity.class); + intent.putExtra(ViewImageOrGifActivity.EXTRA_FILE_NAME_KEY, mPost.getSubredditName() + + "-" + mPost.getId() + ".gif"); + intent.putExtra(ViewImageOrGifActivity.EXTRA_GIF_URL_KEY, mPost.getVideoUrl()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_POST_TITLE_KEY, mPost.getTitle()); + intent.putExtra(ViewImageOrGifActivity.EXTRA_SUBREDDIT_OR_USERNAME_KEY, mPost.getSubredditName()); + mActivity.startActivity(intent); + } else if (mPost.getPostType() == Post.LINK_TYPE || mPost.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + Intent intent = new Intent(mActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(mPost.getUrl()); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(mPost.getUrl())); + } else { + intent.setData(uri); + } + intent.putExtra(LinkResolverActivity.EXTRA_IS_NSFW, mPost.isNSFW()); + mActivity.startActivity(intent); + } else if (mPost.getPostType() == Post.GALLERY_TYPE) { + Intent intent = new Intent(mActivity, ViewRedditGalleryActivity.class); + intent.putParcelableArrayListExtra(ViewRedditGalleryActivity.EXTRA_REDDIT_GALLERY, mPost.getGallery()); + intent.putExtra(ViewRedditGalleryActivity.EXTRA_SUBREDDIT_NAME, mPost.getSubredditName()); + mActivity.startActivity(intent); + } + } + }); + } + } + + class PostDetailGalleryViewHolder extends PostDetailBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_detail_gallery) + AspectRatioGifImageView mIconGifImageView; + @BindView(R.id.subreddit_text_view_item_post_detail_gallery) + TextView mSubredditTextView; + @BindView(R.id.user_text_view_item_post_detail_gallery) + TextView mUserTextView; + @BindView(R.id.author_flair_text_view_item_post_detail_gallery) + TextView mAuthorFlairTextView; + @BindView(R.id.post_time_text_view_item_post_detail_gallery) + TextView mPostTimeTextView; + @BindView(R.id.title_text_view_item_post_detail_gallery) + TextView mTitleTextView; + @BindView(R.id.type_text_view_item_post_detail_gallery) + CustomTextView mTypeTextView; + @BindView(R.id.crosspost_image_view_item_post_detail_gallery) + ImageView mCrosspostImageView; + @BindView(R.id.archived_image_view_item_post_detail_gallery) + ImageView mArchivedImageView; + @BindView(R.id.locked_image_view_item_post_detail_gallery) + ImageView mLockedImageView; + @BindView(R.id.nsfw_text_view_item_post_detail_gallery) + CustomTextView mNSFWTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_detail_gallery) + CustomTextView mSpoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_detail_gallery) + CustomTextView mFlairTextView; + @BindView(R.id.awards_text_view_item_post_detail_gallery) + TextView mAwardsTextView; + @BindView(R.id.image_view_wrapper_item_post_detail_gallery) + RelativeLayout mRelativeLayout; + @BindView(R.id.load_wrapper_item_post_detail_gallery) + RelativeLayout mLoadWrapper; + @BindView(R.id.progress_bar_item_post_detail_gallery) + ProgressBar mLoadImageProgressBar; + @BindView(R.id.load_image_error_text_view_item_post_detail_gallery) + TextView mLoadImageErrorTextView; + @BindView(R.id.image_view_item_post_detail_gallery) + AspectRatioGifImageView mImageView; + @BindView(R.id.image_view_no_preview_link_item_post_detail_gallery) + ImageView mNoPreviewPostTypeImageView; + @BindView(R.id.bottom_constraint_layout_item_post_detail_gallery) + ConstraintLayout mBottomConstraintLayout; + @BindView(R.id.plus_button_item_post_detail_gallery) + ImageView mUpvoteButton; + @BindView(R.id.score_text_view_item_post_detail_gallery) + TextView mScoreTextView; + @BindView(R.id.minus_button_item_post_detail_gallery) + ImageView mDownvoteButton; + @BindView(R.id.comments_count_item_post_detail_gallery) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_detail_gallery) + ImageView mSaveButton; + @BindView(R.id.share_button_item_post_detail_gallery) + ImageView mShareButton; + + PostDetailGalleryViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(mIconGifImageView, + mSubredditTextView, + mUserTextView, + mAuthorFlairTextView, + mPostTimeTextView, + mTitleTextView, + mTypeTextView, + mCrosspostImageView, + mArchivedImageView, + mLockedImageView, + mNSFWTextView, + mSpoilerTextView, + mFlairTextView, + mAwardsTextView, + mBottomConstraintLayout, + mUpvoteButton, + mScoreTextView, + mDownvoteButton, + commentsCountTextView, + mSaveButton, + mShareButton); + + mLoadImageProgressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + mLoadImageErrorTextView.setTextColor(mPrimaryTextColor); + mNoPreviewPostTypeImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + mNoPreviewPostTypeImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + + mImageView.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()); + mActivity.startActivity(intent); + }); + + mNoPreviewPostTypeImageView.setOnClickListener(view -> { + mImageView.performClick(); + }); + } + } + + class PostDetailTextViewHolder extends PostDetailBaseViewHolder { + @BindView(R.id.icon_gif_image_view_item_post_detail_text) + AspectRatioGifImageView mIconGifImageView; + @BindView(R.id.subreddit_text_view_item_post_detail_text) + TextView mSubredditTextView; + @BindView(R.id.user_text_view_item_post_detail_text) + TextView mUserTextView; + @BindView(R.id.author_flair_text_view_item_post_detail_text) + TextView mAuthorFlairTextView; + @BindView(R.id.post_time_text_view_item_post_detail_text) + TextView mPostTimeTextView; + @BindView(R.id.title_text_view_item_post_detail_text) + TextView mTitleTextView; + @BindView(R.id.content_markdown_view_item_post_detail_text) + RecyclerView mContentMarkdownView; + @BindView(R.id.type_text_view_item_post_detail_text) + CustomTextView mTypeTextView; + @BindView(R.id.crosspost_image_view_item_post_detail_text) + ImageView mCrosspostImageView; + @BindView(R.id.archived_image_view_item_post_detail_text) + ImageView mArchivedImageView; + @BindView(R.id.locked_image_view_item_post_detail_text) + ImageView mLockedImageView; + @BindView(R.id.nsfw_text_view_item_post_detail_text) + CustomTextView mNSFWTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_detail_text) + CustomTextView mSpoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_detail_text) + CustomTextView mFlairTextView; + @BindView(R.id.awards_text_view_item_post_detail_text) + TextView mAwardsTextView; + @BindView(R.id.bottom_constraint_layout_item_post_detail_text) + ConstraintLayout mBottomConstraintLayout; + @BindView(R.id.plus_button_item_post_detail_text) + ImageView mUpvoteButton; + @BindView(R.id.score_text_view_item_post_detail_text) + TextView mScoreTextView; + @BindView(R.id.minus_button_item_post_detail_text) + ImageView mDownvoteButton; + @BindView(R.id.comments_count_item_post_detail_text) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_detail_text) + ImageView mSaveButton; + @BindView(R.id.share_button_item_post_detail_text) + ImageView mShareButton; + + PostDetailTextViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(mIconGifImageView, + mSubredditTextView, + mUserTextView, + mAuthorFlairTextView, + mPostTimeTextView, + mTitleTextView, + mTypeTextView, + mCrosspostImageView, + mArchivedImageView, + mLockedImageView, + mNSFWTextView, + mSpoilerTextView, + mFlairTextView, + mAwardsTextView, + mBottomConstraintLayout, + mUpvoteButton, + mScoreTextView, + mDownvoteButton, + commentsCountTextView, + mSaveButton, + mShareButton); + } + } + + public class CommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.linear_layout_item_comment) + LinearLayout linearLayout; + @BindView(R.id.author_text_view_item_post_comment) + TextView authorTextView; + @BindView(R.id.author_flair_text_view_item_post_comment) + TextView authorFlairTextView; + @BindView(R.id.comment_time_text_view_item_post_comment) + TextView commentTimeTextView; + @BindView(R.id.top_score_text_view_item_post_comment) + TextView topScoreTextView; + @BindView(R.id.awards_text_view_item_comment) + TextView awardsTextView; + @BindView(R.id.comment_markdown_view_item_post_comment) + TextView commentMarkdownView; + @BindView(R.id.bottom_constraint_layout_item_post_comment) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.up_vote_button_item_post_comment) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_comment) + TextView scoreTextView; + @BindView(R.id.down_vote_button_item_post_comment) + ImageView downvoteButton; + @BindView(R.id.more_button_item_post_comment) + ImageView moreButton; + @BindView(R.id.save_button_item_post_comment) + ImageView saveButton; + @BindView(R.id.expand_button_item_post_comment) + ImageView expandButton; + @BindView(R.id.reply_button_item_post_comment) + ImageView replyButton; + @BindView(R.id.vertical_block_item_post_comment) + View verticalBlock; + @BindView(R.id.divider_item_comment) + View commentDivider; + + CommentViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + 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(expandButton.getId(), ConstraintSet.END); + constraintSet.clear(saveButton.getId(), ConstraintSet.END); + constraintSet.clear(replyButton.getId(), ConstraintSet.END); + constraintSet.clear(moreButton.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(moreButton.getId(), ConstraintSet.START, expandButton.getId(), ConstraintSet.END); + constraintSet.connect(expandButton.getId(), ConstraintSet.START, saveButton.getId(), ConstraintSet.END); + constraintSet.connect(saveButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); + constraintSet.connect(replyButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); + constraintSet.setHorizontalBias(moreButton.getId(), 0); + constraintSet.applyTo(bottomConstraintLayout); + } + + if (mShowCommentDivider) { + commentDivider.setBackgroundColor(mDividerColor); + commentDivider.setVisibility(View.VISIBLE); + } + + itemView.setBackgroundColor(mCommentBackgroundColor); + authorTextView.setTextColor(mUsernameColor); + commentTimeTextView.setTextColor(mSecondaryTextColor); + commentMarkdownView.setTextColor(mCommentTextColor); + authorFlairTextView.setTextColor(mAuthorFlairTextColor); + topScoreTextView.setTextColor(mSecondaryTextColor); + awardsTextView.setTextColor(mSecondaryTextColor); + commentDivider.setBackgroundColor(mDividerColor); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + authorFlairTextView.setOnClickListener(view -> authorTextView.performClick()); + + moreButton.setOnClickListener(view -> { + Comment comment = getCurrentComment(this); + if (comment != null) { + Bundle bundle = new Bundle(); + if (!mPost.isArchived() && !mPost.isLocked() && comment.getAuthor().equals(mAccountName)) { + bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true); + } + bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putParcelable(CommentMoreBottomSheetFragment.EXTRA_COMMENT, comment); + if (mIsSingleCommentThreadMode) { + bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getAdapterPosition() - 2); + } else { + bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getAdapterPosition() - 1); + } + bundle.putString(CommentMoreBottomSheetFragment.EXTRA_COMMENT_MARKDOWN, comment.getCommentMarkdown()); + bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_IS_NSFW, mPost.isNSFW()); + CommentMoreBottomSheetFragment commentMoreBottomSheetFragment = new CommentMoreBottomSheetFragment(); + commentMoreBottomSheetFragment.setArguments(bundle); + commentMoreBottomSheetFragment.show(mActivity.getSupportFragmentManager(), commentMoreBottomSheetFragment.getTag()); + } + }); + + replyButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_reply_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mPost.isLocked()) { + Toast.makeText(mActivity, R.string.locked_post_reply_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + Comment comment = getCurrentComment(this); + if (comment != null) { + Intent intent = new Intent(mActivity, CommentActivity.class); + intent.putExtra(CommentActivity.EXTRA_PARENT_DEPTH_KEY, comment.getDepth() + 1); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_MARKDOWN_KEY, comment.getCommentMarkdown()); + intent.putExtra(CommentActivity.EXTRA_COMMENT_PARENT_TEXT_KEY, comment.getCommentRawText()); + intent.putExtra(CommentActivity.EXTRA_PARENT_FULLNAME_KEY, comment.getFullName()); + intent.putExtra(CommentActivity.EXTRA_IS_REPLYING_KEY, true); + + int parentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; + intent.putExtra(CommentActivity.EXTRA_PARENT_POSITION_KEY, parentPosition); + mActivity.startActivityForResult(intent, CommentActivity.WRITE_COMMENT_REQUEST_CODE); + } + }); + + upvoteButton.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + Comment comment = getCurrentComment(this); + if (comment != null) { + int previousVoteType = comment.getVoteType(); + String newVoteType; + + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { + //Not upvoted before + comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); + newVoteType = APIUtils.DIR_UPVOTE; + upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + newVoteType = APIUtils.DIR_UNVOTE; + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position) { + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); + upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + } + + @Override + public void onVoteThingFail(int position) { + } + }, comment.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + downvoteButton.setOnClickListener(view -> { + if (mPost.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + Comment comment = getCurrentComment(this); + if (comment != null) { + int previousVoteType = comment.getVoteType(); + String newVoteType; + + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { + //Not downvoted before + comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); + newVoteType = APIUtils.DIR_DOWNVOTE; + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + newVoteType = APIUtils.DIR_UNVOTE; + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + topScoreTextView.setText(mActivity.getString(R.string.top_score, + Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType()))); + } + + @Override + public void onVoteThingFail(int position1) { + } + }, comment.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + saveButton.setOnClickListener(view -> { + Comment comment = getCurrentComment(this); + if (comment != null) { + if (comment.isSaved()) { + comment.setSaved(false); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { + @Override + public void success() { + comment.setSaved(false); + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mActivity, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + comment.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + comment.setSaved(true); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { + @Override + public void success() { + comment.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.comment_saved_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + comment.setSaved(false); + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mActivity, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + } + }); + + authorTextView.setOnClickListener(view -> { + Comment comment = getCurrentComment(this); + if (comment != null) { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, comment.getAuthor()); + mActivity.startActivity(intent); + } + }); + + expandButton.setOnClickListener(view -> { + if (expandButton.getVisibility() == View.VISIBLE) { + int commentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; + if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { + Comment comment = getCurrentComment(this); + if (comment != null) { + if (mVisibleComments.get(commentPosition).isExpanded()) { + collapseChildren(commentPosition); + expandButton.setImageResource(R.drawable.ic_expand_more_grey_24dp); + } else { + comment.setExpanded(true); + ArrayList newList = new ArrayList<>(); + expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); + mVisibleComments.get(commentPosition).setExpanded(true); + mVisibleComments.addAll(commentPosition + 1, newList); + + if (mIsSingleCommentThreadMode) { + notifyItemRangeInserted(commentPosition + 3, newList.size()); + } else { + notifyItemRangeInserted(commentPosition + 2, newList.size()); + } + expandButton.setImageResource(R.drawable.ic_expand_less_grey_24dp); + } + } + } + } else if (mFullyCollapseComment) { + int commentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; + if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { + collapseChildren(commentPosition); + } + } + }); + + commentMarkdownView.setMovementMethod(LinkMovementMethod.getInstance()); + + if (mSwapTapAndLong) { + if (mCommentToolbarHideOnClick) { + View.OnLongClickListener hideToolbarOnLongClickListener = view -> hideToolbar(); + linearLayout.setOnLongClickListener(hideToolbarOnLongClickListener); + commentMarkdownView.setOnLongClickListener(hideToolbarOnLongClickListener); + commentTimeTextView.setOnLongClickListener(hideToolbarOnLongClickListener); + } + commentMarkdownView.setOnClickListener(view -> { + if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { + expandComments(); + } + }); + itemView.setOnClickListener(view -> expandComments()); + } else { + if (mCommentToolbarHideOnClick) { + commentMarkdownView.setOnClickListener(view -> { + if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { + hideToolbar(); + } + }); + View.OnClickListener hideToolbarOnClickListener = view -> hideToolbar(); + linearLayout.setOnClickListener(hideToolbarOnClickListener); + commentTimeTextView.setOnClickListener(hideToolbarOnClickListener); + } + View.OnLongClickListener expandsCommentsOnLongClickListener = view -> expandComments(); + commentMarkdownView.setOnLongClickListener(expandsCommentsOnLongClickListener); + itemView.setOnLongClickListener(expandsCommentsOnLongClickListener); + } + commentMarkdownView.setMovementMethod(LinkMovementMethod.getInstance()); + commentMarkdownView.setHighlightColor(Color.TRANSPARENT); + } + + private boolean expandComments() { + expandButton.performClick(); + return true; + } + + private boolean hideToolbar() { + if (bottomConstraintLayout.getLayoutParams().height == 0) { + bottomConstraintLayout.getLayoutParams().height = LinearLayout.LayoutParams.WRAP_CONTENT; + topScoreTextView.setVisibility(View.GONE); + ((ViewPostDetailActivity) mActivity).delayTransition(); + } else { + ((ViewPostDetailActivity) mActivity).delayTransition(); + bottomConstraintLayout.getLayoutParams().height = 0; + topScoreTextView.setVisibility(View.VISIBLE); + } + return true; + } + } + + @Nullable + private Comment getCurrentComment(RecyclerView.ViewHolder holder) { + return getCurrentComment(holder.getAdapterPosition()); + } + + @Nullable + private Comment getCurrentComment(int position) { + if (mIsSingleCommentThreadMode) { + if (position - 2 >= 0 && position - 2 < mVisibleComments.size()) { + return mVisibleComments.get(position - 2); + } + } else { + if (position - 1 >= 0 && position - 1 < mVisibleComments.size()) { + return mVisibleComments.get(position - 1); + } + } + + return null; + } + + class CommentFullyCollapsedViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.vertical_block_item_comment_fully_collapsed) + View verticalBlock; + @BindView(R.id.user_name_text_view_item_comment_fully_collapsed) + TextView usernameTextView; + @BindView(R.id.score_text_view_item_comment_fully_collapsed) + TextView scoreTextView; + @BindView(R.id.time_text_view_item_comment_fully_collapsed) + TextView commentTimeTextView; + @BindView(R.id.divider_item_comment_fully_collapsed) + View commentDivider; + + public CommentFullyCollapsedViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + itemView.setBackgroundColor(mFullyCollapsedCommentBackgroundColor); + usernameTextView.setTextColor(mUsernameColor); + scoreTextView.setTextColor(mSecondaryTextColor); + commentTimeTextView.setTextColor(mSecondaryTextColor); + + if (mShowCommentDivider) { + commentDivider.setBackgroundColor(mDividerColor); + commentDivider.setVisibility(View.VISIBLE); + } + + itemView.setOnClickListener(view -> { + int commentPosition = mIsSingleCommentThreadMode ? getAdapterPosition() - 2 : getAdapterPosition() - 1; + if (commentPosition >= 0 && commentPosition < mVisibleComments.size()) { + Comment comment = getCurrentComment(this); + if (comment != null) { + comment.setExpanded(true); + ArrayList newList = new ArrayList<>(); + expandChildren(mVisibleComments.get(commentPosition).getChildren(), newList, 0); + mVisibleComments.get(commentPosition).setExpanded(true); + mVisibleComments.addAll(commentPosition + 1, newList); + + if (mIsSingleCommentThreadMode) { + notifyItemChanged(commentPosition + 2); + notifyItemRangeInserted(commentPosition + 3, newList.size()); + } else { + notifyItemChanged(commentPosition + 1); + notifyItemRangeInserted(commentPosition + 2, newList.size()); + } + } + } + }); + + itemView.setOnLongClickListener(view -> { + itemView.performClick(); + return true; + }); + } + } + + class LoadMoreChildCommentsViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.vertical_block_item_load_more_comments) + View verticalBlock; + @BindView(R.id.placeholder_text_view_item_load_more_comments) + TextView placeholderTextView; + @BindView(R.id.divider_item_load_more_comments_placeholder) + View commentDivider; + + LoadMoreChildCommentsViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + if (mShowCommentDivider) { + commentDivider.setVisibility(View.VISIBLE); + } + + itemView.setBackgroundColor(mCommentBackgroundColor); + placeholderTextView.setTextColor(mPrimaryTextColor); + commentDivider.setBackgroundColor(mDividerColor); + } + } + + class LoadCommentsViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.comment_progress_bar_item_load_comments) + CircleProgressBar circleProgressBar; + + LoadCommentsViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + circleProgressBar.setBackgroundTintList(ColorStateList.valueOf(mCircularProgressBarBackgroundColor)); + circleProgressBar.setColorSchemeColors(mColorAccent); + } + } + + class LoadCommentsFailedViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_load_comments_failed_placeholder) + TextView errorTextView; + + LoadCommentsFailedViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + itemView.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingComments()); + errorTextView.setTextColor(mSecondaryTextColor); + } + } + + class NoCommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_no_comment_placeholder) + TextView errorTextView; + + NoCommentViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + errorTextView.setTextColor(mSecondaryTextColor); + } + } + + class IsLoadingMoreCommentsViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_comment_footer_loading) + ProgressBar progressbar; + + IsLoadingMoreCommentsViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + progressbar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + } + } + + class LoadMoreCommentsFailedViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_comment_footer_error) + TextView errorTextView; + @BindView(R.id.retry_button_item_comment_footer_error) + Button retryButton; + + LoadMoreCommentsFailedViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + errorTextView.setText(R.string.load_comments_failed); + retryButton.setOnClickListener(view -> mCommentRecyclerViewAdapterCallback.retryFetchingMoreComments()); + errorTextView.setTextColor(mSecondaryTextColor); + retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); + retryButton.setTextColor(mButtonTextColor); + } + } + + class ViewAllCommentsViewHolder extends RecyclerView.ViewHolder { + + ViewAllCommentsViewHolder(@NonNull View itemView) { + super(itemView); + + itemView.setOnClickListener(view -> { + if (mActivity != null && mActivity instanceof ViewPostDetailActivity) { + mIsSingleCommentThreadMode = false; + mSingleCommentId = null; + ((ViewPostDetailActivity) mActivity).changeToNomalThreadMode(); + } + }); + + itemView.setBackgroundTintList(ColorStateList.valueOf(mCommentBackgroundColor)); + ((TextView) itemView).setTextColor(mColorAccent); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java new file mode 100644 index 00000000..fad4476f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CommentsListingRecyclerViewAdapter.java @@ -0,0 +1,730 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.net.Uri; +import android.os.Bundle; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +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; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.constraintlayout.widget.ConstraintSet; +import androidx.paging.PagedListAdapter; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CommentMoreBottomSheetFragment; +import ml.docilealligator.infinityforreddit.comment.Comment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SaveThing; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import ml.docilealligator.infinityforreddit.VoteThing; +import retrofit2.Retrofit; + +public class CommentsListingRecyclerViewAdapter extends PagedListAdapter { + private static final int VIEW_TYPE_DATA = 0; + private static final int VIEW_TYPE_ERROR = 1; + private static final int VIEW_TYPE_LOADING = 2; + private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull Comment comment, @NonNull Comment t1) { + return comment.getId().equals(t1.getId()); + } + + @Override + public boolean areContentsTheSame(@NonNull Comment comment, @NonNull Comment t1) { + return comment.getCommentMarkdown().equals(t1.getCommentMarkdown()); + } + }; + private Context mContext; + private Retrofit mOauthRetrofit; + private Locale mLocale; + private Markwon mMarkwon; + private String mAccessToken; + private String mAccountName; + private int mColorPrimaryLightTheme; + private int mSecondaryTextColor; + private int mCommentBackgroundColor; + private int mCommentColor; + private int mDividerColor; + private int mUsernameColor; + private int mAuthorFlairColor; + private int mSubredditColor; + private int mUpvotedColor; + private int mDownvotedColor; + private int mButtonTextColor; + private int mColorAccent; + private int mCommentIconAndInfoColor; + private boolean mVoteButtonsOnTheRight; + private boolean mShowElapsedTime; + private String mTimeFormatPattern; + private boolean mShowCommentDivider; + private boolean mShowAbsoluteNumberOfVotes; + private NetworkState networkState; + private RetryLoadingMoreCallback mRetryLoadingMoreCallback; + + public CommentsListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, + CustomThemeWrapper customThemeWrapper, Locale locale, + SharedPreferences sharedPreferences, String accessToken, + String accountName, RetryLoadingMoreCallback retryLoadingMoreCallback) { + super(DIFF_CALLBACK); + mContext = context; + mOauthRetrofit = oauthRetrofit; + mCommentColor = customThemeWrapper.getCommentColor(); + int commentSpoilerBackgroundColor = mCommentColor | 0xFF000000; + mMarkwon = Markwon.builder(mContext) + .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + StringBuilder markdownStringBuilder = new StringBuilder(markdown); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + while (matcher.find()) { + markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); + } + return super.processMarkdown(markdownStringBuilder.toString()); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + textView.setHighlightColor(Color.TRANSPARENT); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + int matcherStart = matcher.start(); + int matcherEnd = matcher.end(); + ClickableSpan clickableSpan = new ClickableSpan() { + private boolean isShowing = false; + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + ds.setColor(mCommentColor); + } else { + ds.bgColor = commentSpoilerBackgroundColor; + ds.setColor(mCommentColor); + } + ds.setUnderlineText(false); + } + + @Override + public void onClick(@NonNull View view) { + isShowing = !isShowing; + view.invalidate(); + } + }; + markdownStringBuilder.setSpan(clickableSpan, matcherStart, matcherEnd - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcherEnd - 4; + } + if (find) { + textView.setText(markdownStringBuilder); + } + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(customThemeWrapper.getLinkColor()); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mContext, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + mContext.startActivity(intent); + }); + + } + }) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .build(); + mLocale = locale; + mAccessToken = accessToken; + mAccountName = accountName; + mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); + mShowCommentDivider = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_COMMENT_DIVIDER, false); + mShowAbsoluteNumberOfVotes = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES, true); + mVoteButtonsOnTheRight = sharedPreferences.getBoolean(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY, false); + mTimeFormatPattern = sharedPreferences.getString(SharedPreferencesUtils.TIME_FORMAT_KEY, SharedPreferencesUtils.TIME_FORMAT_DEFAULT_VALUE); + mRetryLoadingMoreCallback = retryLoadingMoreCallback; + mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + mCommentBackgroundColor = customThemeWrapper.getCommentBackgroundColor(); + mCommentColor = customThemeWrapper.getCommentColor(); + mDividerColor = customThemeWrapper.getDividerColor(); + mSubredditColor = customThemeWrapper.getSubreddit(); + mUsernameColor = customThemeWrapper.getUsername(); + mAuthorFlairColor = customThemeWrapper.getAuthorFlairTextColor(); + mUpvotedColor = customThemeWrapper.getUpvoted(); + mDownvotedColor = customThemeWrapper.getDownvoted(); + mButtonTextColor = customThemeWrapper.getButtonTextColor(); + mColorAccent = customThemeWrapper.getColorAccent(); + mCommentIconAndInfoColor = customThemeWrapper.getCommentIconAndInfoColor(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_DATA) { + return new CommentViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false)); + } else if (viewType == VIEW_TYPE_ERROR) { + return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false)); + } else { + return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof CommentViewHolder) { + Comment comment = getItem(holder.getAdapterPosition()); + if (comment != null) { + if (comment.getSubredditName().substring(2).equals(comment.getLinkAuthor())) { + String name = "u/" + comment.getLinkAuthor(); + ((CommentViewHolder) holder).authorTextView.setText(name); + ((CommentViewHolder) holder).authorTextView.setTextColor(mUsernameColor); + } else { + String name = "r/" + comment.getSubredditName(); + ((CommentViewHolder) holder).authorTextView.setText(name); + ((CommentViewHolder) holder).authorTextView.setTextColor(mSubredditColor); + } + + if (comment.getAuthorFlairHTML() != null && !comment.getAuthorFlairHTML().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).authorFlairTextView, comment.getAuthorFlairHTML(), true); + } else if (comment.getAuthorFlair() != null && !comment.getAuthorFlair().equals("")) { + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.VISIBLE); + ((CommentViewHolder) holder).authorFlairTextView.setText(comment.getAuthorFlair()); + } + + if (mShowElapsedTime) { + ((CommentViewHolder) holder).commentTimeTextView.setText( + Utils.getElapsedTime(mContext, comment.getCommentTimeMillis())); + } else { + ((CommentViewHolder) holder).commentTimeTextView.setText(Utils.getFormattedTime(mLocale, comment.getCommentTimeMillis(), mTimeFormatPattern)); + } + + if (comment.getAwards() != null && !comment.getAwards().equals("")) { + ((CommentViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((CommentViewHolder) holder).awardsTextView, comment.getAwards(), true); + } + + mMarkwon.setMarkdown(((CommentViewHolder) holder).commentMarkdownView, comment.getCommentMarkdown()); + + ((CommentViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + + switch (comment.getVoteType()) { + case Comment.VOTE_TYPE_UPVOTE: + ((CommentViewHolder) holder).upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + break; + case Comment.VOTE_TYPE_DOWNVOTE: + ((CommentViewHolder) holder).downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + break; + } + + ((CommentViewHolder) holder).verticalBlock.setVisibility(View.GONE); + + if (comment.isSaved()) { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + } else { + ((CommentViewHolder) holder).saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + } + } + } + } + + @Override + public int getItemViewType(int position) { + // Reached at the end + if (hasExtraRow() && position == getItemCount() - 1) { + if (networkState.getStatus() == NetworkState.Status.LOADING) { + return VIEW_TYPE_LOADING; + } else { + return VIEW_TYPE_ERROR; + } + } else { + return VIEW_TYPE_DATA; + } + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if (holder instanceof CommentViewHolder) { + ((CommentViewHolder) holder).authorFlairTextView.setText(""); + ((CommentViewHolder) holder).authorFlairTextView.setVisibility(View.GONE); + ((CommentViewHolder) holder).awardsTextView.setText(""); + ((CommentViewHolder) holder).awardsTextView.setVisibility(View.GONE); + ((CommentViewHolder) holder).upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((CommentViewHolder) holder).scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + } + + @Override + public int getItemCount() { + if (hasExtraRow()) { + return super.getItemCount() + 1; + } + return super.getItemCount(); + } + + private boolean hasExtraRow() { + return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; + } + + public void setNetworkState(NetworkState newNetworkState) { + NetworkState previousState = this.networkState; + boolean previousExtraRow = hasExtraRow(); + this.networkState = newNetworkState; + boolean newExtraRow = hasExtraRow(); + if (previousExtraRow != newExtraRow) { + if (previousExtraRow) { + notifyItemRemoved(super.getItemCount()); + } else { + notifyItemInserted(super.getItemCount()); + } + } else if (newExtraRow && !previousState.equals(newNetworkState)) { + notifyItemChanged(getItemCount() - 1); + } + } + + public void onItemSwipe(RecyclerView.ViewHolder viewHolder, int direction, int swipeLeftAction, int swipeRightAction) { + if (viewHolder instanceof CommentViewHolder) { + if (direction == ItemTouchHelper.LEFT || direction == ItemTouchHelper.START) { + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((CommentViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((CommentViewHolder) viewHolder).downvoteButton.performClick(); + } + } else { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + ((CommentViewHolder) viewHolder).upvoteButton.performClick(); + } else if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + ((CommentViewHolder) viewHolder).downvoteButton.performClick(); + } + } + } + } + + public void giveAward(String awardsHTML, int position) { + if (position >= 0 && position < getItemCount()) { + Comment comment = getItem(position); + if (comment != null) { + comment.addAwards(awardsHTML); + notifyItemChanged(position); + } + } + } + + public void editComment(String commentContentMarkdown, int position) { + Comment comment = getItem(position); + if (comment != null) { + comment.setCommentMarkdown(commentContentMarkdown); + notifyItemChanged(position); + } + } + + public interface RetryLoadingMoreCallback { + void retryLoadingMore(); + } + + public class CommentViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.linear_layout_item_comment) + LinearLayout linearLayout; + @BindView(R.id.vertical_block_item_post_comment) + View verticalBlock; + @BindView(R.id.author_text_view_item_post_comment) + TextView authorTextView; + @BindView(R.id.author_flair_text_view_item_post_comment) + TextView authorFlairTextView; + @BindView(R.id.comment_time_text_view_item_post_comment) + TextView commentTimeTextView; + @BindView(R.id.awards_text_view_item_comment) + TextView awardsTextView; + @BindView(R.id.comment_markdown_view_item_post_comment) + TextView commentMarkdownView; + @BindView(R.id.bottom_constraint_layout_item_post_comment) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.up_vote_button_item_post_comment) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_comment) + TextView scoreTextView; + @BindView(R.id.down_vote_button_item_post_comment) + ImageView downvoteButton; + @BindView(R.id.more_button_item_post_comment) + ImageView moreButton; + @BindView(R.id.save_button_item_post_comment) + ImageView saveButton; + @BindView(R.id.expand_button_item_post_comment) + ImageView expandButton; + @BindView(R.id.reply_button_item_post_comment) + ImageView replyButton; + @BindView(R.id.divider_item_comment) + View commentDivider; + + CommentViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + replyButton.setVisibility(View.GONE); + + 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(expandButton.getId(), ConstraintSet.END); + constraintSet.clear(replyButton.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(saveButton.getId(), ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START); + constraintSet.connect(moreButton.getId(), ConstraintSet.START, saveButton.getId(), ConstraintSet.END); + constraintSet.connect(moreButton.getId(), ConstraintSet.END, upvoteButton.getId(), ConstraintSet.END); + constraintSet.connect(expandButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); + constraintSet.connect(replyButton.getId(), ConstraintSet.START, replyButton.getId(), ConstraintSet.END); + constraintSet.setHorizontalBias(moreButton.getId(), 0); + constraintSet.applyTo(bottomConstraintLayout); + } + + if (mShowCommentDivider) { + commentDivider.setVisibility(View.VISIBLE); + } + + itemView.setBackgroundColor(mCommentBackgroundColor); + authorTextView.setTextColor(mUsernameColor); + authorFlairTextView.setTextColor(mAuthorFlairColor); + commentTimeTextView.setTextColor(mSecondaryTextColor); + awardsTextView.setTextColor(mSecondaryTextColor); + commentMarkdownView.setTextColor(mCommentColor); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + moreButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + expandButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + saveButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + replyButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + commentDivider.setBackgroundColor(mDividerColor); + + commentMarkdownView.setMovementMethod(LinkMovementMethod.getInstance()); + + authorTextView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Comment comment = getItem(getAdapterPosition()); + if (comment != null) { + if (comment.getSubredditName().substring(2).equals(comment.getLinkAuthor())) { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, comment.getLinkAuthor()); + mContext.startActivity(intent); + } else { + Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, comment.getSubredditName()); + mContext.startActivity(intent); + } + } + }); + + moreButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Comment comment = getItem(getAdapterPosition()); + if (comment != null) { + Bundle bundle = new Bundle(); + if (comment.getAuthor().equals(mAccountName)) { + bundle.putBoolean(CommentMoreBottomSheetFragment.EXTRA_EDIT_AND_DELETE_AVAILABLE, true); + } + bundle.putString(CommentMoreBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putParcelable(CommentMoreBottomSheetFragment.EXTRA_COMMENT, comment); + bundle.putInt(CommentMoreBottomSheetFragment.EXTRA_POSITION, getAdapterPosition()); + bundle.putString(CommentMoreBottomSheetFragment.EXTRA_COMMENT_MARKDOWN, comment.getCommentMarkdown()); + CommentMoreBottomSheetFragment commentMoreBottomSheetFragment = new CommentMoreBottomSheetFragment(); + commentMoreBottomSheetFragment.setArguments(bundle); + commentMoreBottomSheetFragment.show(((AppCompatActivity) mContext).getSupportFragmentManager(), commentMoreBottomSheetFragment.getTag()); + } + }); + + linearLayout.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Comment comment = getItem(getAdapterPosition()); + if (comment != null) { + Intent intent = new Intent(mContext, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_ID, comment.getLinkId()); + intent.putExtra(ViewPostDetailActivity.EXTRA_SINGLE_COMMENT_ID, comment.getId()); + mContext.startActivity(intent); + } + }); + + commentMarkdownView.setOnClickListener(view -> { + if (commentMarkdownView.getSelectionStart() == -1 && commentMarkdownView.getSelectionEnd() == -1) { + linearLayout.callOnClick(); + } + }); + + upvoteButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Comment comment = getItem(getAdapterPosition()); + if (comment != null) { + int previousVoteType = comment.getVoteType(); + String newVoteType; + + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != Comment.VOTE_TYPE_UPVOTE) { + //Not upvoted before + comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); + newVoteType = APIUtils.DIR_UPVOTE; + upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + newVoteType = APIUtils.DIR_UNVOTE; + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + + VoteThing.voteThing(mContext, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position) { + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + comment.setVoteType(Comment.VOTE_TYPE_UPVOTE); + upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + } + + @Override + public void onVoteThingFail(int position) { + } + }, comment.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + downvoteButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mContext, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Comment comment = getItem(getAdapterPosition()); + if (comment != null) { + int previousVoteType = comment.getVoteType(); + String newVoteType; + + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != Comment.VOTE_TYPE_DOWNVOTE) { + //Not downvoted before + comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); + newVoteType = APIUtils.DIR_DOWNVOTE; + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + newVoteType = APIUtils.DIR_UNVOTE; + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + + VoteThing.voteThing(mContext, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + comment.setVoteType(Comment.VOTE_TYPE_DOWNVOTE); + downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + comment.setVoteType(Comment.VOTE_TYPE_NO_VOTE); + downvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mCommentIconAndInfoColor); + } + + upvoteButton.setColorFilter(mCommentIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, + comment.getScore() + comment.getVoteType())); + } + + @Override + public void onVoteThingFail(int position1) { + } + }, comment.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + saveButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Comment comment = getItem(getAdapterPosition()); + if (comment != null) { + if (comment.isSaved()) { + comment.setSaved(false); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { + @Override + public void success() { + comment.setSaved(false); + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mContext, R.string.comment_unsaved_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + comment.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mContext, R.string.comment_unsaved_failed, Toast.LENGTH_SHORT).show(); + } + }); + } else { + comment.setSaved(true); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, comment.getFullName(), new SaveThing.SaveThingListener() { + @Override + public void success() { + comment.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mContext, R.string.comment_saved_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void failed() { + comment.setSaved(false); + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + Toast.makeText(mContext, R.string.comment_saved_failed, Toast.LENGTH_SHORT).show(); + } + }); + } + } + }); + } + } + + class ErrorViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_footer_error) + TextView errorTextView; + @BindView(R.id.retry_button_item_footer_error) + Button retryButton; + + ErrorViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + errorTextView.setText(R.string.load_comments_failed); + retryButton.setOnClickListener(view -> mRetryLoadingMoreCallback.retryLoadingMore()); + errorTextView.setTextColor(mSecondaryTextColor); + retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); + retryButton.setTextColor(mButtonTextColor); + } + } + + class LoadingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_footer_loading) + ProgressBar progressBar; + + LoadingViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomThemeListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomThemeListingRecyclerViewAdapter.java new file mode 100644 index 00000000..127c6955 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomThemeListingRecyclerViewAdapter.java @@ -0,0 +1,170 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Intent; +import android.content.res.ColorStateList; +import android.os.Bundle; +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.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.CustomThemeListingActivity; +import ml.docilealligator.infinityforreddit.activities.CustomizeThemeActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.CustomThemeOptionsBottomSheetFragment; +import ml.docilealligator.infinityforreddit.R; + +public class CustomThemeListingRecyclerViewAdapter extends RecyclerView.Adapter { + private static final int VIEW_TYPE_PREDEFINED_THEME = 0; + private static final int VIEW_TYPE_USER_THME = 1; + private static final int VIEW_TYPE_PREDEFINED_THEME_DIVIDER = 2; + private static final int VIEW_TYPE_USER_THEME_DIVIDER = 3; + + private AppCompatActivity activity; + private ArrayList predefinedCustomThemes; + private ArrayList userCustomThemes; + + public CustomThemeListingRecyclerViewAdapter(AppCompatActivity activity, ArrayList predefinedCustomThemes) { + this.activity = activity; + this.predefinedCustomThemes = predefinedCustomThemes; + userCustomThemes = new ArrayList<>(); + } + + @Override + public int getItemViewType(int position) { + if (position == 0) { + return VIEW_TYPE_PREDEFINED_THEME_DIVIDER; + } else if (position < 1 + predefinedCustomThemes.size()) { + return VIEW_TYPE_PREDEFINED_THEME; + } else if (position == 1 + predefinedCustomThemes.size()) { + return VIEW_TYPE_USER_THEME_DIVIDER; + } else { + return VIEW_TYPE_USER_THME; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_PREDEFINED_THEME_DIVIDER: + return new PreDefinedThemeDividerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_theme_type_divider, parent, false)); + case VIEW_TYPE_PREDEFINED_THEME: + return new PredefinedCustomThemeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_predefined_custom_theme, parent, false)); + case VIEW_TYPE_USER_THEME_DIVIDER: + return new UserThemeDividerViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_theme_type_divider, parent, false)); + default: + return new UserCustomThemeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_custom_theme, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof PredefinedCustomThemeViewHolder) { + CustomTheme customTheme = predefinedCustomThemes.get(position - 1); + ((PredefinedCustomThemeViewHolder) holder).colorPrimaryView.setBackgroundTintList(ColorStateList.valueOf(customTheme.colorPrimary)); + ((PredefinedCustomThemeViewHolder) holder).nameTextView.setText(customTheme.name); + ((PredefinedCustomThemeViewHolder) holder).itemView.setOnClickListener(view -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, customTheme.name); + intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); + intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); + activity.startActivity(intent); + }); + } else if (holder instanceof UserCustomThemeViewHolder) { + CustomTheme customTheme = userCustomThemes.get(position - predefinedCustomThemes.size() - 2); + ((UserCustomThemeViewHolder) holder).colorPrimaryView.setBackgroundTintList(ColorStateList.valueOf(customTheme.colorPrimary)); + ((UserCustomThemeViewHolder) holder).nameTextView.setText(customTheme.name); + ((UserCustomThemeViewHolder) holder).createThemeImageView.setOnClickListener(view -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, customTheme.name); + intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); + activity.startActivity(intent); + }); + ((UserCustomThemeViewHolder) holder).shareImageView.setOnClickListener(view -> { + ((CustomThemeListingActivity) activity).shareTheme(customTheme); + }); + ((UserCustomThemeViewHolder) holder).itemView.setOnClickListener(view -> { + CustomThemeOptionsBottomSheetFragment customThemeOptionsBottomSheetFragment = new CustomThemeOptionsBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(CustomThemeOptionsBottomSheetFragment.EXTRA_THEME_NAME, customTheme.name); + customThemeOptionsBottomSheetFragment.setArguments(bundle); + customThemeOptionsBottomSheetFragment.show(activity.getSupportFragmentManager(), customThemeOptionsBottomSheetFragment.getTag()); + }); + ((UserCustomThemeViewHolder) holder).itemView.setOnLongClickListener(view -> { + ((UserCustomThemeViewHolder) holder).itemView.performClick(); + return true; + }); + } else if (holder instanceof PreDefinedThemeDividerViewHolder) { + ((TextView) ((PreDefinedThemeDividerViewHolder) holder).itemView).setText(R.string.predefined_themes); + } else if (holder instanceof UserThemeDividerViewHolder) { + ((TextView) ((UserThemeDividerViewHolder) holder).itemView).setText(R.string.user_themes); + } + } + + @Override + public int getItemCount() { + return predefinedCustomThemes.size() + userCustomThemes.size() + 2; + } + + public void setUserThemes(List userThemes) { + userCustomThemes = (ArrayList) userThemes; + notifyDataSetChanged(); + } + + class PredefinedCustomThemeViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.color_primary_item_predefined_custom_theme) + View colorPrimaryView; + @BindView(R.id.name_text_view_item_predefined_custom_theme) + TextView nameTextView; + @BindView(R.id.add_image_view_item_predefined_custom_theme) + ImageView createThemeImageView; + + PredefinedCustomThemeViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + + class UserCustomThemeViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.color_primary_item_user_custom_theme) + View colorPrimaryView; + @BindView(R.id.name_text_view_item_user_custom_theme) + TextView nameTextView; + @BindView(R.id.add_image_view_item_user_custom_theme) + ImageView createThemeImageView; + @BindView(R.id.share_image_view_item_user_custom_theme) + ImageView shareImageView; + + UserCustomThemeViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + + class PreDefinedThemeDividerViewHolder extends RecyclerView.ViewHolder { + + PreDefinedThemeDividerViewHolder(@NonNull View itemView) { + super(itemView); + } + } + + class UserThemeDividerViewHolder extends RecyclerView.ViewHolder { + + UserThemeDividerViewHolder(@NonNull View itemView) { + super(itemView); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomizeThemeRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomizeThemeRecyclerViewAdapter.java new file mode 100644 index 00000000..eb8189dd --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/CustomizeThemeRecyclerViewAdapter.java @@ -0,0 +1,178 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.Switch; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeSettingsItem; +import ml.docilealligator.infinityforreddit.customviews.ColorPickerDialog; +import ml.docilealligator.infinityforreddit.R; + +public class CustomizeThemeRecyclerViewAdapter extends RecyclerView.Adapter { + private static final int VIEW_TYPE_COLOR = 1; + private static final int VIEW_TYPE_SWITCH = 2; + private static final int VIEW_TYPE_THEME_NAME = 3; + private AppCompatActivity activity; + private ArrayList customThemeSettingsItems; + private String themeName; + private boolean isPredefinedTheme; + + public CustomizeThemeRecyclerViewAdapter(AppCompatActivity activity, String themeName, + boolean isPredefinedTheme) { + this.activity = activity; + customThemeSettingsItems = new ArrayList<>(); + this.themeName = themeName; + this.isPredefinedTheme = isPredefinedTheme; + } + + @Override + public int getItemViewType(int position) { + if (position == 0) { + return VIEW_TYPE_THEME_NAME; + } else if (position > 3 && position < customThemeSettingsItems.size() - 2) { + return VIEW_TYPE_COLOR; + } + + return VIEW_TYPE_SWITCH; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_SWITCH) { + return new ThemeSwitchItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_custom_theme_switch_item, parent, false)); + } else if (viewType == VIEW_TYPE_THEME_NAME) { + return new ThemeNameItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_theme_name, parent, false)); + } + + return new ThemeColorItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_custom_theme_color_item, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof ThemeColorItemViewHolder) { + CustomThemeSettingsItem customThemeSettingsItem = customThemeSettingsItems.get(position - 1); + ((ThemeColorItemViewHolder) holder).themeItemNameTextView.setText(customThemeSettingsItem.itemName); + ((ThemeColorItemViewHolder) holder).themeItemInfoTextView.setText(customThemeSettingsItem.itemDetails); + ((ThemeColorItemViewHolder) holder).colorImageView.setBackgroundTintList(ColorStateList.valueOf(customThemeSettingsItem.colorValue)); + holder.itemView.setOnClickListener(view -> { + new ColorPickerDialog(activity, customThemeSettingsItem.colorValue, color -> { + customThemeSettingsItem.colorValue = color; + ((ThemeColorItemViewHolder) holder).colorImageView.setBackgroundTintList(ColorStateList.valueOf(color)); + }).show(); + }); + } else if (holder instanceof ThemeSwitchItemViewHolder) { + CustomThemeSettingsItem customThemeSettingsItem = customThemeSettingsItems.get(position - 1); + ((ThemeSwitchItemViewHolder) holder).themeItemNameTextView.setText(customThemeSettingsItem.itemName); + ((ThemeSwitchItemViewHolder) holder).themeItemInfoTextView.setText(customThemeSettingsItem.itemName); + ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.setChecked(customThemeSettingsItem.isEnabled); + ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.setOnClickListener(view -> customThemeSettingsItem.isEnabled = ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.isChecked()); + holder.itemView.setOnClickListener(view -> ((ThemeSwitchItemViewHolder) holder).themeItemSwitch.performClick()); + } else if (holder instanceof ThemeNameItemViewHolder) { + ((ThemeNameItemViewHolder) holder).themeNameTextView.setText(themeName); + holder.itemView.setOnClickListener(view -> { + View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_edit_theme_name, null); + EditText themeNameEditText = dialogView.findViewById(R.id.theme_name_edit_text_edit_theme_name_dialog); + themeNameEditText.setText(themeName); + themeNameEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.edit_theme_name) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); + } + themeName = themeNameEditText.getText().toString(); + ((ThemeNameItemViewHolder) holder).themeNameTextView.setText(themeName); + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); + } + }) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(themeNameEditText.getWindowToken(), 0); + } + }) + .show(); + }); + } + } + + @Override + public int getItemCount() { + return customThemeSettingsItems.size() + 1; + } + + public void setCustomThemeSettingsItem(ArrayList customThemeSettingsItems) { + this.customThemeSettingsItems.clear(); + notifyDataSetChanged(); + this.customThemeSettingsItems.addAll(customThemeSettingsItems); + notifyDataSetChanged(); + } + + public String getThemeName() { + return themeName; + } + + class ThemeColorItemViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.color_image_view_item_custom_theme_color_item) + View colorImageView; + @BindView(R.id.theme_item_name_text_view_item_custom_theme_color_item) + TextView themeItemNameTextView; + @BindView(R.id.theme_item_info_text_view_item_custom_theme_color_item) + TextView themeItemInfoTextView; + + ThemeColorItemViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + + class ThemeSwitchItemViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.theme_item_name_text_view_item_custom_theme_switch_item) + TextView themeItemNameTextView; + @BindView(R.id.theme_item_info_text_view_item_custom_theme_switch_item) + TextView themeItemInfoTextView; + @BindView(R.id.theme_item_switch_item_custom_theme_switch_item) + Switch themeItemSwitch; + + ThemeSwitchItemViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + + class ThemeNameItemViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.theme_name_text_view_item_theme_name) + TextView themeNameTextView; + @BindView(R.id.description_text_view_item_theme_name) + TextView descriptionTextView; + public ThemeNameItemViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java new file mode 100644 index 00000000..4585c95e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FlairBottomSheetRecyclerViewAdapter.java @@ -0,0 +1,114 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.app.Activity; +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.R; + +public class FlairBottomSheetRecyclerViewAdapter extends RecyclerView.Adapter { + private Context context; + private ArrayList flairs; + private int flairTextColor; + private ItemClickListener itemClickListener; + + public FlairBottomSheetRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper, + ItemClickListener itemClickListener) { + this.context = context; + flairTextColor = customThemeWrapper.getPrimaryTextColor(); + this.itemClickListener = itemClickListener; + } + + @NonNull + @Override + public FlairViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new FlairViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_flair, null, false)); + } + + @Override + public void onBindViewHolder(@NonNull FlairViewHolder holder, int position) { + if (flairs.get(holder.getAdapterPosition()).isEditable()) { + holder.editFlairImageView.setVisibility(View.VISIBLE); + holder.editFlairImageView.setOnClickListener(view -> { + View dialogView = ((Activity) context).getLayoutInflater().inflate(R.layout.dialog_edit_flair, null); + EditText flairEditText = dialogView.findViewById(R.id.flair_edit_text_edit_flair_dialog); + flairEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(context, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.edit_flair) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + Flair flair = flairs.get(holder.getAdapterPosition()); + flair.setText(flairEditText.getText().toString()); + itemClickListener.onClick(flair); + }) + .setNegativeButton(R.string.cancel, null) + .show(); + }); + } + + if (flairs.get(holder.getAdapterPosition()).isEditable() && flairs.get(holder.getAdapterPosition()).getText().equals("")) { + holder.itemView.setOnClickListener(view -> holder.editFlairImageView.performClick()); + } else { + holder.itemView.setOnClickListener(view -> itemClickListener.onClick(flairs.get(holder.getAdapterPosition()))); + } + + holder.flairTextView.setText(flairs.get(holder.getAdapterPosition()).getText()); + } + + @Override + public int getItemCount() { + return flairs == null ? 0 : flairs.size(); + } + + @Override + public void onViewRecycled(@NonNull FlairViewHolder holder) { + super.onViewRecycled(holder); + holder.editFlairImageView.setVisibility(View.GONE); + } + + public void changeDataset(ArrayList flairs) { + this.flairs = flairs; + notifyDataSetChanged(); + } + + public interface ItemClickListener { + void onClick(Flair flair); + } + + class FlairViewHolder extends RecyclerView.ViewHolder { + View itemView; + @BindView(R.id.flair_text_view_item_flair) + TextView flairTextView; + @BindView(R.id.edit_flair_image_view_item_flair) + ImageView editFlairImageView; + + FlairViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + this.itemView = itemView; + flairTextView.setTextColor(flairTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FollowedUsersRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FollowedUsersRecyclerViewAdapter.java new file mode 100644 index 00000000..05c85ed1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/FollowedUsersRecyclerViewAdapter.java @@ -0,0 +1,359 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import me.zhanghai.android.fastscroll.PopupTextProvider; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FavoriteThing; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class FollowedUsersRecyclerViewAdapter extends RecyclerView.Adapter implements PopupTextProvider { + private static final int VIEW_TYPE_FAVORITE_USER_DIVIDER = 0; + private static final int VIEW_TYPE_FAVORITE_USER = 1; + private static final int VIEW_TYPE_USER_DIVIDER = 2; + private static final int VIEW_TYPE_USER = 3; + + private List mSubscribedUserData; + private List mFavoriteSubscribedUserData; + private Context mContext; + private Retrofit mOauthRetrofit; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private String mAccessToken; + private RequestManager glide; + private int mPrimaryTextColor; + private int mSecondaryTextColor; + + public FollowedUsersRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, + RedditDataRoomDatabase redditDataRoomDatabase, + CustomThemeWrapper customThemeWrapper, + String accessToken) { + mContext = context; + mOauthRetrofit = oauthRetrofit; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mAccessToken = accessToken; + glide = Glide.with(context); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + } + + @Override + public int getItemViewType(int position) { + if (mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) { + if (position == 0) { + return VIEW_TYPE_FAVORITE_USER_DIVIDER; + } else if (position == mFavoriteSubscribedUserData.size() + 1) { + return VIEW_TYPE_USER_DIVIDER; + } else if (position <= mFavoriteSubscribedUserData.size()) { + return VIEW_TYPE_FAVORITE_USER; + } else { + return VIEW_TYPE_USER; + } + } else { + return VIEW_TYPE_USER; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + switch (i) { + case VIEW_TYPE_FAVORITE_USER_DIVIDER: + return new FavoriteUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); + case VIEW_TYPE_FAVORITE_USER: + return new FavoriteUserViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_subscribed_thing, viewGroup, false)); + case VIEW_TYPE_USER_DIVIDER: + return new AllUsersDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); + default: + return new UserViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_subscribed_thing, viewGroup, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) { + if (viewHolder instanceof UserViewHolder) { + int offset = (mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) ? + mFavoriteSubscribedUserData.size() + 2 : 0; + + viewHolder.itemView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getName()); + mContext.startActivity(intent); + }); + if (!mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getIconUrl().equals("")) { + glide.load(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((UserViewHolder) viewHolder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((UserViewHolder) viewHolder).iconGifImageView); + } + ((UserViewHolder) viewHolder).userNameTextView.setText(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).getName()); + + if(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } else { + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + ((UserViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { + if(mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).setFavorite(false); + FavoriteThing.unfavoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, + mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(false); + } + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(true); + } + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + }); + } else { + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset).setFavorite(true); + FavoriteThing.favoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, + mSubscribedUserData.get(viewHolder.getAdapterPosition() - offset), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(true); + } + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(false); + } + ((UserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + }); + } + }); + } else if (viewHolder instanceof FavoriteUserViewHolder) { + viewHolder.itemView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getName()); + mContext.startActivity(intent); + }); + if (!mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getIconUrl().equals("")) { + glide.load(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((FavoriteUserViewHolder) viewHolder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((FavoriteUserViewHolder) viewHolder).iconGifImageView); + } + ((FavoriteUserViewHolder) viewHolder).userNameTextView.setText(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).getName()); + + if(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).isFavorite()) { + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } else { + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { + if(mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).isFavorite()) { + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).setFavorite(false); + FavoriteThing.unfavoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, + mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(false); + } + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(true); + } + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + }); + } else { + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1).setFavorite(true); + FavoriteThing.favoriteUser(mOauthRetrofit, mRedditDataRoomDatabase, mAccessToken, + mFavoriteSubscribedUserData.get(viewHolder.getAdapterPosition() - 1), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(true); + } + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedUserData.size() > position) { + mFavoriteSubscribedUserData.get(position).setFavorite(false); + } + ((FavoriteUserViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + }); + } + }); + } + } + + @Override + public int getItemCount() { + if (mSubscribedUserData != null && mSubscribedUserData.size() > 0) { + if(mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) { + return mSubscribedUserData.size() + mFavoriteSubscribedUserData.size() + 2; + } + return mSubscribedUserData.size(); + } + return 0; + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if(holder instanceof UserViewHolder) { + glide.clear(((UserViewHolder) holder).iconGifImageView); + } else if (holder instanceof FavoriteUserViewHolder) { + glide.clear(((FavoriteUserViewHolder) holder).iconGifImageView); + } + } + + public void setSubscribedUsers(List subscribedUsers) { + mSubscribedUserData = subscribedUsers; + notifyDataSetChanged(); + } + + public void setFavoriteSubscribedUsers(List favoriteSubscribedUsers) { + mFavoriteSubscribedUserData = favoriteSubscribedUsers; + notifyDataSetChanged(); + } + + @NonNull + @Override + public String getPopupText(int position) { + switch (getItemViewType(position)) { + case VIEW_TYPE_USER: + int offset = (mFavoriteSubscribedUserData != null && mFavoriteSubscribedUserData.size() > 0) ? + mFavoriteSubscribedUserData.size() + 2 : 0; + return mSubscribedUserData.get(position - offset).getName().substring(0, 1).toUpperCase(); + case VIEW_TYPE_FAVORITE_USER: + return mFavoriteSubscribedUserData.get(position - 1).getName().substring(0, 1).toUpperCase(); + default: + return ""; + } + } + + class FavoriteUserViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) + GifImageView iconGifImageView; + @BindView(R.id.thing_name_text_view_item_subscribed_thing) + TextView userNameTextView; + @BindView(R.id.favorite_image_view_item_subscribed_thing) + ImageView favoriteImageView; + + FavoriteUserViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + userNameTextView.setTextColor(mPrimaryTextColor); + } + } + + class UserViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) + GifImageView iconGifImageView; + @BindView(R.id.thing_name_text_view_item_subscribed_thing) + TextView userNameTextView; + @BindView(R.id.favorite_image_view_item_subscribed_thing) + ImageView favoriteImageView; + + UserViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + userNameTextView.setTextColor(mPrimaryTextColor); + } + } + + class FavoriteUsersDividerViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; + + FavoriteUsersDividerViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + dividerTextView.setText(R.string.favorites); + dividerTextView.setTextColor(mSecondaryTextColor); + } + } + + class AllUsersDividerViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; + + AllUsersDividerViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + dividerTextView.setText(R.string.all); + dividerTextView.setTextColor(mSecondaryTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java new file mode 100644 index 00000000..6dd2fff3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MarkdownBottomBarRecyclerViewAdapter.java @@ -0,0 +1,260 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.app.Activity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.ImageView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.slider.Slider; + +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; + +public class MarkdownBottomBarRecyclerViewAdapter extends RecyclerView.Adapter { + + public static final int BOLD = 0; + public static final int ITALIC = 1; + public static final int LINK = 2; + public static final int STRIKE_THROUGH = 3; + public static final int HEADER = 4; + public static final int ORDERED_LIST = 5; + public static final int UNORDERED_LIST = 6; + public static final int SPOILER = 7; + + private static final int ITEM_COUNT = 8; + + private CustomThemeWrapper customThemeWrapper; + private ItemClickListener itemClickListener; + + public interface ItemClickListener { + void onClick(int item); + } + + public MarkdownBottomBarRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, + ItemClickListener itemClickListener) { + this.customThemeWrapper = customThemeWrapper; + this.itemClickListener = itemClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new MarkdownBottomBarItemViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_markdown_bottom_bar, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof MarkdownBottomBarItemViewHolder) { + switch (position) { + case BOLD: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_bold_black_24dp); + break; + case ITALIC: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_italic_black_24dp); + break; + case LINK: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_link_round_black_24dp); + break; + case STRIKE_THROUGH: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_strikethrough_black_24dp); + break; + case HEADER: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_title_24dp); + break; + case ORDERED_LIST: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_ordered_list_black_24dp); + break; + case UNORDERED_LIST: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_unordered_list_black_24dp); + break; + case SPOILER: + ((MarkdownBottomBarItemViewHolder) holder).imageView.setImageResource(R.drawable.ic_spoiler_black_24dp); + break; + } + } + } + + @Override + public int getItemCount() { + return ITEM_COUNT; + } + + public static void bindEditTextWithItemClickListener(Activity activity, EditText commentEditText, int item) { + switch (item) { + case MarkdownBottomBarRecyclerViewAdapter.BOLD: { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "**" + currentSelection + "**", 0, "****".length() + currentSelection.length()); + } else { + commentEditText.getText().replace(start, end, + "****", 0, "****".length()); + commentEditText.setSelection(start + "**".length()); + } + break; + } + case MarkdownBottomBarRecyclerViewAdapter.ITALIC: { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "*" + currentSelection + "*", 0, "**".length() + currentSelection.length()); + } else { + commentEditText.getText().replace(start, end, + "**", 0, "**".length()); + commentEditText.setSelection(start + "*".length()); + } + break; + } + case MarkdownBottomBarRecyclerViewAdapter.LINK: { + View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_insert_link, null); + EditText textEditText = dialogView.findViewById(R.id.edit_text_insert_link_dialog); + EditText linkEditText = dialogView.findViewById(R.id.edit_link_insert_link_dialog); + + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + textEditText.setText(currentSelection); + } + + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.insert_link) + .setView(dialogView) + .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) + -> { + String text = textEditText.getText().toString(); + String link = linkEditText.getText().toString(); + if (text.equals("")) { + text = link; + } + + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "[" + text + "](" + link + ")", 0, "[]()".length() + text.length() + link.length()); + }) + .setNegativeButton(R.string.cancel, null) + .show(); + break; + } + case MarkdownBottomBarRecyclerViewAdapter.STRIKE_THROUGH: { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "~~" + currentSelection + "~~", 0, "~~~~".length() + currentSelection.length()); + } else { + commentEditText.getText().replace(start, end, + "~~~~", 0, "~~~~".length()); + commentEditText.setSelection(start + "~~".length()); + } + break; + } + case MarkdownBottomBarRecyclerViewAdapter.HEADER: { + View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_select_header, null); + Slider seekBar = dialogView.findViewById(R.id.seek_bar_dialog_select_header); + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.select_header_size) + .setView(dialogView) + .setPositiveButton(R.string.ok, (editTextDialogInterface, i1) + -> { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + String hashTags; + switch ((int) seekBar.getValue()) { + case 0: + hashTags = "###### "; + break; + case 1: + hashTags = "##### "; + break; + case 2: + hashTags = "#### "; + break; + case 3: + hashTags = "### "; + break; + case 4: + hashTags = "## "; + break; + default: + hashTags = "# "; + break; + } + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + hashTags + currentSelection, 0, hashTags.length() + currentSelection.length()); + } else { + commentEditText.getText().replace(start, end, + hashTags, 0, hashTags.length()); + } + }) + .setNegativeButton(R.string.cancel, null) + .show(); + break; + } + case MarkdownBottomBarRecyclerViewAdapter.ORDERED_LIST: { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "1. " + currentSelection, 0, "1. ".length() + currentSelection.length()); + } else { + commentEditText.getText().replace(start, end, + "1. ", 0, "1. ".length()); + } + break; + } + case MarkdownBottomBarRecyclerViewAdapter.UNORDERED_LIST: { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + "* " + currentSelection, 0, "* ".length() + currentSelection.length()); + } else { + commentEditText.getText().replace(start, end, + "* ", 0, "* ".length()); + } + break; + } + case MarkdownBottomBarRecyclerViewAdapter.SPOILER: { + int start = Math.max(commentEditText.getSelectionStart(), 0); + int end = Math.max(commentEditText.getSelectionEnd(), 0); + if (end != start) { + String currentSelection = commentEditText.getText().subSequence(start, end).toString(); + commentEditText.getText().replace(Math.min(start, end), Math.max(start, end), + ">!" + currentSelection + "!<", 0, ">!!<".length() + currentSelection.length()); + } else { + commentEditText.getText().replace(start, end, + ">!!<", 0, ">!!<".length()); + commentEditText.setSelection(start + ">!".length()); + } + break; + } + } + } + + class MarkdownBottomBarItemViewHolder extends RecyclerView.ViewHolder { + ImageView imageView; + + public MarkdownBottomBarItemViewHolder(@NonNull View itemView) { + super(itemView); + imageView = (ImageView) itemView; + itemView.setOnClickListener(view -> itemClickListener.onClick(getAdapterPosition())); + + imageView.setColorFilter(customThemeWrapper.getPrimaryIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java new file mode 100644 index 00000000..b4d74f96 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MessageRecyclerViewAdapter.java @@ -0,0 +1,396 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.Intent; +import android.content.res.ColorStateList; +import android.graphics.Color; +import android.net.Uri; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.paging.PagedListAdapter; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPrivateMessagesActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.message.FetchMessage; +import ml.docilealligator.infinityforreddit.message.Message; +import ml.docilealligator.infinityforreddit.message.ReadMessage; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import retrofit2.Retrofit; + +public class MessageRecyclerViewAdapter extends PagedListAdapter { + private static final int VIEW_TYPE_DATA = 0; + private static final int VIEW_TYPE_ERROR = 1; + private static final int VIEW_TYPE_LOADING = 2; + private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull Message message, @NonNull Message t1) { + return message.getId().equals(t1.getId()); + } + + @Override + public boolean areContentsTheSame(@NonNull Message message, @NonNull Message t1) { + return message.getBody().equals(t1.getBody()); + } + }; + private Context mContext; + private Retrofit mOauthRetrofit; + private Markwon mMarkwon; + private String mAccessToken; + private int mMessageType; + private NetworkState networkState; + private RetryLoadingMoreCallback mRetryLoadingMoreCallback; + private int mColorAccent; + private int mMessageBackgroundColor; + private int mUsernameColor; + private int mPrimaryTextColor; + private int mSecondaryTextColor; + private int mUnreadMessageBackgroundColor; + private int mColorPrimaryLightTheme; + private int mButtonTextColor; + + public MessageRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, + CustomThemeWrapper customThemeWrapper, + String accessToken, String where, + RetryLoadingMoreCallback retryLoadingMoreCallback) { + super(DIFF_CALLBACK); + mContext = context; + mOauthRetrofit = oauthRetrofit; + mRetryLoadingMoreCallback = retryLoadingMoreCallback; + + mColorAccent = customThemeWrapper.getColorAccent(); + mMessageBackgroundColor = customThemeWrapper.getCardViewBackgroundColor(); + mUsernameColor = customThemeWrapper.getUsername(); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + int spoilerBackgroundColor = mSecondaryTextColor | 0xFF000000; + mUnreadMessageBackgroundColor = customThemeWrapper.getUnreadMessageBackgroundColor(); + mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); + mButtonTextColor = customThemeWrapper.getButtonTextColor(); + + mMarkwon = Markwon.builder(mContext) + .usePlugin(new AbstractMarkwonPlugin() { + @NonNull + @Override + public String processMarkdown(@NonNull String markdown) { + StringBuilder markdownStringBuilder = new StringBuilder(markdown); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + while (matcher.find()) { + markdownStringBuilder.replace(matcher.start(), matcher.start() + 1, ">"); + } + return super.processMarkdown(markdownStringBuilder.toString()); + } + + @Override + public void afterSetText(@NonNull TextView textView) { + textView.setHighlightColor(Color.TRANSPARENT); + SpannableStringBuilder markdownStringBuilder = new SpannableStringBuilder(textView.getText().toString()); + Pattern spoilerPattern = Pattern.compile(">![\\S\\s]*?!<"); + Matcher matcher = spoilerPattern.matcher(markdownStringBuilder); + int start = 0; + boolean find = false; + while (matcher.find(start)) { + find = true; + markdownStringBuilder.delete(matcher.end() - 2, matcher.end()); + markdownStringBuilder.delete(matcher.start(), matcher.start() + 2); + int matcherStart = matcher.start(); + int matcherEnd = matcher.end(); + ClickableSpan clickableSpan = new ClickableSpan() { + private boolean isShowing = false; + @Override + public void updateDrawState(@NonNull TextPaint ds) { + if (isShowing) { + super.updateDrawState(ds); + ds.setColor(mSecondaryTextColor); + } else { + ds.bgColor = spoilerBackgroundColor; + ds.setColor(mSecondaryTextColor); + } + ds.setUnderlineText(false); + } + + @Override + public void onClick(@NonNull View view) { + isShowing = !isShowing; + view.invalidate(); + } + }; + markdownStringBuilder.setSpan(clickableSpan, matcherStart, matcherEnd - 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + start = matcherEnd - 4; + } + if (find) { + textView.setText(markdownStringBuilder); + } + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(mContext, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + mContext.startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(customThemeWrapper.getLinkColor()); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .build(); + mAccessToken = accessToken; + if (where.equals(FetchMessage.WHERE_MESSAGES)) { + mMessageType = FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE; + } else { + mMessageType = FetchMessage.MESSAGE_TYPE_INBOX; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_DATA) { + return new DataViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message, parent, false)); + } else if (viewType == VIEW_TYPE_ERROR) { + return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false)); + } else { + return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof DataViewHolder) { + Message message = getItem(holder.getAdapterPosition()); + if (message != null) { + ArrayList replies = message.getReplies(); + Message displayedMessage; + if (replies != null && !replies.isEmpty() && replies.get(replies.size() - 1) != null) { + displayedMessage = replies.get(replies.size() - 1); + } else { + displayedMessage = message; + } + if (message.isNew()) { + ((DataViewHolder) holder).itemView.setBackgroundColor( + mUnreadMessageBackgroundColor); + } + + if (message.wasComment()) { + ((DataViewHolder) holder).titleTextView.setText(message.getTitle()); + } else { + ((DataViewHolder) holder).titleTextView.setVisibility(View.GONE); + } + + ((DataViewHolder) holder).authorTextView.setText(displayedMessage.getAuthor()); + String subject = displayedMessage.getSubject().substring(0, 1).toUpperCase() + displayedMessage.getSubject().substring(1); + ((DataViewHolder) holder).subjectTextView.setText(subject); + mMarkwon.setMarkdown(((DataViewHolder) holder).contentCustomMarkwonView, displayedMessage.getBody()); + + ((DataViewHolder) holder).itemView.setOnClickListener(view -> { + if (mMessageType == FetchMessage.MESSAGE_TYPE_INBOX + && message.getContext() != null && !message.getContext().equals("")) { + Uri uri = LinkResolverActivity.getRedditUriByPath(message.getContext()); + Intent intent = new Intent(mContext, LinkResolverActivity.class); + intent.setData(uri); + mContext.startActivity(intent); + } else if (mMessageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE) { + Intent intent = new Intent(mContext, ViewPrivateMessagesActivity.class); + intent.putExtra(ViewPrivateMessagesActivity.EXTRA_PRIVATE_MESSAGE, message); + intent.putExtra(ViewPrivateMessagesActivity.EXTRA_MESSAGE_POSITION, holder.getAdapterPosition()); + mContext.startActivity(intent); + } + + if (displayedMessage.isNew()) { + ((DataViewHolder) holder).itemView.setBackgroundColor(mMessageBackgroundColor); + message.setNew(false); + + ReadMessage.readMessage(mOauthRetrofit, mAccessToken, message.getFullname(), + new ReadMessage.ReadMessageListener() { + @Override + public void readSuccess() { + } + + @Override + public void readFailed() { + message.setNew(true); + ((DataViewHolder) holder).itemView.setBackgroundColor(mUnreadMessageBackgroundColor); + } + }); + } + }); + + ((DataViewHolder) holder).authorTextView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor()); + mContext.startActivity(intent); + }); + + ((DataViewHolder) holder).contentCustomMarkwonView.setOnClickListener(view -> { + if (((DataViewHolder) holder).contentCustomMarkwonView.getSelectionStart() == -1 && ((DataViewHolder) holder).contentCustomMarkwonView.getSelectionEnd() == -1) { + ((DataViewHolder) holder).itemView.performClick(); + } + }); + } + } + } + + @Override + public int getItemViewType(int position) { + // Reached at the end + if (hasExtraRow() && position == getItemCount() - 1) { + if (networkState.getStatus() == NetworkState.Status.LOADING) { + return VIEW_TYPE_LOADING; + } else { + return VIEW_TYPE_ERROR; + } + } else { + return VIEW_TYPE_DATA; + } + } + + @Override + public int getItemCount() { + if (hasExtraRow()) { + return super.getItemCount() + 1; + } + return super.getItemCount(); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof DataViewHolder) { + ((DataViewHolder) holder).itemView.setBackgroundColor(mMessageBackgroundColor); + ((DataViewHolder) holder).titleTextView.setVisibility(View.VISIBLE); + } + } + + private boolean hasExtraRow() { + return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; + } + + public void setNetworkState(NetworkState newNetworkState) { + NetworkState previousState = this.networkState; + boolean previousExtraRow = hasExtraRow(); + this.networkState = newNetworkState; + boolean newExtraRow = hasExtraRow(); + if (previousExtraRow != newExtraRow) { + if (previousExtraRow) { + notifyItemRemoved(super.getItemCount()); + } else { + notifyItemInserted(super.getItemCount()); + } + } else if (newExtraRow && !previousState.equals(newNetworkState)) { + notifyItemChanged(getItemCount() - 1); + } + } + + public void updateMessageReply(Message newReply, int position) { + if (position >= 0 && position < super.getItemCount()) { + Message message = getItem(position); + if (message != null) { + message.addReply(newReply); + notifyItemChanged(position); + } + } + } + + public interface RetryLoadingMoreCallback { + void retryLoadingMore(); + } + + class DataViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.author_text_view_item_message) + TextView authorTextView; + @BindView(R.id.subject_text_view_item_message) + TextView subjectTextView; + @BindView(R.id.title_text_view_item_message) + TextView titleTextView; + @BindView(R.id.content_custom_markwon_view_item_message) + TextView contentCustomMarkwonView; + + DataViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + itemView.setBackgroundColor(mMessageBackgroundColor); + authorTextView.setTextColor(mUsernameColor); + subjectTextView.setTextColor(mPrimaryTextColor); + titleTextView.setTextColor(mPrimaryTextColor); + contentCustomMarkwonView.setTextColor(mSecondaryTextColor); + + contentCustomMarkwonView.setMovementMethod(LinkMovementMethod.getInstance()); + } + } + + class ErrorViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_footer_error) + TextView errorTextView; + @BindView(R.id.retry_button_item_footer_error) + Button retryButton; + + ErrorViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + errorTextView.setText(R.string.load_comments_failed); + errorTextView.setTextColor(mSecondaryTextColor); + retryButton.setOnClickListener(view -> mRetryLoadingMoreCallback.retryLoadingMore()); + retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); + retryButton.setTextColor(mButtonTextColor); + } + } + + class LoadingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_footer_loading) + ProgressBar progressBar; + + LoadingViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MultiRedditListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MultiRedditListingRecyclerViewAdapter.java new file mode 100644 index 00000000..7dd20529 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/MultiRedditListingRecyclerViewAdapter.java @@ -0,0 +1,398 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import me.zhanghai.android.fastscroll.PopupTextProvider; +import ml.docilealligator.infinityforreddit.activities.ViewMultiRedditDetailActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.MultiRedditOptionsBottomSheetFragment; +import ml.docilealligator.infinityforreddit.multireddit.FavoriteMultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class MultiRedditListingRecyclerViewAdapter extends RecyclerView.Adapter implements PopupTextProvider { + + private static final int VIEW_TYPE_FAVORITE_MULTI_REDDIT_DIVIDER = 0; + private static final int VIEW_TYPE_FAVORITE_MULTI_REDDIT = 1; + private static final int VIEW_TYPE_MULTI_REDDIT_DIVIDER = 2; + private static final int VIEW_TYPE_MULTI_REDDIT = 3; + + private AppCompatActivity mActivity; + private Retrofit mOauthRetrofit; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private RequestManager mGlide; + + private String mAccessToken; + private String mAccountName; + private List mMultiReddits; + private List mFavoriteMultiReddits; + private int mPrimaryTextColor; + private int mSecondaryTextColor; + + public MultiRedditListingRecyclerViewAdapter(AppCompatActivity activity, Retrofit oauthRetrofit, + RedditDataRoomDatabase redditDataRoomDatabase, + CustomThemeWrapper customThemeWrapper, + String accessToken, String accountName) { + mActivity = activity; + mGlide = Glide.with(activity); + mOauthRetrofit = oauthRetrofit; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mAccessToken = accessToken; + mAccountName = accountName; + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + } + + @Override + public int getItemViewType(int position) { + if (mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) { + if (position == 0) { + return VIEW_TYPE_FAVORITE_MULTI_REDDIT_DIVIDER; + } else if (position == mFavoriteMultiReddits.size() + 1) { + return VIEW_TYPE_MULTI_REDDIT_DIVIDER; + } else if (position <= mFavoriteMultiReddits.size()) { + return VIEW_TYPE_FAVORITE_MULTI_REDDIT; + } else { + return VIEW_TYPE_MULTI_REDDIT; + } + } else { + return VIEW_TYPE_MULTI_REDDIT; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_FAVORITE_MULTI_REDDIT_DIVIDER: + return new FavoriteMultiRedditsDividerViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_favorite_thing_divider, parent, false)); + case VIEW_TYPE_FAVORITE_MULTI_REDDIT: + return new FavoriteMultiRedditViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_multi_reddit, parent, false)); + case VIEW_TYPE_MULTI_REDDIT_DIVIDER: + return new AllMultiRedditsDividerViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_favorite_thing_divider, parent, false)); + default: + return new MultiRedditViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_multi_reddit, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof MultiRedditViewHolder) { + String name; + String iconUrl; + + int offset = (mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) ? + mFavoriteMultiReddits.size() + 2 : 0; + + MultiReddit multiReddit = mMultiReddits.get(holder.getAdapterPosition() - offset); + name = multiReddit.getDisplayName(); + iconUrl = multiReddit.getIconUrl(); + if(multiReddit.isFavorite()) { + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } else { + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + ((MultiRedditViewHolder) holder).favoriteImageView.setOnClickListener(view -> { + if(multiReddit.isFavorite()) { + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + multiReddit.setFavorite(false); + FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, + mAccessToken, false, multiReddit, + new FavoriteMultiReddit.FavoriteMultiRedditListener() { + @Override + public void success() { + int position = holder.getAdapterPosition() - offset; + if(position >= 0 && mMultiReddits.size() > position) { + mMultiReddits.get(position).setFavorite(false); + } + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + @Override + public void failed() { + Toast.makeText(mActivity, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); + int position = holder.getAdapterPosition() - offset; + if(position >= 0 && mMultiReddits.size() > position) { + mMultiReddits.get(position).setFavorite(true); + } + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + } + ); + } else { + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + multiReddit.setFavorite(true); + FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, + mAccessToken, true, multiReddit, + new FavoriteMultiReddit.FavoriteMultiRedditListener() { + @Override + public void success() { + int position = holder.getAdapterPosition() - offset; + if(position >= 0 && mMultiReddits.size() > position) { + mMultiReddits.get(position).setFavorite(true); + } + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + + @Override + public void failed() { + Toast.makeText(mActivity, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); + int position = holder.getAdapterPosition() - offset; + if(position >= 0 && mMultiReddits.size() > position) { + mMultiReddits.get(position).setFavorite(false); + } + ((MultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + } + ); + } + }); + holder.itemView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, ViewMultiRedditDetailActivity.class); + intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_DATA, multiReddit); + mActivity.startActivity(intent); + }); + + holder.itemView.setOnLongClickListener(view -> { + showOptionsBottomSheetFragment(multiReddit); + return true; + }); + + if (iconUrl != null && !iconUrl.equals("")) { + 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(((MultiRedditViewHolder) holder).iconImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((MultiRedditViewHolder) holder).iconImageView); + } + ((MultiRedditViewHolder) holder).multiRedditNameTextView.setText(name); + } else if (holder instanceof FavoriteMultiRedditViewHolder) { + MultiReddit multiReddit = mFavoriteMultiReddits.get(holder.getAdapterPosition() - 1); + String name = multiReddit.getDisplayName(); + String iconUrl = multiReddit.getIconUrl(); + if(multiReddit.isFavorite()) { + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } else { + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setOnClickListener(view -> { + if(multiReddit.isFavorite()) { + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + multiReddit.setFavorite(false); + FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, + mAccessToken, false, multiReddit, + new FavoriteMultiReddit.FavoriteMultiRedditListener() { + @Override + public void success() { + int position = holder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteMultiReddits.size() > position) { + mFavoriteMultiReddits.get(position).setFavorite(false); + } + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + @Override + public void failed() { + Toast.makeText(mActivity, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); + int position = holder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteMultiReddits.size() > position) { + mFavoriteMultiReddits.get(position).setFavorite(true); + } + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + } + ); + } else { + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + multiReddit.setFavorite(true); + FavoriteMultiReddit.favoriteMultiReddit(mOauthRetrofit, mRedditDataRoomDatabase, + mAccessToken, true, multiReddit, + new FavoriteMultiReddit.FavoriteMultiRedditListener() { + @Override + public void success() { + int position = holder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteMultiReddits.size() > position) { + mFavoriteMultiReddits.get(position).setFavorite(true); + } + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + + @Override + public void failed() { + Toast.makeText(mActivity, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); + int position = holder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteMultiReddits.size() > position) { + mFavoriteMultiReddits.get(position).setFavorite(false); + } + ((FavoriteMultiRedditViewHolder) holder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + } + ); + } + }); + holder.itemView.setOnClickListener(view -> { + Intent intent = new Intent(mActivity, ViewMultiRedditDetailActivity.class); + intent.putExtra(ViewMultiRedditDetailActivity.EXTRA_MULTIREDDIT_DATA, multiReddit); + mActivity.startActivity(intent); + }); + + holder.itemView.setOnLongClickListener(view -> { + showOptionsBottomSheetFragment(multiReddit); + return true; + }); + + if (iconUrl != null && !iconUrl.equals("")) { + 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(((FavoriteMultiRedditViewHolder) holder).iconImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((FavoriteMultiRedditViewHolder) holder).iconImageView); + } + ((FavoriteMultiRedditViewHolder) holder).multiRedditNameTextView.setText(name); + } + } + + @Override + public int getItemCount() { + if (mMultiReddits != null) { + if(mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) { + return mMultiReddits.size() > 0 ? + mFavoriteMultiReddits.size() + mMultiReddits.size() + 2 : 0; + } + + return mMultiReddits.size(); + } + return 0; + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if(holder instanceof MultiRedditViewHolder) { + mGlide.clear(((MultiRedditViewHolder) holder).iconImageView); + } else if (holder instanceof FavoriteMultiRedditViewHolder) { + mGlide.clear(((FavoriteMultiRedditViewHolder) holder).iconImageView); + } + } + + private void showOptionsBottomSheetFragment(MultiReddit multiReddit) { + MultiRedditOptionsBottomSheetFragment fragment = new MultiRedditOptionsBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putParcelable(MultiRedditOptionsBottomSheetFragment.EXTRA_MULTI_REDDIT, multiReddit); + fragment.setArguments(bundle); + fragment.show(mActivity.getSupportFragmentManager(), fragment.getTag()); + } + + public void setMultiReddits(List multiReddits) { + mMultiReddits = multiReddits; + notifyDataSetChanged(); + } + + public void setFavoriteMultiReddits(List favoriteMultiReddits) { + mFavoriteMultiReddits = favoriteMultiReddits; + notifyDataSetChanged(); + } + + @NonNull + @Override + public String getPopupText(int position) { + switch (getItemViewType(position)) { + case VIEW_TYPE_MULTI_REDDIT: + int offset = (mFavoriteMultiReddits != null && mFavoriteMultiReddits.size() > 0) ? + mFavoriteMultiReddits.size() + 2 : 0; + return mMultiReddits.get(position - offset).getDisplayName().substring(0, 1).toUpperCase(); + case VIEW_TYPE_FAVORITE_MULTI_REDDIT: + return mFavoriteMultiReddits.get(position - 1).getDisplayName().substring(0, 1).toUpperCase(); + default: + return ""; + } + } + + class MultiRedditViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.multi_reddit_icon_gif_image_view_item_multi_reddit) + GifImageView iconImageView; + @BindView(R.id.multi_reddit_name_text_view_item_multi_reddit) + TextView multiRedditNameTextView; + @BindView(R.id.favorite_image_view_item_multi_reddit) + ImageView favoriteImageView; + + MultiRedditViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + multiRedditNameTextView.setTextColor(mPrimaryTextColor); + } + } + + class FavoriteMultiRedditViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.multi_reddit_icon_gif_image_view_item_multi_reddit) + GifImageView iconImageView; + @BindView(R.id.multi_reddit_name_text_view_item_multi_reddit) + TextView multiRedditNameTextView; + @BindView(R.id.favorite_image_view_item_multi_reddit) + ImageView favoriteImageView; + + FavoriteMultiRedditViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + multiRedditNameTextView.setTextColor(mPrimaryTextColor); + } + } + + class FavoriteMultiRedditsDividerViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; + + FavoriteMultiRedditsDividerViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + dividerTextView.setText(R.string.favorites); + dividerTextView.setTextColor(mSecondaryTextColor); + } + } + + class AllMultiRedditsDividerViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; + + AllMultiRedditsDividerViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + dividerTextView.setText(R.string.all); + dividerTextView.setTextColor(mSecondaryTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java new file mode 100644 index 00000000..9d022099 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/NavigationDrawerRecyclerViewAdapter.java @@ -0,0 +1,657 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.content.res.Resources; +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.appcompat.app.AppCompatActivity; +import androidx.biometric.BiometricManager; +import androidx.biometric.BiometricPrompt; +import androidx.core.content.ContextCompat; +import androidx.core.content.res.ResourcesCompat; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executor; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import pl.droidsonroids.gif.GifImageView; + +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; +import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; + +public class NavigationDrawerRecyclerViewAdapter extends RecyclerView.Adapter { + + public interface ItemClickListener { + void onMenuClick(int stringId); + void onSubscribedSubredditClick(String subredditName); + void onAccountClick(String accountName); + } + + private static final int VIEW_TYPE_NAV_HEADER = 0; + private static final int VIEW_TYPE_MENU_GROUP_TITLE = 1; + private static final int VIEW_TYPE_MENU_ITEM = 2; + private static final int VIEW_TYPE_DIVIDER = 3; + private static final int VIEW_TYPE_FAVORITE_SUBSCRIBED_SUBREDDIT = 4; + private static final int VIEW_TYPE_SUBSCRIBED_SUBREDDIT = 5; + private static final int VIEW_TYPE_ACCOUNT = 6; + private static final int CURRENT_MENU_ITEMS = 17; + + private AppCompatActivity appCompatActivity; + private Resources resources; + private RequestManager glide; + private String accountName; + private String userIconUrl; + private String userBannerUrl; + private int karma; + private boolean isNSFWEnabled; + private boolean requireAuthToAccountSection; + private ItemClickListener itemClickListener; + private boolean isLoggedIn; + private boolean isInMainPage = true; + private ArrayList favoriteSubscribedSubreddits; + private ArrayList subscribedSubreddits; + private ArrayList accounts; + private int primaryTextColor; + private int secondaryTextColor; + private int dividerColor; + private int primaryIconColor; + + public NavigationDrawerRecyclerViewAdapter(AppCompatActivity appCompatActivity, SharedPreferences sharedPreferences, + SharedPreferences nsfwAndSpoilerSharedPreferences, + CustomThemeWrapper customThemeWrapper, + String accountName, String userIconUrl, + String userBannerUrl, int karma, + ItemClickListener itemClickListener) { + this.appCompatActivity = appCompatActivity; + resources = appCompatActivity.getResources(); + glide = Glide.with(appCompatActivity); + this.accountName = accountName; + this.userIconUrl = userIconUrl; + this.userBannerUrl = userBannerUrl; + this.karma = karma; + isNSFWEnabled = nsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); + requireAuthToAccountSection = sharedPreferences.getBoolean(SharedPreferencesUtils.REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER, false); + isLoggedIn = accountName != null; + this.itemClickListener = itemClickListener; + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + dividerColor = customThemeWrapper.getDividerColor(); + primaryIconColor = customThemeWrapper.getPrimaryIconColor(); + favoriteSubscribedSubreddits = new ArrayList<>(); + subscribedSubreddits = new ArrayList<>(); + } + + @Override + public int getItemViewType(int position) { + if (isInMainPage) { + if (isLoggedIn) { + if (position == CURRENT_MENU_ITEMS) { + return VIEW_TYPE_MENU_GROUP_TITLE; + } else if (!favoriteSubscribedSubreddits.isEmpty() && position == CURRENT_MENU_ITEMS + favoriteSubscribedSubreddits.size() + 1) { + return VIEW_TYPE_MENU_GROUP_TITLE; + } else if (position > CURRENT_MENU_ITEMS) { + if (!favoriteSubscribedSubreddits.isEmpty() && position <= CURRENT_MENU_ITEMS + favoriteSubscribedSubreddits.size()) { + return VIEW_TYPE_FAVORITE_SUBSCRIBED_SUBREDDIT; + } else { + return VIEW_TYPE_SUBSCRIBED_SUBREDDIT; + } + } else if (position == 0) { + return VIEW_TYPE_NAV_HEADER; + } else if (position == 1 || position == 6 || position == 12) { + return VIEW_TYPE_MENU_GROUP_TITLE; + } else if (position == 16) { + return VIEW_TYPE_DIVIDER; + } else { + return VIEW_TYPE_MENU_ITEM; + } + } else { + if (position == 0) { + return VIEW_TYPE_NAV_HEADER; + } else { + return VIEW_TYPE_MENU_ITEM; + } + } + } else { + if (position == 0) { + return VIEW_TYPE_NAV_HEADER; + } + if (accounts != null) { + if (position > accounts.size()) { + return VIEW_TYPE_MENU_ITEM; + } else { + return VIEW_TYPE_ACCOUNT; + } + } else { + return VIEW_TYPE_MENU_ITEM; + } + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + switch (viewType) { + case VIEW_TYPE_NAV_HEADER: + return new NavHeaderViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.nav_header_main, parent, false)); + case VIEW_TYPE_MENU_GROUP_TITLE: + return new MenuGroupTitleViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_nav_drawer_menu_group_title, parent, false)); + case VIEW_TYPE_MENU_ITEM: + return new MenuItemViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_nav_drawer_menu_item, parent, false)); + case VIEW_TYPE_DIVIDER: + return new DividerViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_nav_drawer_divider, parent, false)); + case VIEW_TYPE_ACCOUNT: + return new AccountViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_nav_drawer_account, parent, false)); + case VIEW_TYPE_FAVORITE_SUBSCRIBED_SUBREDDIT: + return new FavoriteSubscribedThingViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_nav_drawer_subscribed_thing, parent, false)); + default: + return new SubscribedThingViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_nav_drawer_subscribed_thing, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof NavHeaderViewHolder) { + if (isLoggedIn) { + ((NavHeaderViewHolder) holder).karmaTextView.setText(appCompatActivity.getString(R.string.karma_info, karma)); + ((NavHeaderViewHolder) holder).accountNameTextView.setText(accountName); + if (userIconUrl != null && !userIconUrl.equals("")) { + glide.load(userIconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0)))) + .into(((NavHeaderViewHolder) holder).profileImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0))) + .into(((NavHeaderViewHolder) holder).profileImageView); + } + + if (userBannerUrl != null && !userBannerUrl.equals("")) { + glide.load(userBannerUrl).into(((NavHeaderViewHolder) holder).bannerImageView); + } + } else { + ((NavHeaderViewHolder) holder).karmaTextView.setText(R.string.press_here_to_login); + ((NavHeaderViewHolder) holder).accountNameTextView.setText(R.string.anonymous_account); + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(144, 0))) + .into(((NavHeaderViewHolder) holder).profileImageView); + } + + if (isInMainPage) { + ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_down_24px)); + } else { + ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_arrow_drop_up_24px)); + } + + ((NavHeaderViewHolder) holder).itemView.setOnClickListener(view -> { + if (isInMainPage) { + if (requireAuthToAccountSection) { + BiometricManager biometricManager = BiometricManager.from(appCompatActivity); + if (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS) { + Executor executor = ContextCompat.getMainExecutor(appCompatActivity); + BiometricPrompt biometricPrompt = new BiometricPrompt(appCompatActivity, + executor, new BiometricPrompt.AuthenticationCallback() { + @Override + public void onAuthenticationSucceeded( + @NonNull BiometricPrompt.AuthenticationResult result) { + super.onAuthenticationSucceeded(result); + openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); + } + }); + + BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() + .setTitle(appCompatActivity.getString(R.string.unlock_account_section)) + .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) + .build(); + + biometricPrompt.authenticate(promptInfo); + } else { + openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); + } + } else { + openAccountSection(((NavHeaderViewHolder) holder).dropIconImageView); + } + } else { + ((NavHeaderViewHolder) holder).dropIconImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_arrow_drop_down_24px, null)); + closeAccountSectionWithoutChangeIconResource(false); + } + }); + } else if (holder instanceof MenuGroupTitleViewHolder) { + if (position == 1) { + ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_account); + } else if (position == 6) { + ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_post); + } else if (position == 12) { + ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.label_preferences); + } else { + if (!favoriteSubscribedSubreddits.isEmpty() && position == CURRENT_MENU_ITEMS) { + ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.favorites); + } else { + ((MenuGroupTitleViewHolder) holder).titleTextView.setText(R.string.subscriptions); + } + } + } else if (holder instanceof MenuItemViewHolder) { + int stringId = 0; + int drawableId = 0; + boolean setOnClickListener = true; + + if (isInMainPage) { + if (isLoggedIn) { + switch (position) { + case 2: + stringId = R.string.profile; + drawableId = R.drawable.ic_account_circle_24dp; + break; + case 3: + stringId = R.string.subscriptions; + drawableId = R.drawable.ic_subscritptions_bottom_app_bar_24dp; + break; + case 4: + stringId = R.string.multi_reddit; + drawableId = R.drawable.ic_multi_reddit_24dp; + break; + case 5: + stringId = R.string.inbox; + drawableId = R.drawable.ic_inbox_24dp; + break; + case 7: + stringId = R.string.upvoted; + drawableId = R.drawable.ic_arrow_upward_black_24dp; + break; + case 8: + stringId = R.string.downvoted; + drawableId = R.drawable.ic_arrow_downward_black_24dp; + break; + case 9: + stringId = R.string.hidden; + drawableId = R.drawable.ic_outline_lock_24dp; + break; + case 10: + stringId = R.string.saved; + drawableId = R.drawable.ic_outline_bookmarks_24dp; + break; + case 11: + stringId = R.string.gilded; + drawableId = R.drawable.ic_star_border_24dp; + break; + case 13: + if ((resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + stringId = R.string.dark_theme; + drawableId = R.drawable.ic_dark_theme_24dp; + } else { + stringId = R.string.light_theme; + drawableId = R.drawable.ic_light_theme_24dp; + } + break; + case 14: + setOnClickListener = false; + if (isNSFWEnabled) { + stringId = R.string.disable_nsfw; + drawableId = R.drawable.ic_nsfw_off_24dp; + } else { + stringId = R.string.enable_nsfw; + drawableId = R.drawable.ic_nsfw_on_24dp; + } + + ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> { + if (isNSFWEnabled) { + isNSFWEnabled = false; + ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); + itemClickListener.onMenuClick(R.string.disable_nsfw); + } else { + isNSFWEnabled = true; + ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); + itemClickListener.onMenuClick(R.string.enable_nsfw); + } + }); + break; + case 15: + stringId = R.string.settings; + drawableId = R.drawable.ic_settings_24dp; + } + } else { + switch (position) { + case 1: + if ((resources.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + stringId = R.string.dark_theme; + drawableId = R.drawable.ic_dark_theme_24dp; + } else { + stringId = R.string.light_theme; + drawableId = R.drawable.ic_light_theme_24dp; + } + break; + case 2: + setOnClickListener = false; + if (isNSFWEnabled) { + stringId = R.string.disable_nsfw; + drawableId = R.drawable.ic_nsfw_off_24dp; + } else { + stringId = R.string.enable_nsfw; + drawableId = R.drawable.ic_nsfw_on_24dp; + } + + ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> { + if (isNSFWEnabled) { + isNSFWEnabled = false; + ((MenuItemViewHolder) holder).menuTextView.setText(R.string.enable_nsfw); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_on_24dp)); + itemClickListener.onMenuClick(R.string.disable_nsfw); + } else { + isNSFWEnabled = true; + ((MenuItemViewHolder) holder).menuTextView.setText(R.string.disable_nsfw); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(R.drawable.ic_nsfw_off_24dp)); + itemClickListener.onMenuClick(R.string.enable_nsfw); + } + }); + break; + case 3: + stringId = R.string.settings; + drawableId = R.drawable.ic_settings_24dp; + } + } + } else { + if (isLoggedIn) { + int offset = accounts == null ? 0 : accounts.size(); + if (position == offset + 1) { + stringId = R.string.add_account; + drawableId = R.drawable.ic_outline_add_circle_outline_24dp; + } else if (position == offset + 2) { + stringId = R.string.anonymous_account; + drawableId = R.drawable.ic_anonymous_24dp; + } else if (position == offset + 3) { + stringId = R.string.log_out; + drawableId = R.drawable.ic_log_out_24dp; + } + } else { + stringId = R.string.add_account; + drawableId = R.drawable.ic_outline_add_circle_outline_24dp; + } + } + + if (stringId != 0) { + ((MenuItemViewHolder) holder).menuTextView.setText(stringId); + ((MenuItemViewHolder) holder).imageView.setImageDrawable(appCompatActivity.getDrawable(drawableId)); + if (setOnClickListener) { + int finalStringId = stringId; + ((MenuItemViewHolder) holder).itemView.setOnClickListener(view -> itemClickListener.onMenuClick(finalStringId)); + } + } + } else if (holder instanceof FavoriteSubscribedThingViewHolder) { + SubscribedSubredditData subreddit = favoriteSubscribedSubreddits.get(position - CURRENT_MENU_ITEMS - 1); + String subredditName = subreddit.getName(); + String iconUrl = subreddit.getIconUrl(); + ((FavoriteSubscribedThingViewHolder) holder).subredditNameTextView.setText(subredditName); + if (iconUrl != null && !iconUrl.equals("")) { + glide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((FavoriteSubscribedThingViewHolder) holder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((FavoriteSubscribedThingViewHolder) holder).iconGifImageView); + } + + ((FavoriteSubscribedThingViewHolder) holder).itemView.setOnClickListener(view -> { + itemClickListener.onSubscribedSubredditClick(subredditName); + }); + } else if (holder instanceof SubscribedThingViewHolder) { + SubscribedSubredditData subreddit = favoriteSubscribedSubreddits.isEmpty() ? subscribedSubreddits.get(position - CURRENT_MENU_ITEMS - 1) + : subscribedSubreddits.get(position - CURRENT_MENU_ITEMS - favoriteSubscribedSubreddits.size() - 2); + String subredditName = subreddit.getName(); + String iconUrl = subreddit.getIconUrl(); + ((SubscribedThingViewHolder) holder).subredditNameTextView.setText(subredditName); + if (iconUrl != null && !iconUrl.equals("")) { + glide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((SubscribedThingViewHolder) holder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((SubscribedThingViewHolder) holder).iconGifImageView); + } + + ((SubscribedThingViewHolder) holder).itemView.setOnClickListener(view -> { + itemClickListener.onSubscribedSubredditClick(subredditName); + }); + } else if (holder instanceof AccountViewHolder) { + glide.load(accounts.get(position - 1).getProfileImageUrl()) + .error(glide.load(R.drawable.subreddit_default_icon)) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(128, 0))) + .into(((AccountViewHolder) holder).profileImageGifImageView); + ((AccountViewHolder) holder).usernameTextView.setText(accounts.get(position - 1).getUsername()); + ((AccountViewHolder) holder).itemView.setOnClickListener(view -> + itemClickListener.onAccountClick(accounts.get(position - 1).getUsername())); + } + } + + public boolean closeAccountSectionWithoutChangeIconResource(boolean checkIsInMainPage) { + if (!(checkIsInMainPage && isInMainPage)) { + notifyItemRangeRemoved(1, getItemCount() - 1); + if (isLoggedIn) { + notifyItemRangeInserted(1, (favoriteSubscribedSubreddits.isEmpty() ? 0 : favoriteSubscribedSubreddits.size() + 1) + + (subscribedSubreddits.isEmpty() ? 0 : subscribedSubreddits.size() + 1) + CURRENT_MENU_ITEMS - 1); + } else { + notifyItemRangeInserted(1, 2); + } + isInMainPage = true; + + return true; + } + + return false; + } + + private void openAccountSection(ImageView dropIconImageView) { + dropIconImageView.setImageDrawable(ResourcesCompat.getDrawable(resources, R.drawable.ic_baseline_arrow_drop_up_24px, null)); + notifyItemRangeRemoved(1, getItemCount() - 1); + if (accounts != null) { + notifyItemRangeInserted(1, accounts.size() + 3); + } else { + if (isLoggedIn) { + notifyItemRangeInserted(1, 3); + } else { + notifyItemInserted(1); + } + } + isInMainPage = false; + } + + @Override + public int getItemCount() { + if (isInMainPage) { + if (isLoggedIn) { + if (!(favoriteSubscribedSubreddits.isEmpty() && subscribedSubreddits.isEmpty())) { + return CURRENT_MENU_ITEMS + (favoriteSubscribedSubreddits.isEmpty() ? 0 : favoriteSubscribedSubreddits.size() + 1) + + (subscribedSubreddits.isEmpty() ? 0 : subscribedSubreddits.size() + 1); + } + return CURRENT_MENU_ITEMS - 1; + } else { + return 4; + } + } else { + if (isLoggedIn) { + if (accounts != null && !accounts.isEmpty()) { + return 4 + accounts.size(); + } else { + return 4; + } + } else { + if (accounts != null && !accounts.isEmpty()) { + return 2 + accounts.size(); + } else { + return 2; + } + } + } + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof SubscribedThingViewHolder) { + glide.clear(((SubscribedThingViewHolder) holder).iconGifImageView); + } + } + + public void setFavoriteSubscribedSubreddits(List favoriteSubscribedSubreddits) { + this.favoriteSubscribedSubreddits = (ArrayList) favoriteSubscribedSubreddits; + if (isInMainPage) { + notifyDataSetChanged(); + } + } + + public void setSubscribedSubreddits(List subscribedSubreddits) { + this.subscribedSubreddits = (ArrayList) subscribedSubreddits; + if (isInMainPage) { + notifyDataSetChanged(); + } + } + + public void changeAccountsDataset(List accounts) { + this.accounts = (ArrayList) accounts; + if (!isInMainPage) { + notifyDataSetChanged(); + } + } + + public void updateKarma(int karma) { + this.karma = karma; + notifyItemChanged(0); + } + + public void setNSFWEnabled(boolean isNSFWEnabled) { + this.isNSFWEnabled = isNSFWEnabled; + if (isInMainPage) { + if (isLoggedIn) { + notifyItemChanged(CURRENT_MENU_ITEMS - 3); + } else { + notifyItemChanged(2); + } + } + } + + public void setRequireAuthToAccountSection(boolean requireAuthToAccountSection) { + this.requireAuthToAccountSection = requireAuthToAccountSection; + } + + class NavHeaderViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.name_text_view_nav_header_main) + TextView accountNameTextView; + @BindView(R.id.karma_text_view_nav_header_main) + TextView karmaTextView; + @BindView(R.id.profile_image_view_nav_header_main) + GifImageView profileImageView; + @BindView(R.id.banner_image_view_nav_header_main) + ImageView bannerImageView; + @BindView(R.id.account_switcher_image_view_nav_header_main) + ImageView dropIconImageView; + + NavHeaderViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } + + class MenuGroupTitleViewHolder extends RecyclerView.ViewHolder { + TextView titleTextView; + + MenuGroupTitleViewHolder(@NonNull View itemView) { + super(itemView); + titleTextView = (TextView) itemView; + titleTextView.setTextColor(secondaryTextColor); + } + } + + class MenuItemViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.image_view_item_nav_drawer_menu_item) + ImageView imageView; + @BindView(R.id.text_view_item_nav_drawer_menu_item) + TextView menuTextView; + + MenuItemViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + menuTextView.setTextColor(primaryTextColor); + imageView.setColorFilter(primaryIconColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + } + + class DividerViewHolder extends RecyclerView.ViewHolder { + + DividerViewHolder(@NonNull View itemView) { + super(itemView); + itemView.setBackgroundColor(dividerColor); + } + } + + class FavoriteSubscribedThingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.thing_icon_gif_image_view_item_nav_drawer_subscribed_thing) + GifImageView iconGifImageView; + @BindView(R.id.thing_name_text_view_item_nav_drawer_subscribed_thing) + TextView subredditNameTextView; + + FavoriteSubscribedThingViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + subredditNameTextView.setTextColor(primaryTextColor); + } + } + + class SubscribedThingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.thing_icon_gif_image_view_item_nav_drawer_subscribed_thing) + GifImageView iconGifImageView; + @BindView(R.id.thing_name_text_view_item_nav_drawer_subscribed_thing) + TextView subredditNameTextView; + + SubscribedThingViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + subredditNameTextView.setTextColor(primaryTextColor); + } + } + + class AccountViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.profile_image_item_account) + GifImageView profileImageGifImageView; + @BindView(R.id.username_text_view_item_account) + TextView usernameTextView; + + AccountViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + usernameTextView.setTextColor(primaryTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java new file mode 100644 index 00000000..cf53ffb4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PostRecyclerViewAdapter.java @@ -0,0 +1,3008 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.ColorFilter; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import androidx.constraintlayout.widget.Barrier; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.constraintlayout.widget.ConstraintSet; +import androidx.core.graphics.drawable.DrawableCompat; +import androidx.paging.PagedListAdapter; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestBuilder; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.RequestOptions; +import com.bumptech.glide.request.target.Target; +import com.google.android.exoplayer2.metadata.Metadata; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.text.Cue; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.ui.AspectRatioFrameLayout; +import com.google.android.exoplayer2.ui.PlayerView; +import com.google.android.material.card.MaterialCardView; +import com.libRG.CustomTextView; + +import org.greenrobot.eventbus.EventBus; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import butterknife.BindView; +import butterknife.ButterKnife; +import im.ene.toro.CacheManager; +import im.ene.toro.ToroPlayer; +import im.ene.toro.ToroUtil; +import im.ene.toro.exoplayer.ExoCreator; +import im.ene.toro.exoplayer.ExoPlayerViewHelper; +import im.ene.toro.exoplayer.Playable; +import im.ene.toro.media.PlaybackInfo; +import im.ene.toro.widget.Container; +import jp.wasabeef.glide.transformations.BlurTransformation; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.activities.FilteredThingActivity; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewImageOrGifActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewRedditGalleryActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewVideoActivity; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIconAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.LoadUserDataAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.ShareLinkBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; +import ml.docilealligator.infinityforreddit.events.PostUpdateEventToDetailActivity; +import ml.docilealligator.infinityforreddit.FetchGfycatOrRedgifsVideoLinks; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SaveThing; +import ml.docilealligator.infinityforreddit.user.UserDao; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import ml.docilealligator.infinityforreddit.VoteThing; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +/** + * Created by alex on 2/25/18. + */ + +public class PostRecyclerViewAdapter extends PagedListAdapter implements CacheManager { + private static final int VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE = 1; + private static final int VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE = 2; + private static final int VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE = 3; + private static final int VIEW_TYPE_POST_CARD_LINK_TYPE = 4; + private static final int VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE = 5; + private static final int VIEW_TYPE_POST_CARD_TEXT_TYPE = 6; + private static final int VIEW_TYPE_POST_CARD_GALLERY_TYPE = 7; + private static final int VIEW_TYPE_POST_COMPACT = 8; + private static final int VIEW_TYPE_ERROR = 9; + private static final int VIEW_TYPE_LOADING = 10; + private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull Post post, @NonNull Post t1) { + return post.getId().equals(t1.getId()); + } + + @Override + public boolean areContentsTheSame(@NonNull Post post, @NonNull Post t1) { + return false; + } + }; + private AppCompatActivity mActivity; + private Retrofit mOauthRetrofit; + private Retrofit mRetrofit; + private Retrofit mGfycatRetrofit; + private Retrofit mRedgifsRetrofit; + private int mImageViewWidth; + private String mAccessToken; + private RequestManager mGlide; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private Locale mLocale; + private UserDao mUserDao; + private boolean canStartActivity = true; + private int mPostType; + private int mPostLayout; + private int mColorPrimaryLightTheme; + private int mColorAccent; + private int mCardViewBackgroundColor; + private int mPrimaryTextColor; + private int mSecondaryTextColor; + private int mPostTitleColor; + private int mPostContentColor; + private int mStickiedPostIconTint; + private int mPostTypeBackgroundColor; + private int mPostTypeTextColor; + private int mSubredditColor; + private int mUsernameColor; + private int mSpoilerBackgroundColor; + private int mSpoilerTextColor; + private int mFlairBackgroundColor; + private int mFlairTextColor; + private int mAwardsBackgroundColor; + private int mAwardsTextColor; + private int mNSFWBackgroundColor; + private int mNSFWTextColor; + private int mArchivedIconTint; + private int mLockedIconTint; + private int mCrosspostIconTint; + private int mNoPreviewPostTypeBackgroundColor; + private int mNoPreviewPostTypeIconTint; + private int mUpvotedColor; + private int mDownvotedColor; + private int mVoteAndReplyUnavailableVoteButtonColor; + private int mButtonTextColor; + 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 = false; + private Drawable mCommentIcon; + private NetworkState networkState; + private ExoCreator mExoCreator; + private Callback mCallback; + private ShareLinkBottomSheetFragment mShareLinkBottomSheetFragment; + + public PostRecyclerViewAdapter(AppCompatActivity activity, Retrofit oauthRetrofit, Retrofit retrofit, + Retrofit gfycatRetrofit, Retrofit redgifsRetrofit, + RedditDataRoomDatabase redditDataRoomDatabase, + CustomThemeWrapper customThemeWrapper, Locale locale, int imageViewWidth, + 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; + mOauthRetrofit = oauthRetrofit; + mRetrofit = retrofit; + mGfycatRetrofit = gfycatRetrofit; + mRedgifsRetrofit = redgifsRetrofit; + mImageViewWidth = imageViewWidth; + 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); + + mPostLayout = postLayout; + + mColorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); + mColorAccent = customThemeWrapper.getColorAccent(); + mCardViewBackgroundColor = customThemeWrapper.getCardViewBackgroundColor(); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + mPostTitleColor = customThemeWrapper.getPostTitleColor(); + mPostContentColor = customThemeWrapper.getPostContentColor(); + mStickiedPostIconTint = customThemeWrapper.getStickiedPostIconTint(); + mPostTypeBackgroundColor = customThemeWrapper.getPostTypeBackgroundColor(); + mPostTypeTextColor = customThemeWrapper.getPostTypeTextColor(); + mSubredditColor = customThemeWrapper.getSubreddit(); + mUsernameColor = customThemeWrapper.getUsername(); + mSpoilerBackgroundColor = customThemeWrapper.getSpoilerBackgroundColor(); + mSpoilerTextColor = customThemeWrapper.getSpoilerTextColor(); + mFlairBackgroundColor = customThemeWrapper.getFlairBackgroundColor(); + mFlairTextColor = customThemeWrapper.getFlairTextColor(); + mAwardsBackgroundColor = customThemeWrapper.getAwardsBackgroundColor(); + mAwardsTextColor = customThemeWrapper.getAwardsTextColor(); + mNSFWBackgroundColor = customThemeWrapper.getNsfwBackgroundColor(); + mNSFWTextColor = customThemeWrapper.getNsfwTextColor(); + mArchivedIconTint = customThemeWrapper.getArchivedIconTint(); + mLockedIconTint = customThemeWrapper.getLockedIconTint(); + mCrosspostIconTint = customThemeWrapper.getCrosspostIconTint(); + mNoPreviewPostTypeBackgroundColor = customThemeWrapper.getNoPreviewPostTypeBackgroundColor(); + mNoPreviewPostTypeIconTint = customThemeWrapper.getNoPreviewPostTypeIconTint(); + mUpvotedColor = customThemeWrapper.getUpvoted(); + mDownvotedColor = customThemeWrapper.getDownvoted(); + mVoteAndReplyUnavailableVoteButtonColor = customThemeWrapper.getVoteAndReplyUnavailableButtonColor(); + mButtonTextColor = customThemeWrapper.getButtonTextColor(); + mPostIconAndInfoColor = customThemeWrapper.getPostIconAndInfoColor(); + mDividerColor = customThemeWrapper.getDividerColor(); + + mCommentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); + if (mCommentIcon != null) { + DrawableCompat.setTint(mCommentIcon, mPostIconAndInfoColor); + } + + mScale = resources.getDisplayMetrics().density; + mGlide = Glide.with(mActivity); + mRedditDataRoomDatabase = redditDataRoomDatabase; + mLocale = locale; + mUserDao = redditDataRoomDatabase.userDao(); + mExoCreator = exoCreator; + mCallback = callback; + mShareLinkBottomSheetFragment = new ShareLinkBottomSheetFragment(); + } + } + + public void setCanStartActivity(boolean canStartActivity) { + this.canStartActivity = canStartActivity; + } + + @Override + public int getItemViewType(int position) { + // Reached at the end + if (hasExtraRow() && position == getItemCount() - 1) { + if (networkState.getStatus() == NetworkState.Status.LOADING) { + return VIEW_TYPE_LOADING; + } else { + return VIEW_TYPE_ERROR; + } + } else { + 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_VIDEO_AND_GIF_PREVIEW_TYPE; + } + return VIEW_TYPE_POST_CARD_VIDEO_AUTOPLAY_TYPE; + } + return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; + case Post.GIF_TYPE: + if (mAutoplay) { + if (!mAutoplayNsfwVideos && post.isNSFW()) { + return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; + } + return VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE; + } + return VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE; + case Post.IMAGE_TYPE: + return VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE; + case Post.LINK_TYPE: + return VIEW_TYPE_POST_CARD_LINK_TYPE; + case Post.NO_PREVIEW_LINK_TYPE: + return VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE; + case Post.GALLERY_TYPE: + return VIEW_TYPE_POST_CARD_GALLERY_TYPE; + default: + return VIEW_TYPE_POST_CARD_TEXT_TYPE; + } + } + return VIEW_TYPE_POST_CARD_TEXT_TYPE; + } else { + return VIEW_TYPE_POST_COMPACT; + } + } + } + + @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(R.layout.item_post_video_type_autoplay, parent, false)); + } else if (viewType == VIEW_TYPE_POST_CARD_VIDEO_AND_GIF_PREVIEW_TYPE + || viewType == VIEW_TYPE_POST_CARD_IMAGE_AND_GIF_AUTOPLAY_TYPE + || viewType == VIEW_TYPE_POST_CARD_LINK_TYPE + || viewType == VIEW_TYPE_POST_CARD_NO_PREVIEW_LINK_TYPE + || viewType == VIEW_TYPE_POST_CARD_GALLERY_TYPE) { + return new PostWithPreviewTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_with_preview, parent, false)); + } else if (viewType == VIEW_TYPE_POST_CARD_TEXT_TYPE) { + return new PostTextTypeViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_text, parent, false)); + } else if (viewType == VIEW_TYPE_POST_COMPACT) { + if (mShowThumbnailOnTheRightInCompactLayout) { + return new PostCompactRightThumbnailViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_compact_right_thumbnail, parent, false)); + } else { + return new PostCompactLeftThumbnailViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post_compact, parent, false)); + } + } else if (viewType == VIEW_TYPE_ERROR) { + return new ErrorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false)); + } else { + return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) { + if (holder instanceof PostBaseViewHolder) { + Post post = getItem(position); + if (post != null) { + String subredditNamePrefixed = post.getSubredditNamePrefixed(); + String subredditName = subredditNamePrefixed.substring(2); + String authorPrefixed = "u/" + post.getAuthor(); + String flair = post.getFlair(); + int nAwards = post.getnAwards(); + + ((PostBaseViewHolder) holder).subredditTextView.setText(subredditNamePrefixed); + ((PostBaseViewHolder) holder).userTextView.setText(authorPrefixed); + + if (mDisplaySubredditName) { + if (authorPrefixed.equals(subredditNamePrefixed)) { + if (post.getAuthorIconUrl() == null) { + new LoadUserDataAsyncTask(mUserDao, post.getAuthor(), mRetrofit, iconImageUrl -> { + if (mActivity != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getAuthorIconUrl().equals("")) { + mGlide.load(post.getAuthorIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((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) { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, + iconImageUrl -> { + if (mActivity != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setSubredditIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getSubredditIconUrl().equals("")) { + mGlide.load(post.getSubredditIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + } + } else { + if (post.getAuthorIconUrl() == null) { + String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditNamePrefixed().substring(2) : post.getAuthor(); + new LoadUserDataAsyncTask(mUserDao, authorName, mRetrofit, iconImageUrl -> { + if (mActivity != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getAuthorIconUrl().equals("")) { + mGlide.load(post.getAuthorIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((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()); + ((PostBaseViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + if (post.isLocked()) { + ((PostBaseViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); + } + + if (post.isNSFW()) { + ((PostBaseViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); + } + + if (post.isSpoiler()) { + ((PostBaseViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE); + } + + if (flair != null && !flair.equals("")) { + ((PostBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostBaseViewHolder) holder).flairTextView, flair, false); + } + + if (nAwards > 0) { + ((PostBaseViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + if (nAwards == 1) { + ((PostBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.one_award)); + } else { + ((PostBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.n_awards, nAwards)); + } + } + + 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 == PostDataSource.TYPE_SUBREDDIT && !mDisplaySubredditName && post.isStickied()) { + ((PostBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostBaseViewHolder) holder).stickiedPostImageView); + } + + if (post.isArchived()) { + ((PostBaseViewHolder) holder).archivedImageView.setVisibility(View.VISIBLE); + + ((PostBaseViewHolder) holder).upvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostBaseViewHolder) holder).downvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (post.isCrosspost()) { + ((PostBaseViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); + } + + ((PostBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(post.getNComments())); + + 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 (holder instanceof PostVideoAutoplayViewHolder) { + ((PostVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.VISIBLE); + Post.Preview preview = getSuitablePreview(post.getPreviews()); + if (preview != null) { + ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio((float) preview.getPreviewWidth() / preview.getPreviewHeight()); + if (mImageViewWidth > preview.getPreviewWidth()) { + mGlide.load(preview.getPreviewUrl()).override(Target.SIZE_ORIGINAL).into(((PostVideoAutoplayViewHolder) holder).previewImageView); + } else { + mGlide.load(preview.getPreviewUrl()).into(((PostVideoAutoplayViewHolder) holder).previewImageView); + } + } else { + ((PostVideoAutoplayViewHolder) holder).aspectRatioFrameLayout.setAspectRatio(1); + } + ((PostVideoAutoplayViewHolder) holder).setVolume(mMuteAutoplayingVideos || (post.isNSFW() && mMuteNSFWVideo) ? 0f : 1f); + + if (post.isGfycat() || post.isRedgifs() && !post.isLoadGfyOrRedgifsVideoSuccess()) { + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks = new FetchGfycatOrRedgifsVideoLinks(new FetchGfycatOrRedgifsVideoLinks.FetchGfycatOrRedgifsVideoLinksListener() { + @Override + public void success(String webm, String mp4) { + post.setVideoDownloadUrl(mp4); + post.setVideoUrl(webm); + post.setLoadGfyOrRedgifsVideoSuccess(true); + if (position == holder.getAdapterPosition()) { + ((PostVideoAutoplayViewHolder) holder).bindVideoUri(Uri.parse(post.getVideoUrl())); + } + } + + @Override + public void failed(int errorCode) { + if (position == holder.getAdapterPosition()) { + ((PostVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.VISIBLE); + } + } + }); + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks + .fetchGfycatOrRedgifsVideoLinksInRecyclerViewAdapter(mGfycatRetrofit, mRedgifsRetrofit, + post.getGfycatId(), post.isGfycat(), mAutomaticallyTryRedgifs); + } 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).typeTextView.setText(mActivity.getString(R.string.video)); + } else if (post.getPostType() == Post.GIF_TYPE) { + if (!mAutoplay) { + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.VISIBLE); + } + ((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); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).typeTextView.setText(mActivity.getString(R.string.gallery)); + } + + if (post.getPostType() != Post.NO_PREVIEW_LINK_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + } + + if (mDataSavingMode && mDisableImagePreview) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + if (post.getPostType() == Post.VIDEO_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_outline_video_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.IMAGE_TYPE || post.getPostType() == Post.GIF_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + } else if (post.getPostType() == Post.LINK_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); + } else if (post.getPostType() == Post.GALLERY_TYPE) { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + } else { + Post.Preview preview = getSuitablePreview(post.getPreviews()); + if (preview != null) { + ((PostWithPreviewTypeViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.VISIBLE); + if (preview.getPreviewWidth() <= 0 || preview.getPreviewHeight() <= 0) { + ((PostWithPreviewTypeViewHolder) holder).imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); + ((PostWithPreviewTypeViewHolder) holder).imageView.getLayoutParams().height = (int) (400 * mScale); + } else { + ((PostWithPreviewTypeViewHolder) holder).imageView + .setRatio((float) preview.getPreviewHeight() / preview.getPreviewWidth()); + } + loadImage(holder, post, preview); + } else { + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.VISIBLE); + } + } + } else if (holder instanceof PostTextTypeViewHolder) { + if (!post.isSpoiler() && post.getSelfTextPlainTrimmed() != null && !post.getSelfTextPlainTrimmed().equals("")) { + ((PostTextTypeViewHolder) holder).contentTextView.setVisibility(View.VISIBLE); + ((PostTextTypeViewHolder) holder).contentTextView.setText(post.getSelfTextPlainTrimmed()); + } + } + mCallback.currentlyBindItem(holder.getAdapterPosition()); + } + } else if (holder instanceof PostCompactBaseViewHolder) { + Post post = getItem(position); + if (post != null) { + final String subredditNamePrefixed = post.getSubredditNamePrefixed(); + String subredditName = subredditNamePrefixed.substring(2); + String authorPrefixed = "u/" + post.getAuthor(); + final String title = post.getTitle(); + int voteType = post.getVoteType(); + boolean nsfw = post.isNSFW(); + boolean spoiler = post.isSpoiler(); + String flair = post.getFlair(); + int nAwards = post.getnAwards(); + boolean isArchived = post.isArchived(); + + if (mDisplaySubredditName) { + if (authorPrefixed.equals(subredditNamePrefixed)) { + if (post.getAuthorIconUrl() == null) { + new LoadUserDataAsyncTask(mUserDao, post.getAuthor(), mRetrofit, iconImageUrl -> { + if (mActivity != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getAuthorIconUrl().equals("")) { + mGlide.load(post.getAuthorIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((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) { + new LoadSubredditIconAsyncTask(mRedditDataRoomDatabase, subredditName, mRetrofit, + iconImageUrl -> { + if (mActivity != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setSubredditIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getSubredditIconUrl().equals("")) { + mGlide.load(post.getSubredditIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((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); + ((PostCompactBaseViewHolder) holder).nameTextView.setText(subredditNamePrefixed); + } else { + if (post.getAuthorIconUrl() == null) { + String authorName = post.getAuthor().equals("[deleted]") ? post.getSubredditNamePrefixed().substring(2) : post.getAuthor(); + new LoadUserDataAsyncTask(mUserDao, authorName, mRetrofit, iconImageUrl -> { + if (mActivity != null && getItemCount() > 0) { + if (iconImageUrl == null || iconImageUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(iconImageUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + if (holder.getAdapterPosition() >= 0) { + post.setAuthorIconUrl(iconImageUrl); + } + } + }).execute(); + } else if (!post.getAuthorIconUrl().equals("")) { + mGlide.load(post.getAuthorIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((PostCompactBaseViewHolder) holder).iconGifImageView); + } + + ((PostCompactBaseViewHolder) holder).nameTextView.setTextColor(mUsernameColor); + ((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); + ((PostCompactBaseViewHolder) holder).scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + if (post.isLocked()) { + ((PostCompactBaseViewHolder) holder).lockedImageView.setVisibility(View.VISIBLE); + } + + if (nsfw) { + ((PostCompactBaseViewHolder) holder).nsfwTextView.setVisibility(View.VISIBLE); + } + + if (spoiler) { + ((PostCompactBaseViewHolder) holder).spoilerTextView.setVisibility(View.VISIBLE); + } + + if (flair != null && !flair.equals("")) { + ((PostCompactBaseViewHolder) holder).flairTextView.setVisibility(View.VISIBLE); + Utils.setHTMLWithImageToTextView(((PostCompactBaseViewHolder) holder).flairTextView, flair, false); + } + + if (nAwards > 0) { + ((PostCompactBaseViewHolder) holder).awardsTextView.setVisibility(View.VISIBLE); + if (nAwards == 1) { + ((PostCompactBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.one_award)); + } else { + ((PostCompactBaseViewHolder) holder).awardsTextView.setText(mActivity.getString(R.string.n_awards, nAwards)); + } + } + + switch (voteType) { + case 1: + //Upvoted + ((PostCompactBaseViewHolder) holder).upvoteButton.setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactBaseViewHolder) holder).scoreTextView.setTextColor(mUpvotedColor); + break; + case -1: + //Downvoted + ((PostCompactBaseViewHolder) holder).downvoteButton.setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactBaseViewHolder) holder).scoreTextView.setTextColor(mDownvotedColor); + break; + } + + if (post.getPostType() != Post.TEXT_TYPE && post.getPostType() != Post.NO_PREVIEW_LINK_TYPE && !(mDataSavingMode && mDisableImagePreview)) { + ((PostCompactBaseViewHolder) holder).relativeLayout.setVisibility(View.VISIBLE); + if (post.getPostType() != Post.GIF_TYPE && post.getPostType() != Post.VIDEO_TYPE) { + ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + } + if (post.getPostType() == Post.GALLERY_TYPE && post.getPreviews().isEmpty()) { + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); + } else { + ((PostCompactBaseViewHolder) holder).imageView.setVisibility(View.VISIBLE); + } + ArrayList previews = post.getPreviews(); + if (previews != null && !previews.isEmpty()) { + loadImage(holder, post, previews.get(0)); + } + } + + if (mPostType == PostDataSource.TYPE_SUBREDDIT && !mDisplaySubredditName && post.isStickied()) { + ((PostCompactBaseViewHolder) holder).stickiedPostImageView.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.ic_thumbtack_24dp).into(((PostCompactBaseViewHolder) holder).stickiedPostImageView); + } + + if (isArchived) { + ((PostCompactBaseViewHolder) holder).archivedImageView.setVisibility(View.VISIBLE); + + ((PostCompactBaseViewHolder) holder).upvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + ((PostCompactBaseViewHolder) holder).downvoteButton + .setColorFilter(mVoteAndReplyUnavailableVoteButtonColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + + if (post.isCrosspost()) { + ((PostCompactBaseViewHolder) holder).crosspostImageView.setVisibility(View.VISIBLE); + } + + switch (post.getPostType()) { + case Post.IMAGE_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.image); + if (mDataSavingMode && mDisableImagePreview) { + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); + } + break; + case Post.LINK_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.link); + if (mDataSavingMode && mDisableImagePreview) { + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.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) { + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_image_24dp); + } else { + ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.VISIBLE); + } + + break; + case Post.VIDEO_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.video); + if (mDataSavingMode && mDisableImagePreview) { + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_outline_video_24dp); + } else { + ((PostCompactBaseViewHolder) holder).playButtonImageView.setVisibility(View.VISIBLE); + } + + 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).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_link); + break; + case Post.GALLERY_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.gallery); + if (mDataSavingMode && mDisableImagePreview) { + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageFrameLayout.setVisibility(View.VISIBLE); + ((PostCompactBaseViewHolder) holder).noPreviewLinkImageView.setImageResource(R.drawable.ic_gallery_24dp); + } + break; + case Post.TEXT_TYPE: + ((PostCompactBaseViewHolder) holder).typeTextView.setText(R.string.text); + break; + } + + ((PostCompactBaseViewHolder) holder).commentsCountTextView.setText(Integer.toString(post.getNComments())); + + 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.getAdapterPosition()); + } + } + } + + @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() >= 75_000_000) { + for (int i = previews.size() - 1; i >= 1; i--) { + preview = previews.get(i); + if (mImageViewWidth >= preview.getPreviewWidth()) { + if (preview.getPreviewWidth() * preview.getPreviewHeight() <= 75_000_000) { + return preview; + } + } else { + int height = mImageViewWidth / preview.getPreviewWidth() * preview.getPreviewHeight(); + if (mImageViewWidth * height <= 75_000_000) { + return preview; + } + } + } + } + + int divisor = 2; + while (preview.getPreviewWidth() * preview.getPreviewHeight() / divisor / divisor > 75_000_000) { + preview.setPreviewWidth(preview.getPreviewWidth() / divisor); + preview.setPreviewHeight(preview.getPreviewHeight() / divisor); + divisor *= 2; + } + + return preview; + } + + return null; + } + + private void loadImage(final RecyclerView.ViewHolder holder, final Post post, @NonNull Post.Preview preview) { + if (preview != null) { + if (holder instanceof PostWithPreviewTypeViewHolder) { + String url; + if (post.getPostType() == Post.GIF_TYPE && mAutoplay) { + url = post.getUrl(); + } else { + url = preview.getPreviewUrl(); + } + RequestBuilder imageRequestBuilder = mGlide.load(url).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setOnClickListener(view -> { + ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.VISIBLE); + ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); + loadImage(holder, post, preview); + }); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + }); + + if ((post.isNSFW() && mNeedBlurNSFW && !(post.getPostType() == Post.GIF_TYPE && mAutoplayNsfwVideos)) || post.isSpoiler() && mNeedBlurSpoiler) { + imageRequestBuilder.apply(RequestOptions.bitmapTransform(new BlurTransformation(50, 10))) + .into(((PostWithPreviewTypeViewHolder) holder).imageView); + } else { + if (mImageViewWidth > preview.getPreviewWidth()) { + imageRequestBuilder.override(Target.SIZE_ORIGINAL).into(((PostWithPreviewTypeViewHolder) holder).imageView); + } else { + imageRequestBuilder.into(((PostWithPreviewTypeViewHolder) holder).imageView); + } + } + } else if (holder instanceof PostCompactBaseViewHolder) { + String postCompactThumbnailPreviewUrl; + ArrayList previews = post.getPreviews(); + if (previews != null && !previews.isEmpty()) { + if (previews.size() >= 2) { + postCompactThumbnailPreviewUrl = previews.get(1).getPreviewUrl(); + } else { + postCompactThumbnailPreviewUrl = preview.getPreviewUrl(); + } + + RequestBuilder imageRequestBuilder = mGlide.load(postCompactThumbnailPreviewUrl) + .error(R.drawable.ic_error_outline_black_24dp).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + + @Override + public boolean onResourceReady(Drawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + ((PostCompactBaseViewHolder) holder).progressBar.setVisibility(View.GONE); + return false; + } + }); + if ((post.isNSFW() && mNeedBlurNSFW) || post.isSpoiler() && mNeedBlurSpoiler) { + imageRequestBuilder + .transform(new BlurTransformation(50, 2)).into(((PostCompactBaseViewHolder) holder).imageView); + } else { + imageRequestBuilder.into(((PostCompactBaseViewHolder) 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; + } + } + mShareLinkBottomSheetFragment.setArguments(bundle); + mShareLinkBottomSheetFragment.show(mActivity.getSupportFragmentManager(), mShareLinkBottomSheetFragment.getTag()); + } + + @Override + public int getItemCount() { + if (hasExtraRow()) { + return super.getItemCount() + 1; + } + return super.getItemCount(); + } + + @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 setBlurNSFW(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; + } + + private boolean hasExtraRow() { + return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; + } + + public void setNetworkState(NetworkState newNetworkState) { + NetworkState previousState = this.networkState; + boolean previousExtraRow = hasExtraRow(); + this.networkState = newNetworkState; + boolean newExtraRow = hasExtraRow(); + if (previousExtraRow != newExtraRow) { + if (previousExtraRow) { + notifyItemRemoved(getItemCount() - 1); + } else { + notifyItemInserted(super.getItemCount()); + } + } else if (newExtraRow && !previousState.equals(newNetworkState)) { + notifyItemChanged(getItemCount() - 1); + } + } + + public void removeFooter() { + if (hasExtraRow()) { + notifyItemRemoved(getItemCount() - 1); + } + + networkState = null; + } + + 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; + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof PostBaseViewHolder) { + if (holder instanceof PostVideoAutoplayViewHolder) { + ((PostVideoAutoplayViewHolder) holder).mediaUri = null; + if (((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks != null) { + ((PostVideoAutoplayViewHolder) holder).fetchGfycatOrRedgifsVideoLinks.cancel(); + } + ((PostVideoAutoplayViewHolder) holder).errorLoadingGfycatImageView.setVisibility(View.GONE); + ((PostVideoAutoplayViewHolder) holder).muteButton.setVisibility(View.GONE); + ((PostVideoAutoplayViewHolder) holder).resetVolume(); + mGlide.clear(((PostVideoAutoplayViewHolder) holder).previewImageView); + ((PostVideoAutoplayViewHolder) holder).previewImageView.setVisibility(View.GONE); + } else if (holder instanceof PostWithPreviewTypeViewHolder) { + mGlide.clear(((PostWithPreviewTypeViewHolder) holder).imageView); + ((PostWithPreviewTypeViewHolder) holder).imageWrapperRelativeLayout.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).errorRelativeLayout.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).noPreviewLinkImageView.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).progressBar.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).videoOrGifIndicatorImageView.setVisibility(View.GONE); + ((PostWithPreviewTypeViewHolder) holder).linkTextView.setVisibility(View.GONE); + } else if (holder instanceof PostTextTypeViewHolder) { + ((PostTextTypeViewHolder) holder).contentTextView.setText(""); + ((PostTextTypeViewHolder) holder).contentTextView.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) { + 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).noPreviewLinkImageFrameLayout.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); + } + } + + @Nullable + @Override + public Object getKeyForOrder(int order) { + if (super.getItemCount() <= 0 || order >= super.getItemCount()) { + return null; + } + return getItem(order); + } + + @Nullable + @Override + public Integer getOrderForKey(@NonNull Object key) { + if (getCurrentList() != null && key instanceof Post) { + return getCurrentList().indexOf(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 retryLoadingMore(); + + void typeChipClicked(int filter); + + void currentlyBindItem(int position); + + void delayTransition(); + } + + public class PostBaseViewHolder extends RecyclerView.ViewHolder { + MaterialCardView cardView; + 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; + + PostBaseViewHolder(@NonNull View itemView) { + super(itemView); + } + + void setBaseView(MaterialCardView cardView, + 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.cardView = cardView; + 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); + } + + itemView.setBackgroundTintList(ColorStateList.valueOf(mCardViewBackgroundColor)); + 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); + + cardView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position >= 0 && canStartActivity) { + canStartActivity = false; + + Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, getItem(position)); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_LIST_POSITION, getAdapterPosition()); + mActivity.startActivity(intent); + } + }); + + userTextView.setOnClickListener(view -> { + if (canStartActivity) { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + canStartActivity = false; + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); + mActivity.startActivity(intent); + } + } + }); + + if (mDisplaySubredditName) { + subredditTextView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (canStartActivity) { + canStartActivity = false; + if (post.getSubredditNamePrefixed().startsWith("u/")) { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, + post.getSubredditNamePrefixed().substring(2)); + mActivity.startActivity(intent); + } else { + 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 = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (canStartActivity) { + canStartActivity = false; + if (post.getSubredditNamePrefixed().startsWith("u/")) { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); + mActivity.startActivity(intent); + } else { + 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 FilteredThingActivity)) { + nsfwTextView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + Intent intent = new Intent(mActivity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, post.getSubredditNamePrefixed().substring(2)); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, Post.NSFW_TYPE); + mActivity.startActivity(intent); + } + }); + typeTextView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + mCallback.typeChipClicked(post.getPostType()); + } + }); + } + + upvoteButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != 1) { + //Not upvoted before + post.setVoteType(1); + newVoteType = APIUtils.DIR_UPVOTE; + upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + post.setVoteType(1); + upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + post.setVoteType(0); + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }, post.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + downvoteButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != -1) { + //Not downvoted before + post.setVoteType(-1); + newVoteType = APIUtils.DIR_DOWNVOTE; + downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + post.setVoteType(-1); + downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + post.setVoteType(0); + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }, post.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + saveButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + if (post.isSaved()) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(false); + 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 PostUpdateEventToDetailActivity(post)); + } + + @Override + public void failed() { + post.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }); + } else { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void failed() { + post.setSaved(false); + 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 PostUpdateEventToDetailActivity(post)); + } + }); + } + } + }); + + shareButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + shareLink(post); + } + }); + } + } + + class PostVideoAutoplayViewHolder extends PostBaseViewHolder implements ToroPlayer { + @BindView(R.id.card_view_item_post_video_type_autoplay) + MaterialCardView cardView; + @BindView(R.id.icon_gif_image_view_item_post_video_type_autoplay) + AspectRatioGifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_post_video_type_autoplay) + TextView subredditTextView; + @BindView(R.id.user_text_view_item_post_video_type_autoplay) + TextView userTextView; + @BindView(R.id.stickied_post_image_view_item_post_video_type_autoplay) + ImageView stickiedPostImageView; + @BindView(R.id.post_time_text_view_item_post_video_type_autoplay) + TextView postTimeTextView; + @BindView(R.id.title_text_view_item_post_video_type_autoplay) + TextView titleTextView; + @BindView(R.id.type_text_view_item_post_video_type_autoplay) + CustomTextView typeTextView; + @BindView(R.id.archived_image_view_item_post_video_type_autoplay) + ImageView archivedImageView; + @BindView(R.id.locked_image_view_item_post_video_type_autoplay) + ImageView lockedImageView; + @BindView(R.id.crosspost_image_view_item_post_video_type_autoplay) + ImageView crosspostImageView; + @BindView(R.id.nsfw_text_view_item_post_video_type_autoplay) + CustomTextView nsfwTextView; + @BindView(R.id.spoiler_custom_text_view_item_post_video_type_autoplay) + CustomTextView spoilerTextView; + @BindView(R.id.flair_custom_text_view_item_post_video_type_autoplay) + CustomTextView flairTextView; + @BindView(R.id.awards_text_view_item_post_video_type_autoplay) + CustomTextView awardsTextView; + @BindView(R.id.aspect_ratio_frame_layout_item_post_video_type_autoplay) + AspectRatioFrameLayout aspectRatioFrameLayout; + @BindView(R.id.preview_image_view_item_post_video_type_autoplay) + GifImageView previewImageView; + @BindView(R.id.error_loading_gfycat_image_view_item_post_video_type_autoplay) + ImageView errorLoadingGfycatImageView; + @BindView(R.id.player_view_item_post_video_type_autoplay) + PlayerView videoPlayer; + @BindView(R.id.mute_exo_playback_control_view) + ImageView muteButton; + @BindView(R.id.fullscreen_exo_playback_control_view) + ImageView fullscreenButton; + @BindView(R.id.bottom_constraint_layout_item_post_video_type_autoplay) + ConstraintLayout bottomConstraintLayout; + @BindView(R.id.plus_button_item_post_video_type_autoplay) + ImageView upvoteButton; + @BindView(R.id.score_text_view_item_post_video_type_autoplay) + TextView scoreTextView; + @BindView(R.id.minus_button_item_post_video_type_autoplay) + ImageView downvoteButton; + @BindView(R.id.comments_count_item_post_video_type_autoplay) + TextView commentsCountTextView; + @BindView(R.id.save_button_item_post_video_type_autoplay) + ImageView saveButton; + @BindView(R.id.share_button_item_post_video_type_autoplay) + ImageView shareButton; + + @Nullable + ExoPlayerViewHelper helper; + private Uri mediaUri; + private float volume; + public FetchGfycatOrRedgifsVideoLinks fetchGfycatOrRedgifsVideoLinks; + + PostVideoAutoplayViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(cardView, + 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(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + helper.setVolume(0f); + volume = 0f; + } else { + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + helper.setVolume(1f); + volume = 1f; + } + } + }); + + fullscreenButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + if (post.isGfycat()) { + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_TYPE, ViewVideoActivity.VIDEO_TYPE_GFYCAT); + intent.putExtra(ViewVideoActivity.EXTRA_GFYCAT_ID, post.getGfycatId()); + if (post.isLoadGfyOrRedgifsVideoSuccess()) { + 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.isLoadGfyOrRedgifsVideoSuccess()) { + intent.setData(Uri.parse(post.getVideoUrl())); + intent.putExtra(ViewVideoActivity.EXTRA_VIDEO_DOWNLOAD_URL, post.getVideoDownloadUrl()); + } + } 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.setOnLongClickListener(view -> fullscreenButton.performClick()); + videoPlayer.setOnLongClickListener(view -> fullscreenButton.performClick()); + } + + void bindVideoUri(Uri videoUri) { + mediaUri = videoUri; + } + + void setVolume(float volume) { + this.volume = volume; + } + + void resetVolume() { + volume = 0f; + } + + @NonNull + @Override + public View getPlayerView() { + return videoPlayer; + } + + @NonNull + @Override + public PlaybackInfo getCurrentPlaybackInfo() { + return helper != null && mediaUri != null ? helper.getLatestPlaybackInfo() : new PlaybackInfo(); + } + + @Override + public void initialize(@NonNull Container container, @NonNull PlaybackInfo playbackInfo) { + if (mediaUri == null) { + return; + } + if (helper == null) { + helper = new ExoPlayerViewHelper(this, mediaUri, null, mExoCreator); + helper.addEventListener(new Playable.EventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + helper.setVolume(volume); + muteButton.setVisibility(View.VISIBLE); + if (volume != 0f) { + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_unmute_white_rounded_18dp)); + } else { + muteButton.setImageDrawable(mActivity.getDrawable(R.drawable.ic_mute_white_rounded_18dp)); + } + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + + @Override + public void onMetadata(Metadata metadata) { + + } + + @Override + public void onCues(List cues) { + + } + + @Override + public void onRenderedFirstFrame() { + mGlide.clear(previewImageView); + previewImageView.setVisibility(View.GONE); + } + }); + } + helper.initialize(container, playbackInfo); + } + + @Override + public void play() { + if (helper != null && mediaUri != null) { + helper.play(); + } + } + + @Override + public void pause() { + if (helper != null) helper.pause(); + } + + @Override + public boolean isPlaying() { + return helper != null && helper.isPlaying(); + } + + @Override + public void release() { + if (helper != null) { + helper.release(); + helper = null; + } + } + + @Override + public boolean wantsToPlay() { + return mediaUri != null && ToroUtil.visibleAreaOffset(this, itemView.getParent()) >= mStartAutoplayVisibleAreaOffset; + } + + @Override + public int getPlayerOrder() { + return getAdapterPosition(); + } + } + + class PostWithPreviewTypeViewHolder extends PostBaseViewHolder { + @BindView(R.id.card_view_item_post_with_preview) + MaterialCardView cardView; + @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) + RelativeLayout 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_relative_layout_item_post_with_preview) + RelativeLayout errorRelativeLayout; + @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; + + PostWithPreviewTypeViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(cardView, + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton); + + linkTextView.setTextColor(mSecondaryTextColor); + noPreviewLinkImageView.setBackgroundColor(mNoPreviewPostTypeBackgroundColor); + noPreviewLinkImageView.setColorFilter(mNoPreviewPostTypeIconTint, android.graphics.PorterDuff.Mode.SRC_IN); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + errorTextView.setTextColor(mPrimaryTextColor); + + imageView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.getPostType() == Post.VIDEO_TYPE) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + 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 { + 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()); + 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()); + 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()); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(post.getUrl())); + } else { + 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()); + mActivity.startActivity(intent); + } + } + }); + + noPreviewLinkImageView.setOnClickListener(view -> { + imageView.performClick(); + }); + } + } + + class PostTextTypeViewHolder extends PostBaseViewHolder { + @BindView(R.id.card_view_item_post_text_type) + MaterialCardView cardView; + @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(cardView, + iconGifImageView, + subredditTextView, + userTextView, + stickiedPostImageView, + postTimeTextView, + titleTextView, + typeTextView, + archivedImageView, + lockedImageView, + crosspostImageView, + nsfwTextView, + spoilerTextView, + flairTextView, + awardsTextView, + bottomConstraintLayout, + upvoteButton, + scoreTextView, + downvoteButton, + commentsCountTextView, + saveButton, + shareButton); + + 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 noPreviewLinkImageFrameLayout; + ImageView noPreviewLinkImageView; + Barrier imageBarrier; + ConstraintLayout bottomConstraintLayout; + ImageView upvoteButton; + TextView scoreTextView; + ImageView downvoteButton; + TextView commentsCountTextView; + ImageView saveButton; + ImageView shareButton; + View divider; + + 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.noPreviewLinkImageFrameLayout = noPreviewLinkImageFrameLayout; + this.noPreviewLinkImageView = 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); + } + + 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); + 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 = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && canStartActivity) { + canStartActivity = false; + + Intent intent = new Intent(mActivity, ViewPostDetailActivity.class); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_DATA, post); + intent.putExtra(ViewPostDetailActivity.EXTRA_POST_LIST_POSITION, getAdapterPosition()); + mActivity.startActivity(intent); + } + }); + + itemView.setOnLongClickListener(view -> { + if (mLongPressToHideToolbarInCompactLayout) { + if (bottomConstraintLayout.getLayoutParams().height == 0) { + ViewGroup.LayoutParams params = (LinearLayout.LayoutParams) bottomConstraintLayout.getLayoutParams(); + params.height = LinearLayout.LayoutParams.WRAP_CONTENT; + bottomConstraintLayout.setLayoutParams(params); + mCallback.delayTransition(); + } else { + mCallback.delayTransition(); + ViewGroup.LayoutParams params = (LinearLayout.LayoutParams) bottomConstraintLayout.getLayoutParams(); + params.height = 0; + bottomConstraintLayout.setLayoutParams(params); + } + } + return true; + }); + + nameTextView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && canStartActivity) { + canStartActivity = false; + if (mDisplaySubredditName) { + if (post.getSubredditNamePrefixed().startsWith("u/")) { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, + post.getSubredditNamePrefixed().substring(2)); + mActivity.startActivity(intent); + } else { + Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, + post.getSubredditNamePrefixed().substring(2)); + mActivity.startActivity(intent); + } + } else { + Intent intent = new Intent(mActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, post.getAuthor()); + mActivity.startActivity(intent); + } + } + }); + + iconGifImageView.setOnClickListener(view -> nameTextView.performClick()); + + nsfwTextView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && !(mActivity instanceof FilteredThingActivity)) { + Intent intent = new Intent(mActivity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, post.getSubredditNamePrefixed().substring(2)); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, PostDataSource.TYPE_SUBREDDIT); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, Post.NSFW_TYPE); + mActivity.startActivity(intent); + } + }); + + typeTextView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null && !(mActivity instanceof FilteredThingActivity)) { + mCallback.typeChipClicked(post.getPostType()); + } + }); + + imageView.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.getPostType() == Post.VIDEO_TYPE) { + Intent intent = new Intent(mActivity, ViewVideoActivity.class); + 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 { + 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()); + 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()); + 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()); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(post.getUrl())); + } else { + 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()); + mActivity.startActivity(intent); + } + } + }); + + 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 = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != 1) { + //Not upvoted before + post.setVoteType(1); + newVoteType = APIUtils.DIR_UPVOTE; + upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + //Upvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(APIUtils.DIR_UPVOTE)) { + post.setVoteType(1); + upvoteButton + .setColorFilter(mUpvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mUpvotedColor); + } else { + post.setVoteType(0); + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }, post.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + downvoteButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.isArchived()) { + Toast.makeText(mActivity, R.string.archived_post_vote_unavailable, Toast.LENGTH_SHORT).show(); + return; + } + + ColorFilter previousUpvoteButtonColorFilter = upvoteButton.getColorFilter(); + ColorFilter previousDownvoteButtonColorFilter = downvoteButton.getColorFilter(); + int previousScoreTextViewColor = scoreTextView.getCurrentTextColor(); + + int previousVoteType = post.getVoteType(); + String newVoteType; + + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + + if (previousVoteType != -1) { + //Not downvoted before + post.setVoteType(-1); + newVoteType = APIUtils.DIR_DOWNVOTE; + downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + //Downvoted before + post.setVoteType(0); + newVoteType = APIUtils.DIR_UNVOTE; + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + VoteThing.voteThing(mActivity, mOauthRetrofit, mAccessToken, new VoteThing.VoteThingListener() { + @Override + public void onVoteThingSuccess(int position1) { + if (newVoteType.equals(APIUtils.DIR_DOWNVOTE)) { + post.setVoteType(-1); + downvoteButton + .setColorFilter(mDownvotedColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mDownvotedColor); + } else { + post.setVoteType(0); + downvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setTextColor(mPostIconAndInfoColor); + } + + upvoteButton.setColorFilter(mPostIconAndInfoColor, android.graphics.PorterDuff.Mode.SRC_IN); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + post.getVoteType())); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void onVoteThingFail(int position1) { + Toast.makeText(mActivity, R.string.vote_failed, Toast.LENGTH_SHORT).show(); + post.setVoteType(previousVoteType); + scoreTextView.setText(Utils.getNVotes(mShowAbsoluteNumberOfVotes, post.getScore() + previousVoteType)); + upvoteButton.setColorFilter(previousUpvoteButtonColorFilter); + downvoteButton.setColorFilter(previousDownvoteButtonColorFilter); + scoreTextView.setTextColor(previousScoreTextViewColor); + + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }, post.getFullName(), newVoteType, getAdapterPosition()); + } + }); + + saveButton.setOnClickListener(view -> { + if (mAccessToken == null) { + Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); + return; + } + + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + if (post.isSaved()) { + saveButton.setImageResource(R.drawable.ic_bookmark_border_grey_24dp); + SaveThing.unsaveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(false); + 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 PostUpdateEventToDetailActivity(post)); + } + + @Override + public void failed() { + post.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.post_unsaved_failed, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + }); + } else { + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + SaveThing.saveThing(mOauthRetrofit, mAccessToken, post.getFullName(), + new SaveThing.SaveThingListener() { + @Override + public void success() { + post.setSaved(true); + saveButton.setImageResource(R.drawable.ic_bookmark_grey_24dp); + Toast.makeText(mActivity, R.string.post_saved_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new PostUpdateEventToDetailActivity(post)); + } + + @Override + public void failed() { + post.setSaved(false); + 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 PostUpdateEventToDetailActivity(post)); + } + }); + } + } + }); + + shareButton.setOnClickListener(view -> { + int position = getAdapterPosition(); + if (position < 0) { + return; + } + Post post = getItem(position); + if (post != null) { + shareLink(post); + } + }); + } + } + + 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 ErrorViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_footer_error) + TextView errorTextView; + @BindView(R.id.retry_button_item_footer_error) + Button retryButton; + + ErrorViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + errorTextView.setText(R.string.load_more_posts_error); + errorTextView.setTextColor(mSecondaryTextColor); + retryButton.setOnClickListener(view -> mCallback.retryLoadingMore()); + retryButton.setBackgroundTintList(ColorStateList.valueOf(mColorPrimaryLightTheme)); + retryButton.setTextColor(mButtonTextColor); + itemView.setOnClickListener(view -> retryButton.performClick()); + } + } + + class LoadingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_footer_loading) + ProgressBar progressBar; + + LoadingViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(mColorAccent)); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java new file mode 100644 index 00000000..f9426006 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/PrivateMessagesDetailRecyclerViewAdapter.java @@ -0,0 +1,277 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Color; +import android.net.Uri; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +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 com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import java.util.Locale; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPrivateMessagesActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.message.Message; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; + +public class PrivateMessagesDetailRecyclerViewAdapter extends RecyclerView.Adapter { + private static final int VIEW_TYPE_MESSAGE_SENT = 0; + private static final int VIEW_TYPE_MESSAGE_RECEIVED = 1; + private Message mMessage; + private ViewPrivateMessagesActivity mViewPrivateMessagesActivity; + private RequestManager mGlide; + private Locale mLocale; + private String mAccountName; + private Markwon mMarkwon; + private boolean mShowElapsedTime; + private String mTimeFormatPattern; + private int mSecondaryTextColor; + private int mReceivedMessageTextColor; + private int mSentMessageTextColor; + private int mReceivedMessageBackgroundColor; + private int mSentMessageBackgroundColor; + + public PrivateMessagesDetailRecyclerViewAdapter(ViewPrivateMessagesActivity viewPrivateMessagesActivity, + SharedPreferences sharedPreferences, Locale locale, + Message message, String accountName, + CustomThemeWrapper customThemeWrapper) { + mMessage = message; + mViewPrivateMessagesActivity = viewPrivateMessagesActivity; + mGlide = Glide.with(viewPrivateMessagesActivity); + mLocale = locale; + mAccountName = accountName; + mMarkwon = Markwon.builder(viewPrivateMessagesActivity) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(viewPrivateMessagesActivity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + viewPrivateMessagesActivity.startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(customThemeWrapper.getLinkColor()); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .build(); + mShowElapsedTime = sharedPreferences.getBoolean(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY, false); + mTimeFormatPattern = sharedPreferences.getString(SharedPreferencesUtils.TIME_FORMAT_KEY, SharedPreferencesUtils.TIME_FORMAT_DEFAULT_VALUE); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + mReceivedMessageTextColor = customThemeWrapper.getReceivedMessageTextColor(); + mSentMessageTextColor = customThemeWrapper.getSentMessageTextColor(); + mReceivedMessageBackgroundColor = customThemeWrapper.getReceivedMessageBackgroundColor(); + mSentMessageBackgroundColor = customThemeWrapper.getSentMessageBackgroundColor(); + } + + @Override + public int getItemViewType(int position) { + if (position == 0) { + return mMessage.getAuthor().equals(mAccountName) ? VIEW_TYPE_MESSAGE_SENT : VIEW_TYPE_MESSAGE_RECEIVED; + } else { + return mMessage.getReplies().get(position - 1).getAuthor().equals(mAccountName) ? VIEW_TYPE_MESSAGE_SENT : VIEW_TYPE_MESSAGE_RECEIVED; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_MESSAGE_SENT) { + return new SentMessageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_private_message_sent, parent, false)); + } else { + return new ReceivedMessageViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_private_message_received, parent, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + Message message; + if (holder.getAdapterPosition() == 0) { + message = mMessage; + } else { + message = mMessage.getReplies().get(holder.getAdapterPosition() - 1); + } + if (message != null) { + if (holder instanceof MessageViewHolder) { + mMarkwon.setMarkdown(((MessageViewHolder) holder).messageTextView, message.getBody()); + + ((MessageViewHolder) holder).messageTextView.setOnClickListener(view -> ((MessageViewHolder) holder).itemView.performClick()); + if (mShowElapsedTime) { + ((MessageViewHolder) holder).timeTextView.setText(Utils.getElapsedTime(mViewPrivateMessagesActivity, message.getTimeUTC())); + } else { + ((MessageViewHolder) holder).timeTextView.setText(Utils.getFormattedTime(mLocale, message.getTimeUTC(), mTimeFormatPattern)); + } + + ((MessageViewHolder) holder).messageTextView.setOnClickListener(view -> { + if (((MessageViewHolder) holder).timeTextView.getVisibility() != View.VISIBLE) { + ((MessageViewHolder) holder).timeTextView.setVisibility(View.VISIBLE); + mViewPrivateMessagesActivity.delayTransition(); + } else { + ((MessageViewHolder) holder).timeTextView.setVisibility(View.GONE); + mViewPrivateMessagesActivity.delayTransition(); + } + }); + } + + if (holder instanceof SentMessageViewHolder) { + ((SentMessageViewHolder) holder).messageTextView.setBackground(Utils.getTintedDrawable(mViewPrivateMessagesActivity, + R.drawable.private_message_ballon, mSentMessageBackgroundColor)); + } else if (holder instanceof ReceivedMessageViewHolder) { + mViewPrivateMessagesActivity.fetchUserAvatar(message.getAuthor(), userAvatarUrl -> { + if (userAvatarUrl == null || userAvatarUrl.equals("")) { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((ReceivedMessageViewHolder) holder).userAvatarImageView); + } else { + mGlide.load(userAvatarUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((ReceivedMessageViewHolder) holder).userAvatarImageView); + } + }); + + ((ReceivedMessageViewHolder) holder).userAvatarImageView.setOnClickListener(view -> { + Intent intent = new Intent(mViewPrivateMessagesActivity, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, message.getAuthor()); + mViewPrivateMessagesActivity.startActivity(intent); + }); + + ((ReceivedMessageViewHolder) holder).messageTextView.setBackground( + Utils.getTintedDrawable(mViewPrivateMessagesActivity, + R.drawable.private_message_ballon, mReceivedMessageBackgroundColor)); + } + } + } + + @Override + public int getItemCount() { + if (mMessage == null) { + return 0; + } else if (mMessage.getReplies() == null) { + return 1; + } else { + return 1 + mMessage.getReplies().size(); + } + } + + public void setMessage(Message message) { + mMessage = message; + notifyDataSetChanged(); + } + + public void addReply(Message reply) { + int currentSize = getItemCount(); + + if (mMessage != null) { + mMessage.addReply(reply); + } else { + mMessage = reply; + } + + notifyItemInserted(currentSize); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof MessageViewHolder) { + ((MessageViewHolder) holder).messageTextView.setBackground(null); + ((MessageViewHolder) holder).timeTextView.setVisibility(View.GONE); + } + if (holder instanceof ReceivedMessageViewHolder) { + mGlide.clear(((ReceivedMessageViewHolder) holder).userAvatarImageView); + } + } + + class MessageViewHolder extends RecyclerView.ViewHolder { + TextView messageTextView; + TextView timeTextView; + + public MessageViewHolder(@NonNull View itemView) { + super(itemView); + } + + void setBaseView(TextView messageTextView, TextView timeTextView) { + this.messageTextView = messageTextView; + this.timeTextView = timeTextView; + + messageTextView.setTextColor(Color.WHITE); + timeTextView.setTextColor(mSecondaryTextColor); + } + } + + class SentMessageViewHolder extends MessageViewHolder { + @BindView(R.id.message_text_view_item_private_message_sent) + TextView messageTextView; + @BindView(R.id.time_text_view_item_private_message_sent) + TextView timeTextView; + + SentMessageViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(messageTextView, timeTextView); + + messageTextView.setTextColor(mSentMessageTextColor); + + } + } + + class ReceivedMessageViewHolder extends MessageViewHolder { + @BindView(R.id.avatar_image_view_item_private_message_received) + ImageView userAvatarImageView; + @BindView(R.id.message_text_view_item_private_message_received) + TextView messageTextView; + @BindView(R.id.time_text_view_item_private_message_received) + TextView timeTextView; + + ReceivedMessageViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + setBaseView(messageTextView, timeTextView); + + messageTextView.setTextColor(mReceivedMessageTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/ReportReasonRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/ReportReasonRecyclerViewAdapter.java new file mode 100644 index 00000000..4bb9c255 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/ReportReasonRecyclerViewAdapter.java @@ -0,0 +1,130 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.res.ColorStateList; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.ReportReason; + +public class ReportReasonRecyclerViewAdapter extends RecyclerView.Adapter { + + private ArrayList generalReasons; + private ArrayList rules; + private int primaryTextColor; + private int colorAccent; + + public ReportReasonRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList generalReasons) { + this.generalReasons = generalReasons; + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + colorAccent = customThemeWrapper.getColorAccent(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new ReasonViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_report_reason, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof ReasonViewHolder) { + ReportReason reportReason; + if (position >= generalReasons.size()) { + reportReason = rules.get(holder.getAdapterPosition() - generalReasons.size()); + } else { + reportReason = generalReasons.get(holder.getAdapterPosition()); + } + ((ReasonViewHolder) holder).reasonTextView.setText(reportReason.getReportReason()); + ((ReasonViewHolder) holder).checkBox.setChecked(reportReason.isSelected()); + } + } + + @Override + public int getItemCount() { + return rules == null ? generalReasons.size() : rules.size() + generalReasons.size(); + } + + public void setRules(ArrayList reportReasons) { + this.rules = reportReasons; + notifyDataSetChanged(); + } + + public ReportReason getSelectedReason() { + for (ReportReason reportReason : rules) { + if (reportReason.isSelected()) { + return reportReason; + } + } + + for (ReportReason reportReason : generalReasons) { + if (reportReason.isSelected()) { + return reportReason; + } + } + + return null; + } + + public ArrayList getGeneralReasons() { + return generalReasons; + } + + public ArrayList getRules() { + return rules; + } + + class ReasonViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.reason_text_view_item_report_reason) + TextView reasonTextView; + @BindView(R.id.check_box_item_report_reason) + CheckBox checkBox; + + ReasonViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + reasonTextView.setTextColor(primaryTextColor); + checkBox.setButtonTintList(ColorStateList.valueOf(colorAccent)); + + checkBox.setOnClickListener(view -> { + for (int i = 0; i < generalReasons.size(); i++) { + if (generalReasons.get(i).isSelected()) { + generalReasons.get(i).setSelected(false); + notifyItemChanged(i); + + } + } + + if (rules != null) { + for (int i = 0; i < rules.size(); i++) { + if (rules.get(i).isSelected()) { + rules.get(i).setSelected(false); + notifyItemChanged(i + generalReasons.size()); + } + } + } + + if (getAdapterPosition() >= generalReasons.size()) { + rules.get(getAdapterPosition() - generalReasons.size()).setSelected(checkBox.isChecked()); + } else { + generalReasons.get(getAdapterPosition()).setSelected(checkBox.isChecked()); + } + }); + + itemView.setOnClickListener(view -> checkBox.performClick()); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java new file mode 100644 index 00000000..ee728b96 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/RulesRecyclerViewAdapter.java @@ -0,0 +1,118 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +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.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.Rule; + +public class RulesRecyclerViewAdapter extends RecyclerView.Adapter { + private Markwon markwon; + private ArrayList rules; + private int mPrimaryTextColor; + private int mSecondaryTextColor; + + public RulesRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper) { + markwon = Markwon.builder(context) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(context, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + context.startActivity(intent); + }); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(customThemeWrapper.getLinkColor()); + } + }) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .build(); + mPrimaryTextColor = customThemeWrapper.getPrimaryTextColor(); + mSecondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + } + + @NonNull + @Override + public RuleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new RuleViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rule, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RuleViewHolder holder, int position) { + holder.shortNameTextView.setText(rules.get(holder.getAdapterPosition()).getShortName()); + if (rules.get(holder.getAdapterPosition()).getDescriptionHtml() == null) { + holder.descriptionMarkwonView.setVisibility(View.GONE); + } else { + markwon.setMarkdown(holder.descriptionMarkwonView, rules.get(holder.getAdapterPosition()).getDescriptionHtml()); + } + } + + @Override + public int getItemCount() { + return rules == null ? 0 : rules.size(); + } + + @Override + public void onViewRecycled(@NonNull RuleViewHolder holder) { + super.onViewRecycled(holder); + holder.descriptionMarkwonView.setVisibility(View.VISIBLE); + } + + public void changeDataset(ArrayList rules) { + this.rules = rules; + notifyDataSetChanged(); + } + + class RuleViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.short_name_text_view_item_rule) + TextView shortNameTextView; + @BindView(R.id.description_markwon_view_item_rule) + TextView descriptionMarkwonView; + + RuleViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + shortNameTextView.setTextColor(mPrimaryTextColor); + descriptionMarkwonView.setTextColor(mSecondaryTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SearchActivityRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SearchActivityRecyclerViewAdapter.java new file mode 100644 index 00000000..f4da7bd7 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SearchActivityRecyclerViewAdapter.java @@ -0,0 +1,94 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.app.Activity; +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 ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.recentsearchquery.RecentSearchQuery; +import ml.docilealligator.infinityforreddit.utils.Utils; + +public class SearchActivityRecyclerViewAdapter extends RecyclerView.Adapter { + private List recentSearchQueries; + private int primaryTextColor; + private Drawable historyIcon; + private Drawable deleteIcon; + private ItemOnClickListener itemOnClickListener; + + public interface ItemOnClickListener { + void onClick(String query); + void onDelete(RecentSearchQuery recentSearchQuery); + } + + public SearchActivityRecyclerViewAdapter(Activity activity, CustomThemeWrapper customThemeWrapper, + ItemOnClickListener itemOnClickListener) { + this.primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + this.historyIcon = Utils.getTintedDrawable(activity, R.drawable.ic_history_24dp, customThemeWrapper.getPrimaryIconColor()); + this.deleteIcon = Utils.getTintedDrawable(activity, R.drawable.ic_delete_24dp, customThemeWrapper.getPrimaryIconColor()); + this.itemOnClickListener = itemOnClickListener; + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new RecentSearchQueryViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recent_search_query, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof RecentSearchQueryViewHolder) { + if (recentSearchQueries != null && !recentSearchQueries.isEmpty() && position < recentSearchQueries.size()) { + ((RecentSearchQueryViewHolder) holder).recentSearchQueryTextView.setText(recentSearchQueries.get(position).getSearchQuery()); + } + } + } + + @Override + public int getItemCount() { + return recentSearchQueries == null ? 0 : recentSearchQueries.size(); + } + + public void setRecentSearchQueries(List recentSearchQueries) { + this.recentSearchQueries = recentSearchQueries; + notifyDataSetChanged(); + } + + class RecentSearchQueryViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.recent_search_query_text_view_item_recent_search_query) + TextView recentSearchQueryTextView; + @BindView(R.id.delete_image_view_item_recent_search_query) + ImageView deleteImageView; + + public RecentSearchQueryViewHolder(@NonNull View itemView) { + super(itemView); + + ButterKnife.bind(this, itemView); + + recentSearchQueryTextView.setTextColor(primaryTextColor); + recentSearchQueryTextView.setCompoundDrawablesWithIntrinsicBounds(historyIcon, null, null, null); + deleteImageView.setImageDrawable(deleteIcon); + + itemView.setOnClickListener(view -> { + if (recentSearchQueries != null && !recentSearchQueries.isEmpty()) { + itemOnClickListener.onClick(recentSearchQueries.get(getAdapterPosition()).getSearchQuery()); + } + }); + + deleteImageView.setOnClickListener(view -> { + itemOnClickListener.onDelete(recentSearchQueries.get(getAdapterPosition())); + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SelectedSubredditsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SelectedSubredditsRecyclerViewAdapter.java new file mode 100644 index 00000000..61f4438d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SelectedSubredditsRecyclerViewAdapter.java @@ -0,0 +1,79 @@ +package ml.docilealligator.infinityforreddit.adapters; + +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.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; + +public class SelectedSubredditsRecyclerViewAdapter extends RecyclerView.Adapter { + private CustomThemeWrapper customThemeWrapper; + private ArrayList subreddits; + + public SelectedSubredditsRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList subreddits) { + this.customThemeWrapper = customThemeWrapper; + if (subreddits == null) { + this.subreddits = new ArrayList<>(); + } else { + this.subreddits = subreddits; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new SubredditViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_selected_subreddit, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof SubredditViewHolder) { + ((SubredditViewHolder) holder).subredditNameTextView.setText(subreddits.get(holder.getAdapterPosition())); + ((SubredditViewHolder) holder).deleteButton.setOnClickListener(view -> { + subreddits.remove(holder.getAdapterPosition()); + notifyItemRemoved(holder.getAdapterPosition()); + }); + } + } + + @Override + public int getItemCount() { + return subreddits.size(); + } + + public void addSubreddits(ArrayList newSubreddits) { + int oldSize = subreddits.size(); + subreddits.addAll(newSubreddits); + notifyItemRangeInserted(oldSize, newSubreddits.size()); + } + + public ArrayList getSubreddits() { + return subreddits; + } + + class SubredditViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.subreddit_name_item_selected_subreddit) + TextView subredditNameTextView; + @BindView(R.id.delete_image_view_item_selected_subreddit) + ImageView deleteButton; + + public SubredditViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + subredditNameTextView.setTextColor(customThemeWrapper.getPrimaryIconColor()); + deleteButton.setColorFilter(customThemeWrapper.getPrimaryIconColor(), android.graphics.PorterDuff.Mode.SRC_IN); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditFilterRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditFilterRecyclerViewAdapter.java new file mode 100644 index 00000000..330eab39 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditFilterRecyclerViewAdapter.java @@ -0,0 +1,72 @@ +package ml.docilealligator.infinityforreddit.adapters; + +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 ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; + +public class SubredditFilterRecyclerViewAdapter extends RecyclerView.Adapter { + private List subredditFilters; + private ItemClickListener itemClickListener; + + public SubredditFilterRecyclerViewAdapter(ItemClickListener itemClickListener) { + this.itemClickListener = itemClickListener; + } + + public interface ItemClickListener { + void onItemDelete(SubredditFilter subredditFilter); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new SubredditNameViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_selected_subreddit, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof SubredditNameViewHolder) { + ((SubredditNameViewHolder) holder).subredditRedditNameTextView.setText(subredditFilters.get(position).getSubredditName()); + } + } + + @Override + public int getItemCount() { + return subredditFilters == null ? 0 : subredditFilters.size(); + } + + public void updateSubredditsName(List subredditFilters) { + this.subredditFilters = subredditFilters; + notifyDataSetChanged(); + } + + class SubredditNameViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.subreddit_name_item_selected_subreddit) + TextView subredditRedditNameTextView; + @BindView(R.id.delete_image_view_item_selected_subreddit) + ImageView deleteImageView; + + public SubredditNameViewHolder(@NonNull View itemView) { + super(itemView); + + ButterKnife.bind(this, itemView); + + deleteImageView.setOnClickListener(view -> { + itemClickListener.onItemDelete(subredditFilters.get(getAdapterPosition())); + }); + } + } + +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java new file mode 100644 index 00000000..cec8041a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditListingRecyclerViewAdapter.java @@ -0,0 +1,260 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.paging.PagedListAdapter; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.asynctasks.CheckIsSubscribedToSubredditAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditSubscription; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class SubredditListingRecyclerViewAdapter extends PagedListAdapter { + private static final int VIEW_TYPE_DATA = 0; + private static final int VIEW_TYPE_ERROR = 1; + private static final int VIEW_TYPE_LOADING = 2; + private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull SubredditData oldItem, @NonNull SubredditData newItem) { + return oldItem.getId().equals(newItem.getId()); + } + + @Override + public boolean areContentsTheSame(@NonNull SubredditData oldItem, @NonNull SubredditData newItem) { + return true; + } + }; + private RequestManager glide; + private Context context; + private Retrofit oauthRetrofit; + private Retrofit retrofit; + private String accessToken; + private String accountName; + private RedditDataRoomDatabase redditDataRoomDatabase; + private int colorPrimaryLightTheme; + private int primaryTextColor; + private int secondaryTextColor; + private int colorAccent; + private int buttonTextColor; + private int unsubscribed; + + private NetworkState networkState; + private Callback callback; + + public SubredditListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, Retrofit retrofit, + CustomThemeWrapper customThemeWrapper, + String accessToken, String accountName, + RedditDataRoomDatabase redditDataRoomDatabase, + Callback callback) { + super(DIFF_CALLBACK); + this.context = context; + this.oauthRetrofit = oauthRetrofit; + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.callback = callback; + glide = Glide.with(context); + colorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + colorAccent = customThemeWrapper.getColorAccent(); + buttonTextColor = customThemeWrapper.getButtonTextColor(); + unsubscribed = customThemeWrapper.getUnsubscribed(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_DATA) { + ConstraintLayout constraintLayout = (ConstraintLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_subreddit_listing, parent, false); + return new DataViewHolder(constraintLayout); + } else if (viewType == VIEW_TYPE_ERROR) { + RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false); + return new ErrorViewHolder(relativeLayout); + } else { + RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false); + return new LoadingViewHolder(relativeLayout); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof DataViewHolder) { + SubredditData subredditData = getItem(position); + ((DataViewHolder) holder).constraintLayout.setOnClickListener(view -> + callback.subredditSelected(subredditData.getName(), subredditData.getIconUrl())); + + if (!subredditData.getIconUrl().equals("")) { + glide.load(subredditData.getIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((DataViewHolder) holder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((DataViewHolder) holder).iconGifImageView); + } + + ((DataViewHolder) holder).subredditNameTextView.setText(subredditData.getName()); + + new CheckIsSubscribedToSubredditAsyncTask(redditDataRoomDatabase, subredditData.getName(), accountName, + new CheckIsSubscribedToSubredditAsyncTask.CheckIsSubscribedToSubredditListener() { + @Override + public void isSubscribed() { + ((DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); + } + + @Override + public void isNotSubscribed() { + ((DataViewHolder) holder).subscribeButton.setVisibility(View.VISIBLE); + ((DataViewHolder) holder).subscribeButton.setOnClickListener(view -> { + SubredditSubscription.subscribeToSubreddit(oauthRetrofit, retrofit, + accessToken, subredditData.getName(), accountName, redditDataRoomDatabase, + new SubredditSubscription.SubredditSubscriptionListener() { + @Override + public void onSubredditSubscriptionSuccess() { + ((DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); + Toast.makeText(context, R.string.subscribed, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onSubredditSubscriptionFail() { + Toast.makeText(context, R.string.subscribe_failed, Toast.LENGTH_SHORT).show(); + } + }); + }); + } + }).execute(); + } + } + + @Override + public int getItemViewType(int position) { + // Reached at the end + if (hasExtraRow() && position == getItemCount() - 1) { + if (networkState.getStatus() == NetworkState.Status.LOADING) { + return VIEW_TYPE_LOADING; + } else { + return VIEW_TYPE_ERROR; + } + } else { + return VIEW_TYPE_DATA; + } + } + + @Override + public int getItemCount() { + if (hasExtraRow()) { + return super.getItemCount() + 1; + } + return super.getItemCount(); + } + + private boolean hasExtraRow() { + return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; + } + + public void setNetworkState(NetworkState newNetworkState) { + NetworkState previousState = this.networkState; + boolean previousExtraRow = hasExtraRow(); + this.networkState = newNetworkState; + boolean newExtraRow = hasExtraRow(); + if (previousExtraRow != newExtraRow) { + if (previousExtraRow) { + notifyItemRemoved(super.getItemCount()); + } else { + notifyItemInserted(super.getItemCount()); + } + } else if (newExtraRow && !previousState.equals(newNetworkState)) { + notifyItemChanged(getItemCount() - 1); + } + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if (holder instanceof DataViewHolder) { + glide.clear(((DataViewHolder) holder).iconGifImageView); + ((DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); + } + } + + public interface Callback { + void retryLoadingMore(); + + void subredditSelected(String subredditName, String iconUrl); + } + + class DataViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.constraint_layout_item_subreddit_listing) + ConstraintLayout constraintLayout; + @BindView(R.id.subreddit_icon_gif_image_view_item_subreddit_listing) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_item_subreddit_listing) + TextView subredditNameTextView; + @BindView(R.id.subscribe_image_view_item_subreddit_listing) + ImageView subscribeButton; + + DataViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + subredditNameTextView.setTextColor(primaryTextColor); + subscribeButton.setColorFilter(unsubscribed, android.graphics.PorterDuff.Mode.SRC_IN); + } + } + + class ErrorViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_footer_error) + TextView errorTextView; + @BindView(R.id.retry_button_item_footer_error) + Button retryButton; + + ErrorViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + retryButton.setOnClickListener(view -> callback.retryLoadingMore()); + errorTextView.setText(R.string.load_comments_failed); + errorTextView.setTextColor(secondaryTextColor); + retryButton.setBackgroundTintList(ColorStateList.valueOf(colorPrimaryLightTheme)); + retryButton.setTextColor(buttonTextColor); + } + } + + class LoadingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_footer_loading) + ProgressBar progressBar; + + LoadingViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorAccent)); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditMultiselectionRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditMultiselectionRecyclerViewAdapter.java new file mode 100644 index 00000000..cb3a3c40 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubredditMultiselectionRecyclerViewAdapter.java @@ -0,0 +1,123 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.subreddit.SubredditWithSelection; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import pl.droidsonroids.gif.GifImageView; + +public class SubredditMultiselectionRecyclerViewAdapter extends RecyclerView.Adapter { + + private ArrayList subscribedSubreddits; + private RequestManager glide; + private int primaryTextColor; + private int colorAccent; + + public SubredditMultiselectionRecyclerViewAdapter(Context context, CustomThemeWrapper customThemeWrapper) { + glide = Glide.with(context); + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + colorAccent = customThemeWrapper.getColorAccent(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new SubscribedSubredditViewHolder(LayoutInflater.from(parent.getContext()) + .inflate(R.layout.item_subscribed_subreddit_multi_selection, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof SubscribedSubredditViewHolder) { + ((SubscribedSubredditViewHolder) holder).nameTextView.setText(subscribedSubreddits.get(position).getName()); + glide.load(subscribedSubreddits.get(position).getIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((SubscribedSubredditViewHolder) holder).iconImageView); + if (subscribedSubreddits.get(position).isSelected()) { + ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(true); + } else { + ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(false); + } + ((SubscribedSubredditViewHolder) holder).checkBox.setOnClickListener(view -> { + if (subscribedSubreddits.get(position).isSelected()) { + ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(false); + subscribedSubreddits.get(position).setSelected(false); + } else { + ((SubscribedSubredditViewHolder) holder).checkBox.setChecked(true); + subscribedSubreddits.get(position).setSelected(true); + } + }); + ((SubscribedSubredditViewHolder) holder).itemView.setOnClickListener(view -> + ((SubscribedSubredditViewHolder) holder).checkBox.performClick()); + } + } + + @Override + public int getItemCount() { + return subscribedSubreddits == null ? 0 : subscribedSubreddits.size(); + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + super.onViewRecycled(holder); + if (holder instanceof SubscribedSubredditViewHolder) { + glide.clear(((SubscribedSubredditViewHolder) holder).iconImageView); + } + } + + public void setSubscribedSubreddits(List subscribedSubreddits) { + this.subscribedSubreddits = SubredditWithSelection.convertSubscribedSubreddits(subscribedSubreddits); + notifyDataSetChanged(); + } + + public ArrayList getAllSelectedSubreddits() { + ArrayList selectedSubreddits = new ArrayList<>(); + for (SubredditWithSelection s : subscribedSubreddits) { + if (s.isSelected()) { + selectedSubreddits.add(s.getName()); + } + } + return selectedSubreddits; + } + + class SubscribedSubredditViewHolder extends RecyclerView.ViewHolder { + View itemView; + @BindView(R.id.icon_gif_image_view_item_subscribed_subreddit_multiselection) + GifImageView iconImageView; + @BindView(R.id.name_text_view_item_subscribed_subreddit_multiselection) + TextView nameTextView; + @BindView(R.id.checkbox_item_subscribed_subreddit_multiselection) + CheckBox checkBox; + + SubscribedSubredditViewHolder(@NonNull View itemView) { + super(itemView); + this.itemView = itemView; + ButterKnife.bind(this, itemView); + nameTextView.setTextColor(primaryTextColor); + checkBox.setButtonTintList(ColorStateList.valueOf(colorAccent)); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubscribedSubredditsRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubscribedSubredditsRecyclerViewAdapter.java new file mode 100644 index 00000000..9ab3659d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/SubscribedSubredditsRecyclerViewAdapter.java @@ -0,0 +1,513 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.Intent; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import me.zhanghai.android.fastscroll.PopupTextProvider; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FavoriteThing; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class SubscribedSubredditsRecyclerViewAdapter extends RecyclerView.Adapter implements PopupTextProvider { + private static final int VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER = 0; + private static final int VIEW_TYPE_FAVORITE_SUBREDDIT = 1; + private static final int VIEW_TYPE_SUBREDDIT_DIVIDER = 2; + private static final int VIEW_TYPE_SUBREDDIT = 3; + + private Context mContext; + private Retrofit mOauthRetrofit; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private List mSubscribedSubredditData; + private List mFavoriteSubscribedSubredditData; + private RequestManager glide; + private ItemClickListener itemClickListener; + + private String accessToken; + private String username; + private String userIconUrl; + private boolean hasClearSelectionRow; + + private int primaryTextColor; + private int secondaryTextColor; + + public SubscribedSubredditsRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, + RedditDataRoomDatabase redditDataRoomDatabase, + CustomThemeWrapper customThemeWrapper, + String accessToken) { + mContext = context; + glide = Glide.with(context); + mOauthRetrofit = oauthRetrofit; + mRedditDataRoomDatabase = redditDataRoomDatabase; + this.accessToken = accessToken; + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + } + + public SubscribedSubredditsRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, + RedditDataRoomDatabase redditDataRoomDatabase, + CustomThemeWrapper customThemeWrapper, + String accessToken, boolean hasClearSelectionRow, + ItemClickListener itemClickListener) { + this(context, oauthRetrofit, redditDataRoomDatabase, customThemeWrapper, accessToken); + this.hasClearSelectionRow = hasClearSelectionRow; + this.itemClickListener = itemClickListener; + } + + @Override + public int getItemViewType(int position) { + if (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) { + if (itemClickListener != null && !hasClearSelectionRow) { + if (position == 0) { + return VIEW_TYPE_SUBREDDIT; + } else if (position == 1) { + return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; + } else if (position == mFavoriteSubscribedSubredditData.size() + 2) { + return VIEW_TYPE_SUBREDDIT_DIVIDER; + } else if (position <= mFavoriteSubscribedSubredditData.size() + 1) { + return VIEW_TYPE_FAVORITE_SUBREDDIT; + } else { + return VIEW_TYPE_SUBREDDIT; + } + } else if (hasClearSelectionRow) { + if (position == 0) { + return VIEW_TYPE_SUBREDDIT; + } else if (position == 1) { + return VIEW_TYPE_SUBREDDIT; + } else if (position == 2) { + return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; + } else if (position == mFavoriteSubscribedSubredditData.size() + 3) { + return VIEW_TYPE_SUBREDDIT_DIVIDER; + } else if (position <= mFavoriteSubscribedSubredditData.size() + 2) { + return VIEW_TYPE_FAVORITE_SUBREDDIT; + } else { + return VIEW_TYPE_SUBREDDIT; + } + } else { + if (position == 0) { + return VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER; + } else if (position == mFavoriteSubscribedSubredditData.size() + 1) { + return VIEW_TYPE_SUBREDDIT_DIVIDER; + } else if (position <= mFavoriteSubscribedSubredditData.size()) { + return VIEW_TYPE_FAVORITE_SUBREDDIT; + } else { + return VIEW_TYPE_SUBREDDIT; + } + } + } else { + return VIEW_TYPE_SUBREDDIT; + } + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { + switch (i) { + case VIEW_TYPE_FAVORITE_SUBREDDIT_DIVIDER: + return new FavoriteSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); + case VIEW_TYPE_FAVORITE_SUBREDDIT: + return new FavoriteSubredditViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_subscribed_thing, viewGroup, false)); + case VIEW_TYPE_SUBREDDIT_DIVIDER: + return new AllSubredditsDividerViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_favorite_thing_divider, viewGroup, false)); + default: + return new SubredditViewHolder(LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.item_subscribed_thing, viewGroup, false)); + } + } + + @Override + public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int i) { + if (viewHolder instanceof SubredditViewHolder) { + String name; + String iconUrl; + + if (hasClearSelectionRow && viewHolder.getAdapterPosition() == 0) { + ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(R.string.all_subreddits); + ((SubredditViewHolder) viewHolder).favoriteImageView.setVisibility(View.GONE); + viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(null, null, false)); + return; + } else if (itemClickListener != null && !hasClearSelectionRow && viewHolder.getAdapterPosition() == 0) { + ((SubredditViewHolder) viewHolder).favoriteImageView.setVisibility(View.GONE); + name = username; + iconUrl = userIconUrl; + viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, true)); + } else if (hasClearSelectionRow && viewHolder.getAdapterPosition() == 1) { + ((SubredditViewHolder) viewHolder).favoriteImageView.setVisibility(View.GONE); + name = username; + iconUrl = userIconUrl; + if (itemClickListener != null) { + viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, true)); + } + } else { + int offset; + if (itemClickListener != null) { + if (hasClearSelectionRow) { + offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? + mFavoriteSubscribedSubredditData.size() + 4 : 0; + } else { + offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? + mFavoriteSubscribedSubredditData.size() + 3 : 0; + } + } else { + offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? + mFavoriteSubscribedSubredditData.size() + 2 : 0; + } + + name = mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getName(); + iconUrl = mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getIconUrl(); + if(mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } else { + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + ((SubredditViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { + if(mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(false); + FavoriteThing.unfavoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, + mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mSubscribedSubredditData.size() > position) { + mSubscribedSubredditData.get(position).setFavorite(false); + } + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mSubscribedSubredditData.size() > position) { + mSubscribedSubredditData.get(position).setFavorite(true); + } + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + }); + } else { + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(true); + FavoriteThing.favoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, + mSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mSubscribedSubredditData.size() > position) { + mSubscribedSubredditData.get(position).setFavorite(true); + } + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - offset; + if(position >= 0 && mSubscribedSubredditData.size() > position) { + mSubscribedSubredditData.get(position).setFavorite(false); + } + ((SubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + }); + } + }); + + if (itemClickListener != null) { + viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, false)); + } + } + + if (itemClickListener == null) { + viewHolder.itemView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name); + mContext.startActivity(intent); + }); + } + + if (iconUrl != null && !iconUrl.equals("")) { + glide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((SubredditViewHolder) viewHolder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((SubredditViewHolder) viewHolder).iconGifImageView); + } + ((SubredditViewHolder) viewHolder).subredditNameTextView.setText(name); + } else if (viewHolder instanceof FavoriteSubredditViewHolder) { + int offset; + if (itemClickListener != null) { + if (hasClearSelectionRow) { + offset = 3; + } else { + offset = 2; + } + } else { + offset = 1; + } + String name = mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getName(); + String iconUrl = mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).getIconUrl(); + if(mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } else { + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setOnClickListener(view -> { + if(mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).isFavorite()) { + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(false); + FavoriteThing.unfavoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, + mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { + mFavoriteSubscribedSubredditData.get(position).setFavorite(false); + } + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_unfavorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { + mFavoriteSubscribedSubredditData.get(position).setFavorite(true); + } + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + }); + } else { + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset).setFavorite(true); + FavoriteThing.favoriteSubreddit(mOauthRetrofit, mRedditDataRoomDatabase, accessToken, + mFavoriteSubscribedSubredditData.get(viewHolder.getAdapterPosition() - offset), + new FavoriteThing.FavoriteThingListener() { + @Override + public void success() { + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { + mFavoriteSubscribedSubredditData.get(position).setFavorite(true); + } + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_24dp); + } + + @Override + public void failed() { + Toast.makeText(mContext, R.string.thing_favorite_failed, Toast.LENGTH_SHORT).show(); + int position = viewHolder.getAdapterPosition() - 1; + if(position >= 0 && mFavoriteSubscribedSubredditData.size() > position) { + mFavoriteSubscribedSubredditData.get(position).setFavorite(false); + } + ((FavoriteSubredditViewHolder) viewHolder).favoriteImageView.setImageResource(R.drawable.ic_favorite_border_24dp); + } + }); + } + }); + + if (itemClickListener != null) { + viewHolder.itemView.setOnClickListener(view -> itemClickListener.onClick(name, iconUrl, false)); + } else { + viewHolder.itemView.setOnClickListener(view -> { + Intent intent = new Intent(mContext, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, name); + mContext.startActivity(intent); + }); + } + + if (iconUrl != null && !iconUrl.equals("")) { + glide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((FavoriteSubredditViewHolder) viewHolder).iconGifImageView); + } + ((FavoriteSubredditViewHolder) viewHolder).subredditNameTextView.setText(name); + } + } + + @Override + public int getItemCount() { + if (mSubscribedSubredditData != null) { + if(mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) { + if (itemClickListener != null) { + if (hasClearSelectionRow) { + return mSubscribedSubredditData.size() > 0 ? + mFavoriteSubscribedSubredditData.size() + mSubscribedSubredditData.size() + 4 : 0; + } else { + return mSubscribedSubredditData.size() > 0 ? + mFavoriteSubscribedSubredditData.size() + mSubscribedSubredditData.size() + 3 : 0; + } + } + return mSubscribedSubredditData.size() > 0 ? + mFavoriteSubscribedSubredditData.size() + mSubscribedSubredditData.size() + 2 : 0; + } + + return mSubscribedSubredditData.size(); + } + return 0; + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if(holder instanceof SubredditViewHolder) { + glide.clear(((SubredditViewHolder) holder).iconGifImageView); + ((SubredditViewHolder) holder).favoriteImageView.setVisibility(View.VISIBLE); + } else if (holder instanceof FavoriteSubredditViewHolder) { + glide.clear(((FavoriteSubredditViewHolder) holder).iconGifImageView); + } + } + + public void setSubscribedSubreddits(List subscribedSubreddits) { + mSubscribedSubredditData = subscribedSubreddits; + notifyDataSetChanged(); + } + + public void setFavoriteSubscribedSubreddits(List favoriteSubscribedSubredditData) { + mFavoriteSubscribedSubredditData = favoriteSubscribedSubredditData; + notifyDataSetChanged(); + } + + public void addUser(String username, String userIconUrl) { + this.username = username; + this.userIconUrl = userIconUrl; + } + + @NonNull + @Override + public String getPopupText(int position) { + switch (getItemViewType(position)) { + case VIEW_TYPE_SUBREDDIT: + if (hasClearSelectionRow && position == 0) { + return ""; + } else if (itemClickListener != null && !hasClearSelectionRow && position == 0) { + return ""; + } else if (hasClearSelectionRow && position == 1) { + return ""; + } else { + int offset; + if (itemClickListener != null) { + if (hasClearSelectionRow) { + offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? + mFavoriteSubscribedSubredditData.size() + 4 : 0; + } else { + offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? + mFavoriteSubscribedSubredditData.size() + 3 : 0; + } + } else { + offset = (mFavoriteSubscribedSubredditData != null && mFavoriteSubscribedSubredditData.size() > 0) ? + mFavoriteSubscribedSubredditData.size() + 2 : 0; + } + + return mSubscribedSubredditData.get(position - offset).getName().substring(0, 1).toUpperCase(); + } + case VIEW_TYPE_FAVORITE_SUBREDDIT: + int offset; + if (itemClickListener != null) { + if (hasClearSelectionRow) { + offset = 3; + } else { + offset = 2; + } + } else { + offset = 1; + } + return mFavoriteSubscribedSubredditData.get(position - offset).getName().substring(0, 1).toUpperCase(); + default: + return ""; + } + } + + public interface ItemClickListener { + void onClick(String name, String iconUrl, boolean subredditIsUser); + } + + class SubredditViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) + GifImageView iconGifImageView; + @BindView(R.id.thing_name_text_view_item_subscribed_thing) + TextView subredditNameTextView; + @BindView(R.id.favorite_image_view_item_subscribed_thing) + ImageView favoriteImageView; + + SubredditViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + subredditNameTextView.setTextColor(primaryTextColor); + } + } + + class FavoriteSubredditViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.thing_icon_gif_image_view_item_subscribed_thing) + GifImageView iconGifImageView; + @BindView(R.id.thing_name_text_view_item_subscribed_thing) + TextView subredditNameTextView; + @BindView(R.id.favorite_image_view_item_subscribed_thing) + ImageView favoriteImageView; + + FavoriteSubredditViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + subredditNameTextView.setTextColor(primaryTextColor); + } + } + + class FavoriteSubredditsDividerViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; + + FavoriteSubredditsDividerViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + dividerTextView.setText(R.string.favorites); + dividerTextView.setTextColor(secondaryTextColor); + } + } + + class AllSubredditsDividerViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.divider_text_view_item_favorite_thing_divider) TextView dividerTextView; + + AllSubredditsDividerViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + dividerTextView.setText(R.string.all); + dividerTextView.setTextColor(secondaryTextColor); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/TranslationFragmentRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/TranslationFragmentRecyclerViewAdapter.java new file mode 100644 index 00000000..13f792ae --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/TranslationFragmentRecyclerViewAdapter.java @@ -0,0 +1,82 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.app.Activity; +import android.content.Intent; +import android.net.Uri; +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.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.settings.Translation; + +public class TranslationFragmentRecyclerViewAdapter extends RecyclerView.Adapter { + private Activity activity; + private int primaryTextColor; + private int secondaryTextColor; + private ArrayList translationContributors; + + public TranslationFragmentRecyclerViewAdapter(Activity activity, CustomThemeWrapper customThemeWrapper) { + this.activity = activity; + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + secondaryTextColor = customThemeWrapper.getSecondaryTextColor(); + translationContributors = Translation.getTranslationContributors(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new TranslationContributorViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_translation_contributor, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof TranslationContributorViewHolder) { + Translation translation = translationContributors.get(position); + ((TranslationContributorViewHolder) holder).countryFlagImageView.setImageResource(translation.flagDrawableId); + ((TranslationContributorViewHolder) holder).languageNameTextView.setText(translation.language); + ((TranslationContributorViewHolder) holder).contributorNamesTextView.setText(translation.contributors); + } + } + + @Override + public int getItemCount() { + return translationContributors.size(); + } + + class TranslationContributorViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.country_flag_image_view_item_translation_contributor) + ImageView countryFlagImageView; + @BindView(R.id.language_name_text_view_item_translation_contributor) + TextView languageNameTextView; + @BindView(R.id.contributor_names_text_view_item_translation_contributor) + TextView contributorNamesTextView; + + public TranslationContributorViewHolder(@NonNull View itemView) { + super(itemView); + + ButterKnife.bind(this, itemView); + + languageNameTextView.setTextColor(primaryTextColor); + contributorNamesTextView.setTextColor(secondaryTextColor); + + itemView.setOnClickListener(view -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://poeditor.com/join/project?hash=b2IRyfaJv6")); + activity.startActivity(intent); + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserFlairRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserFlairRecyclerViewAdapter.java new file mode 100644 index 00000000..1f05380b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserFlairRecyclerViewAdapter.java @@ -0,0 +1,88 @@ +package ml.docilealligator.infinityforreddit.adapters; + +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.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UserFlair; +import ml.docilealligator.infinityforreddit.utils.Utils; + +public class UserFlairRecyclerViewAdapter extends RecyclerView.Adapter { + private CustomThemeWrapper customThemeWrapper; + private ArrayList userFlairs; + private ItemClickListener itemClickListener; + + public UserFlairRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList userFlairs, + ItemClickListener itemClickListener) { + this.customThemeWrapper = customThemeWrapper; + this.userFlairs = userFlairs; + this.itemClickListener = itemClickListener; + } + + public interface ItemClickListener { + void onClick(UserFlair userFlair, boolean editUserFlair); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new UserFlairViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_flair, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof UserFlairViewHolder) { + UserFlair userFlair = userFlairs.get(holder.getAdapterPosition()); + if (userFlair.getHtmlText() == null || userFlair.getHtmlText().equals("")) { + ((UserFlairViewHolder) holder).userFlairHtmlTextView.setText(userFlair.getText()); + } else { + Utils.setHTMLWithImageToTextView(((UserFlairViewHolder) holder).userFlairHtmlTextView, userFlair.getHtmlText(), true); + } + if (userFlair.isEditable()) { + ((UserFlairViewHolder) holder).editUserFlairImageView.setVisibility(View.VISIBLE); + } else { + ((UserFlairViewHolder) holder).editUserFlairImageView.setVisibility(View.GONE); + } + } + } + + @Override + public int getItemCount() { + return userFlairs == null ? 0 : userFlairs.size(); + } + + class UserFlairViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.user_flair_html_text_view_item_user_flair) + TextView userFlairHtmlTextView; + @BindView(R.id.edit_user_flair_image_view_item_user_flair) + ImageView editUserFlairImageView; + + public UserFlairViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + userFlairHtmlTextView.setTextColor(customThemeWrapper.getPrimaryTextColor()); + editUserFlairImageView.setColorFilter(customThemeWrapper.getPrimaryTextColor(), android.graphics.PorterDuff.Mode.SRC_IN); + + itemView.setOnClickListener(view -> { + itemClickListener.onClick(userFlairs.get(getAdapterPosition()), false); + }); + + editUserFlairImageView.setOnClickListener(view -> { + itemClickListener.onClick(userFlairs.get(getAdapterPosition()), true); + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserListingRecyclerViewAdapter.java new file mode 100644 index 00000000..a7bd4bc3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/adapters/UserListingRecyclerViewAdapter.java @@ -0,0 +1,263 @@ +package ml.docilealligator.infinityforreddit.adapters; + +import android.content.Context; +import android.content.Intent; +import android.content.res.ColorStateList; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ProgressBar; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.constraintlayout.widget.ConstraintLayout; +import androidx.paging.PagedListAdapter; +import androidx.recyclerview.widget.DiffUtil; +import androidx.recyclerview.widget.RecyclerView; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.asynctasks.CheckIsFollowingUserAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserDao; +import ml.docilealligator.infinityforreddit.user.UserData; +import ml.docilealligator.infinityforreddit.user.UserFollowing; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class UserListingRecyclerViewAdapter extends PagedListAdapter { + private static final int VIEW_TYPE_DATA = 0; + private static final int VIEW_TYPE_ERROR = 1; + private static final int VIEW_TYPE_LOADING = 2; + private static final DiffUtil.ItemCallback DIFF_CALLBACK = new DiffUtil.ItemCallback() { + @Override + public boolean areItemsTheSame(@NonNull UserData oldItem, @NonNull UserData newItem) { + return oldItem.getName().equals(newItem.getName()); + } + + @Override + public boolean areContentsTheSame(@NonNull UserData oldItem, @NonNull UserData newItem) { + return true; + } + }; + private RequestManager glide; + private Context context; + private Retrofit oauthRetrofit; + private Retrofit retrofit; + private String accessToken; + private String accountName; + private SubscribedUserDao subscribedUserDao; + + private int primaryTextColor; + private int buttonTextColor; + private int colorPrimaryLightTheme; + private int colorAccent; + private int unsubscribedColor; + + private NetworkState networkState; + private UserListingRecyclerViewAdapter.RetryLoadingMoreCallback retryLoadingMoreCallback; + + public UserListingRecyclerViewAdapter(Context context, Retrofit oauthRetrofit, Retrofit retrofit, + CustomThemeWrapper customThemeWrapper, String accessToken, + String accountName, SubscribedUserDao subscribedUserDao, + UserListingRecyclerViewAdapter.RetryLoadingMoreCallback retryLoadingMoreCallback) { + super(DIFF_CALLBACK); + this.context = context; + this.oauthRetrofit = oauthRetrofit; + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.subscribedUserDao = subscribedUserDao; + this.retryLoadingMoreCallback = retryLoadingMoreCallback; + glide = Glide.with(context); + primaryTextColor = customThemeWrapper.getPrimaryTextColor(); + buttonTextColor = customThemeWrapper.getButtonTextColor(); + colorPrimaryLightTheme = customThemeWrapper.getColorPrimaryLightTheme(); + colorAccent = customThemeWrapper.getColorAccent(); + unsubscribedColor = customThemeWrapper.getUnsubscribed(); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + if (viewType == VIEW_TYPE_DATA) { + ConstraintLayout constraintLayout = (ConstraintLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_listing, parent, false); + return new UserListingRecyclerViewAdapter.DataViewHolder(constraintLayout); + } else if (viewType == VIEW_TYPE_ERROR) { + RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_error, parent, false); + return new UserListingRecyclerViewAdapter.ErrorViewHolder(relativeLayout); + } else { + RelativeLayout relativeLayout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_footer_loading, parent, false); + return new UserListingRecyclerViewAdapter.LoadingViewHolder(relativeLayout); + } + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof UserListingRecyclerViewAdapter.DataViewHolder) { + UserData userData = getItem(position); + if (userData != null) { + ((UserListingRecyclerViewAdapter.DataViewHolder) holder).constraintLayout.setOnClickListener(view -> { + Intent intent = new Intent(context, ViewUserDetailActivity.class); + intent.putExtra(ViewUserDetailActivity.EXTRA_USER_NAME_KEY, userData.getName()); + context.startActivity(intent); + }); + + if (!userData.getIconUrl().equals("")) { + glide.load(userData.getIconUrl()) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(((UserListingRecyclerViewAdapter.DataViewHolder) holder).iconGifImageView); + } else { + glide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(((UserListingRecyclerViewAdapter.DataViewHolder) holder).iconGifImageView); + } + + ((UserListingRecyclerViewAdapter.DataViewHolder) holder).userNameTextView.setText(userData.getName()); + + new CheckIsFollowingUserAsyncTask(subscribedUserDao, userData.getName(), accountName, + new CheckIsFollowingUserAsyncTask.CheckIsFollowingUserListener() { + @Override + public void isSubscribed() { + ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); + } + + @Override + public void isNotSubscribed() { + ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.VISIBLE); + ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setOnClickListener(view -> { + UserFollowing.followUser(oauthRetrofit, retrofit, + accessToken, userData.getName(), accountName, subscribedUserDao, + new UserFollowing.UserFollowingListener() { + @Override + public void onUserFollowingSuccess() { + ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); + Toast.makeText(context, R.string.followed, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onUserFollowingFail() { + Toast.makeText(context, R.string.follow_failed, Toast.LENGTH_SHORT).show(); + } + }); + }); + } + }).execute(); + } + } + } + + @Override + public int getItemViewType(int position) { + // Reached at the end + if (hasExtraRow() && position == getItemCount() - 1) { + if (networkState.getStatus() == NetworkState.Status.LOADING) { + return VIEW_TYPE_LOADING; + } else { + return VIEW_TYPE_ERROR; + } + } else { + return VIEW_TYPE_DATA; + } + } + + @Override + public int getItemCount() { + if (hasExtraRow()) { + return super.getItemCount() + 1; + } + return super.getItemCount(); + } + + private boolean hasExtraRow() { + return networkState != null && networkState.getStatus() != NetworkState.Status.SUCCESS; + } + + public void setNetworkState(NetworkState newNetworkState) { + NetworkState previousState = this.networkState; + boolean previousExtraRow = hasExtraRow(); + this.networkState = newNetworkState; + boolean newExtraRow = hasExtraRow(); + if (previousExtraRow != newExtraRow) { + if (previousExtraRow) { + notifyItemRemoved(super.getItemCount()); + } else { + notifyItemInserted(super.getItemCount()); + } + } else if (newExtraRow && !previousState.equals(newNetworkState)) { + notifyItemChanged(getItemCount() - 1); + } + } + + @Override + public void onViewRecycled(@NonNull RecyclerView.ViewHolder holder) { + if (holder instanceof UserListingRecyclerViewAdapter.DataViewHolder) { + glide.clear(((UserListingRecyclerViewAdapter.DataViewHolder) holder).iconGifImageView); + ((UserListingRecyclerViewAdapter.DataViewHolder) holder).subscribeButton.setVisibility(View.GONE); + } + } + + public interface RetryLoadingMoreCallback { + void retryLoadingMore(); + } + + class DataViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.constraint_layout_item_user_listing) + ConstraintLayout constraintLayout; + @BindView(R.id.user_icon_gif_image_view_item_user_listing) + GifImageView iconGifImageView; + @BindView(R.id.user_name_text_view_item_user_listing) + TextView userNameTextView; + @BindView(R.id.subscribe_image_view_item_user_listing) + ImageView subscribeButton; + + DataViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + userNameTextView.setTextColor(primaryTextColor); + subscribeButton.setColorFilter(unsubscribedColor, android.graphics.PorterDuff.Mode.SRC_IN); + } + } + + class ErrorViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.error_text_view_item_footer_error) + TextView errorTextView; + @BindView(R.id.retry_button_item_footer_error) + Button retryButton; + + ErrorViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + retryButton.setOnClickListener(view -> retryLoadingMoreCallback.retryLoadingMore()); + errorTextView.setText(R.string.load_comments_failed); + errorTextView.setTextColor(primaryTextColor); + retryButton.setTextColor(buttonTextColor); + retryButton.setBackgroundTintList(ColorStateList.valueOf(colorPrimaryLightTheme)); + } + } + + class LoadingViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.progress_bar_item_footer_loading) + ProgressBar progressBar; + + LoadingViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorAccent)); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/DownloadFile.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/DownloadFile.java new file mode 100644 index 00000000..da02ad80 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/DownloadFile.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.apis; + +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Streaming; +import retrofit2.http.Url; + +public interface DownloadFile { + @Streaming + @GET() + Call downloadFile(@Url String fileUrl); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/GfycatAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/GfycatAPI.java new file mode 100644 index 00000000..14028182 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/GfycatAPI.java @@ -0,0 +1,10 @@ +package ml.docilealligator.infinityforreddit.apis; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Path; + +public interface GfycatAPI { + @GET("{gfyid}") + Call getGfycatData(@Path("gfyid") String gfyId); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/ImgurAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/ImgurAPI.java new file mode 100644 index 00000000..3133b2d5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/ImgurAPI.java @@ -0,0 +1,18 @@ +package ml.docilealligator.infinityforreddit.apis; + +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Header; +import retrofit2.http.Path; + +public interface ImgurAPI { + @GET("gallery/{id}") + Call getGalleryImages(@Header(APIUtils.AUTHORIZATION_KEY) String clientId, @Path("id") String id); + + @GET("album/{id}") + Call getAlbumImages(@Header(APIUtils.AUTHORIZATION_KEY) String clientId, @Path("id") String id); + + @GET("image/{id}") + Call getImage(@Header(APIUtils.AUTHORIZATION_KEY) String clientId, @Path("id") String id); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/PushshiftAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/PushshiftAPI.java new file mode 100644 index 00000000..b19526ae --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/PushshiftAPI.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.apis; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +public interface PushshiftAPI { + @GET("reddit/comment/search/") + Call getRemovedComment(@Query("ids") String commentId); + + @GET("reddit/submission/search/") + Call getRemovedPost(@Query("ids") String postId); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java new file mode 100644 index 00000000..3bee57fb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java @@ -0,0 +1,339 @@ +package ml.docilealligator.infinityforreddit.apis; + +import java.util.Map; + +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.http.DELETE; +import retrofit2.http.FieldMap; +import retrofit2.http.FormUrlEncoded; +import retrofit2.http.GET; +import retrofit2.http.HeaderMap; +import retrofit2.http.Multipart; +import retrofit2.http.POST; +import retrofit2.http.PUT; +import retrofit2.http.Part; +import retrofit2.http.PartMap; +import retrofit2.http.Path; +import retrofit2.http.Query; + +public interface RedditAPI { + @FormUrlEncoded + @POST("api/v1/access_token") + Call getAccessToken(@HeaderMap Map headers, @FieldMap Map params); + + @GET("r/{subredditName}/about.json?raw_json=1") + Call getSubredditData(@Path("subredditName") String subredditName); + + @GET("subreddits/mine/subscriber?raw_json=1") + Call getSubscribedThing(@Query("after") String lastItem, @HeaderMap Map headers); + + @GET("api/v1/me?raw_json=1") + Call getMyInfo(@HeaderMap Map headers); + + @FormUrlEncoded + @POST("api/vote") + Call voteThing(@HeaderMap Map headers, @FieldMap Map params); + + @GET("comments/{id}.json?raw_json=1") + Call getPostOauth(@Path("id") String id, @HeaderMap Map headers); + + @GET("comments/{id}.json?raw_json=1") + Call getPost(@Path("id") String id); + + @GET("{sortType}?raw_json=1") + Call getBestPosts(@Path("sortType") String sortType, @Query("after") String lastItem, @HeaderMap Map headers); + + @GET("{sortType}?raw_json=1") + Call getBestPosts(@Path("sortType") String sortType, @Query("t") String sortTime, + @Query("after") String lastItem, @HeaderMap Map headers); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") + Call getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("after") String lastItem, @HeaderMap Map headers); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") + Call getSubredditBestPostsOauth(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("t") String sortTime, @Query("after") String lastItem, + @HeaderMap Map headers); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") + Call getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("after") String lastItem); + + @GET("r/{subredditName}/{sortType}.json?raw_json=1&limit=25") + Call getSubredditBestPosts(@Path("subredditName") String subredditName, @Path("sortType") String sortType, + @Query("t") String sortTime, @Query("after") String lastItem); + + @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") + Call getUserPostsOauth(@Path("username") String username, @Path("where") String where, + @Query("after") String lastItem, @Query("sort") String sortType, @HeaderMap Map headers); + + @GET("user/{username}/{where}.json?&type=links&raw_json=1&limit=25") + Call getUserPostsOauth(@Path("username") String username, @Path("where") String where, + @Query("after") String lastItem, @Query("sort") String sortType, + @Query("t") String sortTime, @HeaderMap Map headers); + + @GET("user/{username}/submitted.json?raw_json=1&limit=25") + Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, + @Query("sort") String sortType); + + @GET("user/{username}/submitted.json?raw_json=1&limit=25") + Call getUserPosts(@Path("username") String username, @Query("after") String lastItem, + @Query("sort") String sortType, @Query("t") String sortTime); + + @GET("user/{username}/about.json?raw_json=1") + Call getUserData(@Path("username") String username); + + @GET("user/{username}/comments.json?raw_json=1") + Call getUserComments(@Path("username") String username, @Query("after") String after, + @Query("sort") String sortType); + + @GET("user/{username}/comments.json?raw_json=1") + Call getUserComments(@Path("username") String username, @Query("after") String after, + @Query("sort") String sortType, @Query("t") String sortTime); + + @GET("user/{username}/comments.json?raw_json=1") + Call getUserCommentsOauth(@HeaderMap Map headers, @Path("username") String username, + @Query("after") String after, @Query("sort") String sortType); + + @GET("user/{username}/comments.json?raw_json=1") + Call getUserCommentsOauth(@HeaderMap Map headers, @Path("username") String username, + @Query("after") String after, @Query("sort") String sortType, + @Query("t") String sortTime); + + @GET("user/{username}/{where}.json?&type=comments&raw_json=1&limit=25") + Call getUserSavedCommentsOauth(@Path("username") String username, @Path("where") String where, + @Query("after") String lastItem, @Query("sort") String sortType, + @HeaderMap Map headers); + + @GET("user/{username}/{where}.json?&type=comments&raw_json=1&limit=25") + Call getUserSavedCommentsOauth(@Path("username") String username, @Path("where") String where, + @Query("after") String lastItem, @Query("sort") String sortType, + @Query("t") String sortTime, @HeaderMap Map headers); + + @FormUrlEncoded + @POST("api/subscribe") + Call subredditSubscription(@HeaderMap Map headers, @FieldMap Map params); + + @GET("/api/info.json?raw_json=1") + Call getInfo(@Query("id") String id); + + @GET("/api/info.json?raw_json=1") + Call getInfoOauth(@Query("id") String id, @HeaderMap Map headers); + + @GET("subreddits/search.json?raw_json=1") + Call searchSubreddits(@Query("q") String subredditName, @Query("after") String after, + @Query("sort") String sort, @Query("include_over_18") int nsfw, + @HeaderMap Map headers); + + @GET("search.json?raw_json=1&type=user") + Call searchUsers(@Query("q") String profileName, @Query("after") String after, + @Query("sort") String sort, @Query("include_over_18") int nsfw); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPostsOauth(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort, + @HeaderMap Map headers); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPostsOauth(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort, @Query("t") String sortTime, + @HeaderMap Map headers); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPosts(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort); + + @GET("search.json?include_over_18=1&raw_json=1&type=link") + Call searchPosts(@Query("q") String query, @Query("after") String after, + @Query("sort") String sort, @Query("t") String sortTime); + + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + Call searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("after") String after, + @HeaderMap Map headers); + + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + Call searchPostsInSpecificSubredditOauth(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("t") String 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") + Call searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("after") String after); + + @GET("r/{subredditName}/search.json?include_over_18=1&raw_json=1&type=link&restrict_sr=true") + Call searchPostsInSpecificSubreddit(@Path("subredditName") String subredditName, + @Query("q") String query, @Query("sort") String sort, + @Query("t") String sortTime, @Query("after") String after); + + @FormUrlEncoded + @POST("api/comment") + Call sendCommentOrReplyToMessage(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("api/del") + Call delete(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("api/submit") + Call submit(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("api/media/asset.json?raw_json=1&gilding_detail=1") + Call uploadImage(@HeaderMap Map headers, @FieldMap Map params); + + @GET("r/{subredditName}/api/link_flair.json?raw_json=1") + Call getFlairs(@HeaderMap Map headers, @Path("subredditName") String subredditName); + + @GET("/r/{subredditName}/about/rules.json?raw_json=1") + Call getRules(@Path("subredditName") String subredditName); + + @GET("/comments/{id}/placeholder/{singleCommentId}.json?context=8&raw_json=1") + Call getPostAndCommentsSingleThreadByIdOauth(@Path("id") String id, @Path("singleCommentId") String singleCommentId, + @Query("sort") String sortType, + @HeaderMap Map headers); + + @GET("/comments/{id}.json?raw_json=1") + Call getPostAndCommentsByIdOauth(@Path("id") String id, @Query("sort") String sortType, + @HeaderMap Map headers); + + @GET("/comments/{id}/placeholder/{singleCommentId}.json?context=8&raw_json=1") + Call getPostAndCommentsSingleThreadById(@Path("id") String id, @Path("singleCommentId") String singleCommentId, + @Query("sort") String sortType); + + @GET("/comments/{id}.json?raw_json=1") + Call getPostAndCommentsById(@Path("id") String id, @Query("sort") String sortType); + + @Multipart + @POST(".") + Call uploadMediaToAWS(@PartMap() Map params, @Part() MultipartBody.Part file); + + @FormUrlEncoded + @POST("/api/editusertext") + Call editPostOrComment(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/marknsfw") + Call markNSFW(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/unmarknsfw") + Call unmarkNSFW(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/spoiler") + Call markSpoiler(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/unspoiler") + Call unmarkSpoiler(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("{subredditNamePrefixed}/api/selectflair") + Call selectFlair(@Path("subredditNamePrefixed") String subredditName, @HeaderMap Map headers, @FieldMap Map params); + + @GET("/message/{where}.json?raw_json=1") + Call getMessages(@HeaderMap Map headers, @Path("where") String where, @Query("after") String after); + + @FormUrlEncoded + @POST("/api/read_message") + Call readMessage(@HeaderMap Map headers, @FieldMap Map ids); + + @FormUrlEncoded + @POST("/api/save") + Call save(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/unsave") + Call unsave(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/hide") + Call hide(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/unhide") + Call unhide(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/favorite") + Call favoriteThing(@HeaderMap Map headers, @FieldMap Map params); + + @GET("/api/multi/mine") + Call getMyMultiReddits(@HeaderMap Map headers); + + @FormUrlEncoded + @POST("/api/multi/favorite?raw_json=1&gilding_detail=1") + Call favoriteMultiReddit(@HeaderMap Map headers, @FieldMap Map params); + + @GET("/api/multi/user/{username}") + Call getUserMultiReddits(@Path("username") String username); + + @GET("{multipath}?raw_json=1") + Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after); + + @GET("{multipath}?raw_json=1") + Call getMultiRedditPosts(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after, @Query("t") String sortTime); + + @GET("{multipath}.json?raw_json=1") + Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after, @Query("t") String sortTime, + @HeaderMap Map headers); + + @GET("{multipath}.json?raw_json=1") + Call getMultiRedditPostsOauth(@Path(value = "multipath", encoded = true) String multiPath, + @Query("after") String after, @HeaderMap Map headers); + + @FormUrlEncoded + @POST("/api/multi/multipath") + Call createMultiReddit(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @PUT("/api/multi/multipath") + Call updateMultiReddit(@HeaderMap Map headers, @FieldMap Map params); + + @DELETE("/api/multi/multipath") + Call deleteMultiReddit(@HeaderMap Map headers, @Query("multipath") String multipath); + + @GET("/api/multi/multipath/") + Call getMultiRedditInfo(@HeaderMap Map headers, @Query("multipath") String multipath); + + @FormUrlEncoded + @POST("/api/report") + Call report(@HeaderMap Map headers, @FieldMap Map params); + + @FormUrlEncoded + @POST("/api/compose") + Call composePrivateMessage(@HeaderMap Map headers, @FieldMap Map params); + + + @FormUrlEncoded + @POST("api/block_user") + Call blockUser(@HeaderMap Map headers, @FieldMap Map params); + + @GET("r/{subredditName}/api/user_flair_v2.json?raw_json=1") + Call getUserFlairs(@HeaderMap Map headers, @Path("subredditName") String subredditName); + + @FormUrlEncoded + @POST("/r/{subredditName}/api/selectflair?raw_json=1") + Call selectUserFlair(@HeaderMap Map headers, @FieldMap Map params, + @Path("subredditName") String subredditName); + + @FormUrlEncoded + @POST("api/v2/gold/gild") + Call awardThing(@HeaderMap Map headers, @FieldMap Map params); + + @GET("/r/random/comments.json?limit=1&raw_json=1") + Call getRandomPost(); + + @GET("/r/randnsfw/new.json?sort=new&t=all&limit=1&raw_json=1") + Call getRandomNSFWPost(); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ChangeThemeNameAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ChangeThemeNameAsyncTask.java new file mode 100644 index 00000000..4bc3bef4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ChangeThemeNameAsyncTask.java @@ -0,0 +1,23 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class ChangeThemeNameAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private String oldName; + private String newName; + + public ChangeThemeNameAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String oldName, String newName) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.oldName = oldName; + this.newName = newName; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.customThemeDao().updateName(oldName, newName); + return null; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsFollowingUserAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsFollowingUserAsyncTask.java new file mode 100644 index 00000000..a34bd0a8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsFollowingUserAsyncTask.java @@ -0,0 +1,44 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserDao; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; + +public class CheckIsFollowingUserAsyncTask extends AsyncTask { + private SubscribedUserDao subscribedUserDao; + private String username; + private String accountName; + private SubscribedUserData subscribedUserData; + private CheckIsFollowingUserListener checkIsFollowingUserListener; + + public CheckIsFollowingUserAsyncTask(SubscribedUserDao subscribedUserDao, String username, String accountName, + CheckIsFollowingUserListener checkIsFollowingUserListener) { + this.subscribedUserDao = subscribedUserDao; + this.username = username; + this.accountName = accountName; + this.checkIsFollowingUserListener = checkIsFollowingUserListener; + } + + @Override + protected Void doInBackground(Void... voids) { + subscribedUserData = subscribedUserDao.getSubscribedUser(username, accountName); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (subscribedUserData != null) { + checkIsFollowingUserListener.isSubscribed(); + } else { + checkIsFollowingUserListener.isNotSubscribed(); + } + } + + public interface CheckIsFollowingUserListener { + void isSubscribed(); + + void isNotSubscribed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubredditAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubredditAsyncTask.java new file mode 100644 index 00000000..a7aaddd4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/CheckIsSubscribedToSubredditAsyncTask.java @@ -0,0 +1,46 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; + +public class CheckIsSubscribedToSubredditAsyncTask extends AsyncTask { + + private RedditDataRoomDatabase redditDataRoomDatabase; + private String subredditName; + private String accountName; + private SubscribedSubredditData subscribedSubredditData; + private CheckIsSubscribedToSubredditListener checkIsSubscribedToSubredditListener; + + public CheckIsSubscribedToSubredditAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + String subredditName, String accountName, + CheckIsSubscribedToSubredditListener checkIsSubscribedToSubredditListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.subredditName = subredditName; + this.accountName = accountName; + this.checkIsSubscribedToSubredditListener = checkIsSubscribedToSubredditListener; + } + + @Override + protected Void doInBackground(Void... voids) { + subscribedSubredditData = redditDataRoomDatabase.subscribedSubredditDao().getSubscribedSubreddit(subredditName, accountName); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (subscribedSubredditData != null) { + checkIsSubscribedToSubredditListener.isSubscribed(); + } else { + checkIsSubscribedToSubredditListener.isNotSubscribed(); + } + } + + public interface CheckIsSubscribedToSubredditListener { + void isSubscribed(); + + void isNotSubscribed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllPostLayoutsAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllPostLayoutsAsyncTask.java new file mode 100644 index 00000000..a4298f10 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllPostLayoutsAsyncTask.java @@ -0,0 +1,57 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.content.SharedPreferences; +import android.os.AsyncTask; + +import java.util.Map; + +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class DeleteAllPostLayoutsAsyncTask extends AsyncTask { + + private SharedPreferences defaultSharedPreferences; + private SharedPreferences postLayoutSharedPreferences; + private DeleteAllPostLayoutsAsyncTaskListener deleteAllPostLayoutsAsyncTaskListener; + + public interface DeleteAllPostLayoutsAsyncTaskListener { + void success(); + } + + public DeleteAllPostLayoutsAsyncTask(SharedPreferences defaultSharedPreferences, + SharedPreferences postLayoutSharedPreferences, + DeleteAllPostLayoutsAsyncTaskListener deleteAllPostLayoutsAsyncTaskListener) { + this.defaultSharedPreferences = defaultSharedPreferences; + this.postLayoutSharedPreferences = postLayoutSharedPreferences; + this.deleteAllPostLayoutsAsyncTaskListener = deleteAllPostLayoutsAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + Map keys = defaultSharedPreferences.getAll(); + SharedPreferences.Editor editor = defaultSharedPreferences.edit(); + + for(Map.Entry entry : keys.entrySet()){ + String key = entry.getKey(); + if (key.startsWith(SharedPreferencesUtils.POST_LAYOUT_SHARED_PREFERENCES_FILE) + || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST) + || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST_LEGACY) + || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_ALL_POST_LEGACY) + || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE) + || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE) + || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE) + || key.startsWith(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST)) { + editor.remove(key); + } + } + editor.apply(); + + postLayoutSharedPreferences.edit().clear().apply(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteAllPostLayoutsAsyncTaskListener.success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSortTypesAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSortTypesAsyncTask.java new file mode 100644 index 00000000..a0d999b5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSortTypesAsyncTask.java @@ -0,0 +1,58 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.content.SharedPreferences; +import android.os.AsyncTask; + +import java.util.Map; + +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class DeleteAllSortTypesAsyncTask extends AsyncTask { + private SharedPreferences defaultSharedPreferences; + private SharedPreferences sortTypeSharedPreferences; + private DeleteAllSortTypesAsyncTaskListener deleteAllSortTypesAsyncTaskListener; + + public interface DeleteAllSortTypesAsyncTaskListener { + void success(); + } + + public DeleteAllSortTypesAsyncTask(SharedPreferences defaultSharedPreferences, + SharedPreferences sortTypeSharedPreferences, + DeleteAllSortTypesAsyncTaskListener deleteAllSortTypesAsyncTaskListener) { + this.defaultSharedPreferences = defaultSharedPreferences; + this.sortTypeSharedPreferences = sortTypeSharedPreferences; + this.deleteAllSortTypesAsyncTaskListener = deleteAllSortTypesAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + Map keys = defaultSharedPreferences.getAll(); + SharedPreferences.Editor editor = defaultSharedPreferences.edit(); + + for(Map.Entry entry : keys.entrySet()){ + String key = entry.getKey(); + if (key.contains(SharedPreferencesUtils.SORT_TYPE_BEST_POST) || key.contains(SharedPreferencesUtils.SORT_TIME_BEST_POST) + || key.contains(SharedPreferencesUtils.SORT_TYPE_ALL_POST_LEGACY) || key.contains(SharedPreferencesUtils.SORT_TIME_ALL_POST_LEGACY) + || key.contains(SharedPreferencesUtils.SORT_TYPE_POPULAR_POST_LEGACY) || key.contains(SharedPreferencesUtils.SORT_TIME_POPULAR_POST_LEGACY) + || key.contains(SharedPreferencesUtils.SORT_TYPE_SEARCH_POST) || key.contains(SharedPreferencesUtils.SORT_TIME_SEARCH_POST) + || key.contains(SharedPreferencesUtils.SORT_TYPE_SUBREDDIT_POST_BASE) || key.contains(SharedPreferencesUtils.SORT_TIME_SUBREDDIT_POST_BASE) + || key.contains(SharedPreferencesUtils.SORT_TYPE_MULTI_REDDIT_POST_BASE) || key.contains(SharedPreferencesUtils.SORT_TIME_MULTI_REDDIT_POST_BASE) + || key.contains(SharedPreferencesUtils.SORT_TYPE_USER_POST_BASE) || key.contains(SharedPreferencesUtils.SORT_TIME_USER_POST_BASE) + || key.contains(SharedPreferencesUtils.SORT_TYPE_USER_COMMENT) || key.contains(SharedPreferencesUtils.SORT_TIME_USER_COMMENT) + || key.contains(SharedPreferencesUtils.SORT_TYPE_SEARCH_SUBREDDIT) || key.contains(SharedPreferencesUtils.SORT_TYPE_SEARCH_USER) + || key.contains(SharedPreferencesUtils.SORT_TYPE_POST_COMMENT)) { + editor.remove(key); + } + } + editor.apply(); + + sortTypeSharedPreferences.edit().clear().apply(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteAllSortTypesAsyncTaskListener.success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSubredditsAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSubredditsAsyncTask.java new file mode 100644 index 00000000..f5494224 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllSubredditsAsyncTask.java @@ -0,0 +1,33 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class DeleteAllSubredditsAsyncTask extends AsyncTask { + + private RedditDataRoomDatabase redditDataRoomDatabase; + private DeleteAllSubredditsAsyncTaskListener deleteAllSubredditsAsyncTaskListener; + + public interface DeleteAllSubredditsAsyncTaskListener { + void success(); + } + + public DeleteAllSubredditsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + DeleteAllSubredditsAsyncTaskListener deleteAllSubredditsAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.deleteAllSubredditsAsyncTaskListener = deleteAllSubredditsAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.subredditDao().deleteAllSubreddits(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteAllSubredditsAsyncTaskListener.success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllThemesAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllThemesAsyncTask.java new file mode 100644 index 00000000..ccf935fb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllThemesAsyncTask.java @@ -0,0 +1,45 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.content.SharedPreferences; +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class DeleteAllThemesAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private SharedPreferences lightThemeSharedPreferences; + private SharedPreferences darkThemeSharedPreferences; + private SharedPreferences amoledThemeSharedPreferences; + private DeleteAllThemesAsyncTaskListener deleteAllThemesAsyncTaskListener; + + public interface DeleteAllThemesAsyncTaskListener { + void success(); + } + + public DeleteAllThemesAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + SharedPreferences lightThemeSharedPreferences, + SharedPreferences darkThemeSharedPreferences, + SharedPreferences amoledThemeSharedPreferences, + DeleteAllThemesAsyncTaskListener deleteAllThemesAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.lightThemeSharedPreferences = lightThemeSharedPreferences; + this.darkThemeSharedPreferences = darkThemeSharedPreferences; + this.amoledThemeSharedPreferences = amoledThemeSharedPreferences; + this.deleteAllThemesAsyncTaskListener = deleteAllThemesAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.customThemeDao().deleteAllCustomThemes(); + lightThemeSharedPreferences.edit().clear().apply(); + darkThemeSharedPreferences.edit().clear().apply(); + amoledThemeSharedPreferences.edit().clear().apply(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteAllThemesAsyncTaskListener.success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllUsersAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllUsersAsyncTask.java new file mode 100644 index 00000000..26c20043 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteAllUsersAsyncTask.java @@ -0,0 +1,33 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class DeleteAllUsersAsyncTask extends AsyncTask { + + private RedditDataRoomDatabase redditDataRoomDatabase; + private DeleteAllUsersAsyncTaskListener deleteAllUsersAsyncTaskListener; + + public interface DeleteAllUsersAsyncTaskListener { + void success(); + } + + public DeleteAllUsersAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + DeleteAllUsersAsyncTaskListener deleteAllUsersAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.deleteAllUsersAsyncTaskListener = deleteAllUsersAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.userDao().deleteAllUsers(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteAllUsersAsyncTaskListener.success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteMultiredditInDatabaseAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteMultiredditInDatabaseAsyncTask.java new file mode 100644 index 00000000..61e62244 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteMultiredditInDatabaseAsyncTask.java @@ -0,0 +1,37 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class DeleteMultiredditInDatabaseAsyncTask extends AsyncTask { + public interface DeleteMultiredditInDatabaseAsyncTaskListener { + void success(); + } + + private RedditDataRoomDatabase redditDataRoomDatabase; + private String accountName; + private String multipath; + private DeleteMultiredditInDatabaseAsyncTaskListener deleteMultiredditInDatabaseAsyncTaskListener; + + public DeleteMultiredditInDatabaseAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + String accountName, String multipath, + DeleteMultiredditInDatabaseAsyncTaskListener deleteMultiredditInDatabaseAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.accountName = accountName; + this.multipath = multipath; + this.deleteMultiredditInDatabaseAsyncTaskListener = deleteMultiredditInDatabaseAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.multiRedditDao().deleteMultiReddit(multipath, accountName); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteMultiredditInDatabaseAsyncTaskListener.success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteThemeAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteThemeAsyncTask.java new file mode 100644 index 00000000..e33cdbf5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/DeleteThemeAsyncTask.java @@ -0,0 +1,44 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class DeleteThemeAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private String themeName; + private DeleteThemeAsyncTaskListener deleteThemeAsyncTaskListener; + private boolean isLightTheme = false; + private boolean isDarkTheme = false; + private boolean isAmoledTheme = false; + + public interface DeleteThemeAsyncTaskListener { + void success(boolean isLightTheme, boolean isDarkTheme, boolean isAmoledTheme); + } + + public DeleteThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String themeName, + DeleteThemeAsyncTaskListener deleteThemeAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.themeName = themeName; + this.deleteThemeAsyncTaskListener = deleteThemeAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + CustomTheme customTheme = redditDataRoomDatabase.customThemeDao().getCustomTheme(themeName); + if (customTheme != null) { + isLightTheme = customTheme.isLightTheme; + isDarkTheme = customTheme.isDarkTheme; + isAmoledTheme = customTheme.isAmoledTheme; + redditDataRoomDatabase.customThemeDao().deleteCustomTheme(themeName); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteThemeAsyncTaskListener.success(isLightTheme, isDarkTheme, isAmoledTheme); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCurrentAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCurrentAccountAsyncTask.java new file mode 100644 index 00000000..7c495c0a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCurrentAccountAsyncTask.java @@ -0,0 +1,33 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.account.AccountDao; + +public class GetCurrentAccountAsyncTask extends AsyncTask { + + private Account account; + private AccountDao accountDao; + private GetCurrentAccountAsyncTaskListener getCurrentAccountAsyncTaskListener; + + public GetCurrentAccountAsyncTask(AccountDao accountDao, GetCurrentAccountAsyncTaskListener getCurrentAccountAsyncTaskListener) { + this.accountDao = accountDao; + this.getCurrentAccountAsyncTaskListener = getCurrentAccountAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + account = accountDao.getCurrentAccount(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + getCurrentAccountAsyncTaskListener.success(account); + } + + public interface GetCurrentAccountAsyncTaskListener { + void success(Account account); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCustomThemeAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCustomThemeAsyncTask.java new file mode 100644 index 00000000..62e18f87 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/GetCustomThemeAsyncTask.java @@ -0,0 +1,60 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; + +public class GetCustomThemeAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private String customThemeName; + private int themeType; + private GetCustomThemeAsyncTaskListener getCustomThemeAsyncTaskListener; + private CustomTheme customTheme; + + public interface GetCustomThemeAsyncTaskListener { + void success(CustomTheme customTheme); + } + + public GetCustomThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + String customThemeName, + GetCustomThemeAsyncTaskListener getCustomThemeAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.customThemeName = customThemeName; + this.getCustomThemeAsyncTaskListener = getCustomThemeAsyncTaskListener; + } + + public GetCustomThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + int themeType, + GetCustomThemeAsyncTaskListener getCustomThemeAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.themeType = themeType; + this.getCustomThemeAsyncTaskListener = getCustomThemeAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + if (customThemeName != null) { + customTheme = redditDataRoomDatabase.customThemeDao().getCustomTheme(customThemeName); + } else { + switch (themeType) { + case CustomThemeSharedPreferencesUtils.DARK: + customTheme = redditDataRoomDatabase.customThemeDao().getDarkCustomTheme(); + break; + case CustomThemeSharedPreferencesUtils.AMOLED: + customTheme = redditDataRoomDatabase.customThemeDao().getAmoledCustomTheme(); + break; + default: + customTheme = redditDataRoomDatabase.customThemeDao().getLightCustomTheme(); + } + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + getCustomThemeAsyncTaskListener.success(customTheme); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertCustomThemeAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertCustomThemeAsyncTask.java new file mode 100644 index 00000000..4e46eb47 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertCustomThemeAsyncTask.java @@ -0,0 +1,80 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.content.SharedPreferences; +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; + +public class InsertCustomThemeAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private SharedPreferences lightThemeSharedPreferences; + private SharedPreferences darkThemeSharedPreferences; + private SharedPreferences amoledThemeSharedPreferences; + private CustomTheme customTheme; + private boolean checkDuplicate; + private InsertCustomThemeAsyncTaskListener insertCustomThemeAsyncTaskListener; + private boolean isDuplicate = false; + + public interface InsertCustomThemeAsyncTaskListener { + void success(); + default void duplicate() {} + } + + public InsertCustomThemeAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + SharedPreferences lightThemeSharedPreferences, + SharedPreferences darkThemeSharedPreferences, + SharedPreferences amoledThemeSharedPreferences, + CustomTheme customTheme, boolean checkDuplicate, + InsertCustomThemeAsyncTaskListener insertCustomThemeAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.lightThemeSharedPreferences = lightThemeSharedPreferences; + this.darkThemeSharedPreferences = darkThemeSharedPreferences; + this.amoledThemeSharedPreferences = amoledThemeSharedPreferences; + this.customTheme = customTheme; + this.checkDuplicate = checkDuplicate; + this.insertCustomThemeAsyncTaskListener = insertCustomThemeAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + if (checkDuplicate) { + if (redditDataRoomDatabase.customThemeDao().getCustomTheme(customTheme.name) != null) { + isDuplicate = true; + return null; + } + } + CustomTheme previousTheme = redditDataRoomDatabase.customThemeDao().getCustomTheme(customTheme.name); + if (customTheme.isLightTheme) { + redditDataRoomDatabase.customThemeDao().unsetLightTheme(); + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(customTheme, lightThemeSharedPreferences); + } else if (previousTheme != null && previousTheme.isLightTheme) { + lightThemeSharedPreferences.edit().clear().apply(); + } + if (customTheme.isDarkTheme) { + redditDataRoomDatabase.customThemeDao().unsetDarkTheme(); + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(customTheme, darkThemeSharedPreferences); + } else if (previousTheme != null && previousTheme.isDarkTheme) { + darkThemeSharedPreferences.edit().clear().apply(); + } + if (customTheme.isAmoledTheme) { + redditDataRoomDatabase.customThemeDao().unsetAmoledTheme(); + CustomThemeSharedPreferencesUtils.insertThemeToSharedPreferences(customTheme, amoledThemeSharedPreferences); + } else if (previousTheme != null && previousTheme.isAmoledTheme) { + amoledThemeSharedPreferences.edit().clear().apply(); + } + redditDataRoomDatabase.customThemeDao().insert(customTheme); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (isDuplicate) { + insertCustomThemeAsyncTaskListener.duplicate(); + } else { + insertCustomThemeAsyncTaskListener.success(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertMultiRedditAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertMultiRedditAsyncTask.java new file mode 100644 index 00000000..b0351966 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertMultiRedditAsyncTask.java @@ -0,0 +1,94 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.multireddit.MultiRedditDao; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class InsertMultiRedditAsyncTask extends AsyncTask { + private MultiRedditDao multiRedditDao; + private ArrayList multiReddits; + private MultiReddit multiReddit; + private String accountName; + private InsertMultiRedditAsyncTaskListener insertMultiRedditAsyncTaskListener; + + public InsertMultiRedditAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + ArrayList multiReddits, String accountName, + InsertMultiRedditAsyncTaskListener insertMultiRedditAsyncTaskListener) { + multiRedditDao = redditDataRoomDatabase.multiRedditDao(); + this.multiReddits = multiReddits; + this.accountName = accountName; + this.insertMultiRedditAsyncTaskListener = insertMultiRedditAsyncTaskListener; + } + + public InsertMultiRedditAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + MultiReddit multiReddit, + InsertMultiRedditAsyncTaskListener insertMultiRedditAsyncTaskListener) { + multiRedditDao = redditDataRoomDatabase.multiRedditDao(); + this.multiReddit = multiReddit; + this.insertMultiRedditAsyncTaskListener = insertMultiRedditAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + if (multiReddit != null) { + multiRedditDao.insert(multiReddit); + return null; + } + + List existingMultiReddits = multiRedditDao.getAllMultiRedditsList(accountName); + Collections.sort(multiReddits, (multiReddit, t1) -> multiReddit.getName().compareToIgnoreCase(t1.getName())); + List deletedMultiredditNames = new ArrayList<>(); + compareTwoMultiRedditList(multiReddits, existingMultiReddits, deletedMultiredditNames); + + for (String deleted : deletedMultiredditNames) { + multiRedditDao.deleteMultiReddit(deleted, accountName); + } + + for (MultiReddit multiReddit : multiReddits) { + multiRedditDao.insert(multiReddit); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + insertMultiRedditAsyncTaskListener.success(); + } + + private void compareTwoMultiRedditList(List newMultiReddits, + List oldMultiReddits, + List deletedMultiReddits) { + int newIndex = 0; + for (int oldIndex = 0; oldIndex < oldMultiReddits.size(); oldIndex++) { + if (newIndex >= newMultiReddits.size()) { + for (; oldIndex < oldMultiReddits.size(); oldIndex++) { + deletedMultiReddits.add(oldMultiReddits.get(oldIndex).getName()); + } + return; + } + + MultiReddit old = oldMultiReddits.get(oldIndex); + for (; newIndex < newMultiReddits.size(); newIndex++) { + if (newMultiReddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) == 0) { + newIndex++; + break; + } + if (newMultiReddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) > 0) { + deletedMultiReddits.add(old.getName()); + break; + } + } + } + } + + public interface InsertMultiRedditAsyncTaskListener { + void success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubredditDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubredditDataAsyncTask.java new file mode 100644 index 00000000..c0085540 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubredditDataAsyncTask.java @@ -0,0 +1,35 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subreddit.SubredditDao; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; + +public class InsertSubredditDataAsyncTask extends AsyncTask { + private SubredditDao mSubredditDao; + private SubredditData subredditData; + private InsertSubredditDataAsyncTaskListener insertSubredditDataAsyncTaskListener; + + public InsertSubredditDataAsyncTask(RedditDataRoomDatabase db, SubredditData subredditData, + InsertSubredditDataAsyncTaskListener insertSubredditDataAsyncTaskListener) { + mSubredditDao = db.subredditDao(); + this.subredditData = subredditData; + this.insertSubredditDataAsyncTaskListener = insertSubredditDataAsyncTaskListener; + } + + @Override + protected Void doInBackground(final Void... params) { + mSubredditDao.insert(subredditData); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + insertSubredditDataAsyncTaskListener.insertSuccess(); + } + + public interface InsertSubredditDataAsyncTaskListener { + void insertSuccess(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubscribedThingsAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubscribedThingsAsyncTask.java new file mode 100644 index 00000000..0d67e183 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertSubscribedThingsAsyncTask.java @@ -0,0 +1,184 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subreddit.SubredditDao; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditDao; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserDao; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; + +public class InsertSubscribedThingsAsyncTask extends AsyncTask { + + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private String mAccountName; + private SubscribedSubredditDao mSubscribedSubredditDao; + private SubscribedUserDao mSubscribedUserDao; + private SubredditDao mSubredditDao; + private SubscribedSubredditData mSingleSubscribedSubredditData; + private SubscribedUserData mSingleSubscribedUserData; + private List subscribedSubredditDataList; + private List subscribedUserDataList; + private List subredditDataList; + private InsertSubscribedThingListener mInsertSubscribedThingListener; + + public InsertSubscribedThingsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, @Nullable String accountName, + List subscribedSubredditDataList, + List subscribedUserDataList, + List subredditDataList, + InsertSubscribedThingListener insertSubscribedThingListener) { + mRedditDataRoomDatabase = redditDataRoomDatabase; + mAccountName = accountName; + mSubscribedSubredditDao = redditDataRoomDatabase.subscribedSubredditDao(); + mSubscribedUserDao = redditDataRoomDatabase.subscribedUserDao(); + mSubredditDao = redditDataRoomDatabase.subredditDao(); + + this.subscribedSubredditDataList = subscribedSubredditDataList; + this.subscribedUserDataList = subscribedUserDataList; + this.subredditDataList = subredditDataList; + mInsertSubscribedThingListener = insertSubscribedThingListener; + } + + public InsertSubscribedThingsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + SubscribedSubredditData subscribedSubredditDataList, + InsertSubscribedThingListener insertSubscribedThingListener) { + mRedditDataRoomDatabase = redditDataRoomDatabase; + mSubscribedSubredditDao = redditDataRoomDatabase.subscribedSubredditDao(); + mAccountName = subscribedSubredditDataList.getUsername(); + mSingleSubscribedSubredditData = subscribedSubredditDataList; + mInsertSubscribedThingListener = insertSubscribedThingListener; + } + + public InsertSubscribedThingsAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + SubscribedUserData subscribedUserDataList, + InsertSubscribedThingListener insertSubscribedThingListener) { + mRedditDataRoomDatabase = redditDataRoomDatabase; + mSubscribedUserDao = redditDataRoomDatabase.subscribedUserDao(); + mAccountName = subscribedUserDataList.getUsername(); + mSingleSubscribedUserData = subscribedUserDataList; + mInsertSubscribedThingListener = insertSubscribedThingListener; + } + + @Override + protected Void doInBackground(final Void... params) { + if (mAccountName != null && mRedditDataRoomDatabase.accountDao().getAccountData(mAccountName) == null) { + return null; + } + + if (mSingleSubscribedSubredditData != null) { + mSubscribedSubredditDao.insert(mSingleSubscribedSubredditData); + } else if (mSingleSubscribedUserData != null) { + mSubscribedUserDao.insert(mSingleSubscribedUserData); + } else { + if (subscribedSubredditDataList != null) { + List existingSubscribedSubredditDataList = + mSubscribedSubredditDao.getAllSubscribedSubredditsList(mAccountName); + Collections.sort(subscribedSubredditDataList, (subscribedSubredditData, t1) -> subscribedSubredditData.getName().compareToIgnoreCase(t1.getName())); + List unsubscribedSubreddits = new ArrayList<>(); + compareTwoSubscribedSubredditList(subscribedSubredditDataList, existingSubscribedSubredditDataList, + unsubscribedSubreddits); + + for (String unsubscribed : unsubscribedSubreddits) { + mSubscribedSubredditDao.deleteSubscribedSubreddit(unsubscribed, mAccountName); + } + + for (SubscribedSubredditData s : subscribedSubredditDataList) { + mSubscribedSubredditDao.insert(s); + } + } + + if (subscribedUserDataList != null) { + List existingSubscribedUserDataList = + mSubscribedUserDao.getAllSubscribedUsersList(mAccountName); + Collections.sort(subscribedUserDataList, (subscribedUserData, t1) -> subscribedUserData.getName().compareToIgnoreCase(t1.getName())); + List unsubscribedUsers = new ArrayList<>(); + compareTwoSubscribedUserList(subscribedUserDataList, existingSubscribedUserDataList, + unsubscribedUsers); + + for (String unsubscribed : unsubscribedUsers) { + mSubscribedUserDao.deleteSubscribedUser(unsubscribed, mAccountName); + } + + for (SubscribedUserData s : subscribedUserDataList) { + mSubscribedUserDao.insert(s); + } + } + + if (subredditDataList != null) { + for (SubredditData s : subredditDataList) { + mSubredditDao.insert(s); + } + } + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + mInsertSubscribedThingListener.insertSuccess(); + } + + private void compareTwoSubscribedSubredditList(List newSubscribedSubreddits, + List oldSubscribedSubreddits, + List unsubscribedSubredditNames) { + int newIndex = 0; + for (int oldIndex = 0; oldIndex < oldSubscribedSubreddits.size(); oldIndex++) { + if (newIndex >= newSubscribedSubreddits.size()) { + for (; oldIndex < oldSubscribedSubreddits.size(); oldIndex++) { + unsubscribedSubredditNames.add(oldSubscribedSubreddits.get(oldIndex).getName()); + } + return; + } + + SubscribedSubredditData old = oldSubscribedSubreddits.get(oldIndex); + for (; newIndex < newSubscribedSubreddits.size(); newIndex++) { + if (newSubscribedSubreddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) == 0) { + newIndex++; + break; + } + if (newSubscribedSubreddits.get(newIndex).getName().compareToIgnoreCase(old.getName()) > 0) { + unsubscribedSubredditNames.add(old.getName()); + break; + } + } + } + } + + private void compareTwoSubscribedUserList(List newSubscribedUsers, + List oldSubscribedUsers, + List unsubscribedUserNames) { + int newIndex = 0; + for (int oldIndex = 0; oldIndex < oldSubscribedUsers.size(); oldIndex++) { + if (newIndex >= newSubscribedUsers.size()) { + for (; oldIndex < oldSubscribedUsers.size(); oldIndex++) { + unsubscribedUserNames.add(oldSubscribedUsers.get(oldIndex).getName()); + } + return; + } + + SubscribedUserData old = oldSubscribedUsers.get(oldIndex); + for (; newIndex < newSubscribedUsers.size(); newIndex++) { + if (newSubscribedUsers.get(newIndex).getName().compareToIgnoreCase(old.getName()) == 0) { + newIndex++; + break; + } + if (newSubscribedUsers.get(newIndex).getName().compareToIgnoreCase(old.getName()) > 0) { + unsubscribedUserNames.add(old.getName()); + break; + } + } + } + } + + public interface InsertSubscribedThingListener { + void insertSuccess(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertUserDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertUserDataAsyncTask.java new file mode 100644 index 00000000..caf2f7f1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/InsertUserDataAsyncTask.java @@ -0,0 +1,36 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.user.UserDao; +import ml.docilealligator.infinityforreddit.user.UserData; + +public class InsertUserDataAsyncTask extends AsyncTask { + private UserDao userDao; + private UserData userData; + private InsertUserDataCallback insertUserDataCallback; + + public InsertUserDataAsyncTask(UserDao userDao, UserData userData, InsertUserDataCallback insertUserDataCallback) { + this.userDao = userDao; + this.userData = userData; + this.insertUserDataCallback = insertUserDataCallback; + } + + @Override + protected Void doInBackground(Void... voids) { + userDao.insert(userData); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (insertUserDataCallback != null) { + insertUserDataCallback.insertSuccess(); + } + } + + public interface InsertUserDataCallback { + void insertSuccess(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadSubredditIconAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadSubredditIconAsyncTask.java new file mode 100644 index 00000000..7092bae7 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadSubredditIconAsyncTask.java @@ -0,0 +1,71 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subreddit.SubredditDao; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import retrofit2.Retrofit; + +public class LoadSubredditIconAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private SubredditDao subredditDao; + private String subredditName; + private Retrofit retrofit; + private String iconImageUrl; + private boolean hasSubredditInDb; + private LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener; + public LoadSubredditIconAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String subredditName, Retrofit retrofit, + LoadSubredditIconAsyncTaskListener loadSubredditIconAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.subredditDao = redditDataRoomDatabase.subredditDao(); + this.subredditName = subredditName; + this.retrofit = retrofit; + this.loadSubredditIconAsyncTaskListener = loadSubredditIconAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + SubredditData subredditData = subredditDao.getSubredditData(subredditName); + if (subredditData != null) { + iconImageUrl = subredditDao.getSubredditData(subredditName).getIconUrl(); + hasSubredditInDb = true; + } else { + hasSubredditInDb = false; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (!isCancelled()) { + if (hasSubredditInDb) { + loadSubredditIconAsyncTaskListener.loadIconSuccess(iconImageUrl); + } else { + FetchSubredditData.fetchSubredditData(retrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { + @Override + public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { + ArrayList singleSubredditDataList = new ArrayList<>(); + singleSubredditDataList.add(subredditData); + new InsertSubscribedThingsAsyncTask(redditDataRoomDatabase, null, + null, null, singleSubredditDataList, + () -> loadSubredditIconAsyncTaskListener.loadIconSuccess(subredditData.getIconUrl())).execute(); + } + + @Override + public void onFetchSubredditDataFail() { + loadSubredditIconAsyncTaskListener.loadIconSuccess(null); + } + }); + } + } + } + + public interface LoadSubredditIconAsyncTaskListener { + void loadIconSuccess(String iconImageUrl); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadUserDataAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadUserDataAsyncTask.java new file mode 100644 index 00000000..3386965e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/LoadUserDataAsyncTask.java @@ -0,0 +1,58 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.user.FetchUserData; +import ml.docilealligator.infinityforreddit.user.UserDao; +import ml.docilealligator.infinityforreddit.user.UserData; +import retrofit2.Retrofit; + +public class LoadUserDataAsyncTask extends AsyncTask { + private UserDao userDao; + private String userName; + private String iconImageUrl; + private boolean hasUserInDb; + private Retrofit retrofit; + private LoadUserDataAsyncTaskListener loadUserDataAsyncTaskListener; + public LoadUserDataAsyncTask(UserDao userDao, String userName, Retrofit retrofit, LoadUserDataAsyncTaskListener loadUserDataAsyncTaskListener) { + this.userDao = userDao; + this.userName = userName; + this.retrofit = retrofit; + this.loadUserDataAsyncTaskListener = loadUserDataAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + if (userDao.getUserData(userName) != null) { + iconImageUrl = userDao.getUserData(userName).getIconUrl(); + hasUserInDb = true; + } else { + hasUserInDb = false; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (hasUserInDb) { + loadUserDataAsyncTaskListener.loadUserDataSuccess(iconImageUrl); + } else { + FetchUserData.fetchUserData(retrofit, userName, new FetchUserData.FetchUserDataListener() { + @Override + public void onFetchUserDataSuccess(UserData userData) { + new InsertUserDataAsyncTask(userDao, userData, () -> loadUserDataAsyncTaskListener.loadUserDataSuccess(userData.getIconUrl())).execute(); + } + + @Override + public void onFetchUserDataFailed() { + loadUserDataAsyncTaskListener.loadUserDataSuccess(null); + } + }); + } + } + + public interface LoadUserDataAsyncTaskListener { + void loadUserDataSuccess(String iconImageUrl); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ParseAndInsertNewAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ParseAndInsertNewAccountAsyncTask.java new file mode 100644 index 00000000..7563803e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/ParseAndInsertNewAccountAsyncTask.java @@ -0,0 +1,50 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.account.AccountDao; + +public class ParseAndInsertNewAccountAsyncTask extends AsyncTask { + + private String username; + private String accessToken; + private String refreshToken; + private String profileImageUrl; + private String bannerImageUrl; + private int karma; + private String code; + private AccountDao accountDao; + private ParseAndInsertAccountListener parseAndInsertAccountListener; + public ParseAndInsertNewAccountAsyncTask(String username, String accessToken, String refreshToken, String profileImageUrl, String bannerImageUrl, + int karma, String code, AccountDao accountDao, + ParseAndInsertAccountListener parseAndInsertAccountListener) { + this.username = username; + this.accessToken = accessToken; + this.refreshToken = refreshToken; + this.profileImageUrl = profileImageUrl; + this.bannerImageUrl = bannerImageUrl; + this.karma = karma; + this.code = code; + this.accountDao = accountDao; + this.parseAndInsertAccountListener = parseAndInsertAccountListener; + } + + @Override + protected Void doInBackground(Void... voids) { + Account account = new Account(username, accessToken, refreshToken, code, profileImageUrl, + bannerImageUrl, karma, true); + accountDao.markAllAccountsNonCurrent(); + accountDao.insert(account); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + parseAndInsertAccountListener.success(); + } + + public interface ParseAndInsertAccountListener { + void success(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveBitmapImageToFileAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveBitmapImageToFileAsyncTask.java new file mode 100644 index 00000000..7af3fba4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveBitmapImageToFileAsyncTask.java @@ -0,0 +1,55 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.graphics.Bitmap; +import android.os.AsyncTask; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public class SaveBitmapImageToFileAsyncTask extends AsyncTask { + private Bitmap resource; + private String cacheDirPath; + private String fileName; + private SaveBitmapImageToFileAsyncTaskListener saveBitmapImageToFileAsyncTaskListener; + private boolean saveSuccess = true; + private File imageFile; + + public SaveBitmapImageToFileAsyncTask(Bitmap resource, String cacheDirPath, String fileName, + SaveBitmapImageToFileAsyncTaskListener saveBitmapImageToFileAsyncTaskListener) { + this.resource = resource; + this.cacheDirPath = cacheDirPath; + this.fileName = fileName; + this.saveBitmapImageToFileAsyncTaskListener = saveBitmapImageToFileAsyncTaskListener; + } + + public interface SaveBitmapImageToFileAsyncTaskListener { + void saveSuccess(File imageFile); + void saveFailed(); + } + + @Override + protected Void doInBackground(Void... voids) { + try { + imageFile = new File(cacheDirPath, fileName); + OutputStream outputStream = new FileOutputStream(imageFile); + resource.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); + outputStream.flush(); + outputStream.close(); + } catch (IOException e) { + saveSuccess = false; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (saveSuccess) { + saveBitmapImageToFileAsyncTaskListener.saveSuccess(imageFile); + } else { + saveBitmapImageToFileAsyncTaskListener.saveFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveGIFToFileAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveGIFToFileAsyncTask.java new file mode 100644 index 00000000..52a86e2c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SaveGIFToFileAsyncTask.java @@ -0,0 +1,59 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import com.bumptech.glide.load.resource.gif.GifDrawable; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; + +public class SaveGIFToFileAsyncTask extends AsyncTask { + private GifDrawable resource; + private String cacheDirPath; + private String fileName; + private SaveGIFToFileAsyncTaskListener saveImageToFileAsyncTaskListener; + private boolean saveSuccess = true; + private File imageFile; + + public SaveGIFToFileAsyncTask(GifDrawable resource, String cacheDirPath, String fileName, + SaveGIFToFileAsyncTaskListener saveImageToFileAsyncTaskListener) { + this.resource = resource; + this.cacheDirPath = cacheDirPath; + this.fileName = fileName; + this.saveImageToFileAsyncTaskListener = saveImageToFileAsyncTaskListener; + } + + public interface SaveGIFToFileAsyncTaskListener { + void saveSuccess(File imageFile); + void saveFailed(); + } + + @Override + protected Void doInBackground(Void... voids) { + try { + imageFile = new File(cacheDirPath, fileName); + ByteBuffer byteBuffer = resource.getBuffer(); + OutputStream outputStream = new FileOutputStream(imageFile); + byte[] bytes = new byte[byteBuffer.capacity()]; + ((ByteBuffer) byteBuffer.duplicate().clear()).get(bytes); + outputStream.write(bytes, 0, bytes.length); + outputStream.close(); + } catch (IOException e) { + saveSuccess = false; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (saveSuccess) { + saveImageToFileAsyncTaskListener.saveSuccess(imageFile); + } else { + saveImageToFileAsyncTaskListener.saveFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SetAsWallpaperAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SetAsWallpaperAsyncTask.java new file mode 100644 index 00000000..c613cb9c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SetAsWallpaperAsyncTask.java @@ -0,0 +1,95 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.app.WallpaperManager; +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.media.ThumbnailUtils; +import android.os.AsyncTask; +import android.os.Build; +import android.util.DisplayMetrics; +import android.view.WindowManager; + +import java.io.IOException; + +import ml.docilealligator.infinityforreddit.WallpaperSetter; + +public class SetAsWallpaperAsyncTask extends AsyncTask { + + private Bitmap bitmap; + private int setTo; + private WallpaperManager manager; + private WindowManager windowManager; + private WallpaperSetter.SetWallpaperListener setWallpaperListener; + private boolean success = true; + + public SetAsWallpaperAsyncTask(Bitmap bitmap, int setTo, WallpaperManager manager, WindowManager windowManager, + WallpaperSetter.SetWallpaperListener setWallpaperListener) { + this.bitmap = bitmap; + this.setTo = setTo; + this.manager = manager; + this.windowManager = windowManager; + this.setWallpaperListener = setWallpaperListener; + } + + @Override + protected Void doInBackground(Void... voids) { + DisplayMetrics metrics = new DisplayMetrics(); + Rect rect = null; + + if (windowManager != null) { + windowManager.getDefaultDisplay().getMetrics(metrics); + int height = metrics.heightPixels; + int width = metrics.widthPixels; + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) { + bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height); + } + + float imageAR = (float) bitmap.getWidth() / (float) bitmap.getHeight(); + float screenAR = (float) width / (float) height; + + if (imageAR > screenAR) { + int desiredWidth = (int) (bitmap.getHeight() * screenAR); + rect = new Rect((bitmap.getWidth() - desiredWidth) / 2, 0, bitmap.getWidth(), bitmap.getHeight()); + } else { + int desiredHeight = (int) (bitmap.getWidth() / screenAR); + rect = new Rect(0, (bitmap.getHeight() - desiredHeight) / 2, bitmap.getWidth(), (bitmap.getHeight() + desiredHeight) / 2); + } + } + try { + switch (setTo) { + case WallpaperSetter.HOME_SCREEN: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + manager.setBitmap(bitmap, rect, true, WallpaperManager.FLAG_SYSTEM); + } + break; + case WallpaperSetter.LOCK_SCREEN: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + manager.setBitmap(bitmap, rect, true, WallpaperManager.FLAG_LOCK); + } + break; + case WallpaperSetter.BOTH_SCREENS: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + manager.setBitmap(bitmap, rect, true, WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK); + } else { + manager.setBitmap(bitmap); + } + break; + } + } catch (IOException e) { + success = false; + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (success) { + setWallpaperListener.success(); + } else { + setWallpaperListener.failed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchAccountAsyncTask.java new file mode 100644 index 00000000..227e6082 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchAccountAsyncTask.java @@ -0,0 +1,36 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SwitchAccountAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private String newAccountName; + private Account account; + private SwitchAccountAsyncTaskListener switchAccountAsyncTaskListener; + public SwitchAccountAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String newAccountName, + SwitchAccountAsyncTaskListener switchAccountAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.newAccountName = newAccountName; + this.switchAccountAsyncTaskListener = switchAccountAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.accountDao().markAllAccountsNonCurrent(); + redditDataRoomDatabase.accountDao().markAccountCurrent(newAccountName); + account = redditDataRoomDatabase.accountDao().getCurrentAccount(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + switchAccountAsyncTaskListener.switched(account); + } + + public interface SwitchAccountAsyncTaskListener { + void switched(Account account); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchToAnonymousAccountAsyncTask.java b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchToAnonymousAccountAsyncTask.java new file mode 100644 index 00000000..c0e0da14 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/asynctasks/SwitchToAnonymousAccountAsyncTask.java @@ -0,0 +1,37 @@ +package ml.docilealligator.infinityforreddit.asynctasks; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.account.AccountDao; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SwitchToAnonymousAccountAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private boolean removeCurrentAccount; + private SwitchToAnonymousAccountAsyncTaskListener switchToAnonymousAccountAsyncTaskListener; + public SwitchToAnonymousAccountAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, boolean removeCurrentAccount, + SwitchToAnonymousAccountAsyncTaskListener switchToAnonymousAccountAsyncTaskListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.removeCurrentAccount = removeCurrentAccount; + this.switchToAnonymousAccountAsyncTaskListener = switchToAnonymousAccountAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + AccountDao accountDao = redditDataRoomDatabase.accountDao(); + if (removeCurrentAccount) { + accountDao.deleteCurrentAccount(); + } + accountDao.markAllAccountsNonCurrent(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + switchToAnonymousAccountAsyncTaskListener.logoutSuccess(); + } + + public interface SwitchToAnonymousAccountAsyncTaskListener { + void logoutSuccess(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/award/Award.java b/app/src/main/java/ml/docilealligator/infinityforreddit/award/Award.java new file mode 100644 index 00000000..5188702d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/award/Award.java @@ -0,0 +1,143 @@ +package ml.docilealligator.infinityforreddit.award; + +import java.util.ArrayList; + +public class Award { + private String id; + private String awardSubType; + private String name; + private String description; + private String iconUrl; + private int coinPrice; + + public Award(String id, String awardSubType, String name, String description, String iconUrl, int coinPrice) { + this.id = id; + this.awardSubType = awardSubType; + this.name = name; + this.description = description; + this.iconUrl = iconUrl; + this.coinPrice = coinPrice; + } + + public static ArrayList getAvailableAwards() { + ArrayList awards = new ArrayList<>(); + awards.add(new Award("gid_2", "GLOBAL", "Gold", "Gives the author a week of Reddit Premium, 100 Coins to do with as they please, and shows a Gold Award.", "https://www.redditstatic.com/gold/awards/icon/gold_512.png", 500)); + awards.add(new Award("gid_3", "GLOBAL", "Platinum", "Gives the author a month of Reddit Premium, which includes 700 Coins for that month, and shows a Platinum Award.", "https://www.redditstatic.com/gold/awards/icon/platinum_512.png", 1800)); + awards.add(new Award("award_4ca5a4e6-8873-4ac5-99b9-71b1d5161a91", "GLOBAL", "Argentium", "Latin for distinguished. Shimmers like silver & stronger than steel. When someone deserves outsize recognition. This award gives a three-month Premium subscription and 2500 coins to the recipient.", "https://www.redditstatic.com/gold/awards/icon/Mithril_512.png", 20000)); + awards.add(new Award("award_2385c499-a1fb-44ec-b9b7-d260f3dc55de", "GLOBAL", "Ternion All-Powerful", "Legendary level. A no holds barred celebration of something that hits you in the heart, mind and soul. Some might call it unachievanium. Gives the author 6 months of Premium and 5000 Coins.", "https://www.redditstatic.com/gold/awards/icon/Trinity_512.png", 50000)); + awards.add(new Award("gid_1", "GLOBAL", "Silver", "Shows the Silver Award... and that's it.", "https://www.redditstatic.com/gold/awards/icon/silver_512.png", 100)); + awards.add(new Award("award_e55d1889-11f2-4d04-8abb-44b1de7dd53d", "GLOBAL", "Aww-some", "Use the Aww-some Award to highlight comments that are absolutely adorable.", "https://www.redditstatic.com/gold/awards/icon/Awwsome_512.png", 350)); + awards.add(new Award("award_11eb6af3-3d0d-4d70-8261-22d216ab591d", "GLOBAL", "Heartbeat", "Use the Heartbeat Award to highlight comments that make you feel warm and fuzzy", "https://www.redditstatic.com/gold/awards/icon/Heartbeat_512.png", 350)); + awards.add(new Award("award_0e957fb0-c8f1-4ba1-a8ef-e1e524b60d7d", "GLOBAL", "Starry", "Use the Starry Award to highlight comments that deserve to stand out from the crowd.", "https://www.redditstatic.com/gold/awards/icon/Starry_512.png", 500)); + awards.add(new Award("award_75f9bc56-eba3-4988-a1af-aec974404a0b", "GROUP", "Super Medal Train", "All aboard! Every 5 Awards gives the author 100 Coins and 1 week of Premium. Rack up the number of Awards and watch the Train level-up.", "https://i.redd.it/award_images/t5_22cerq/v3wyujfap4p51_SuperMedalTrain.png", 125)); + awards.add(new Award("award_7149a401-1223-4543-bfd6-4127cb4246da", "GLOBAL", "Cool Summer", "The key is to keep your cool this summer.", "https://i.redd.it/award_images/t5_22cerq/1m9abin81nc51_CoolSummer.png", 50)); + awards.add(new Award("award_02d9ab2c-162e-4c01-8438-317a016ed3d9", "GLOBAL", "Take My Energy", "I'm in this with you.", "https://i.redd.it/award_images/t5_22cerq/898sygoknoo41_TakeMyEnergy.png", 50)); + awards.add(new Award("award_7becef23-fb0b-4d62-b8a6-01d5759367cb", "GLOBAL", "Faith In Humanity Restored", "When goodness lifts you", "https://i.redd.it/award_images/t5_22cerq/gva4vt20qc751_FaithInHumanityRestored.png", 70)); + awards.add(new Award("award_84276b1e-cc8f-484f-a19c-be6c09adc1a5", "GLOBAL", "Bravo!", "An amazing showing.", "https://www.redditstatic.com/gold/awards/icon/SnooClapping_512.png", 400)); + awards.add(new Award("award_68ba1ee3-9baf-4252-be52-b808c1e8bdc4", "GLOBAL", "This", "Me approved", "https://i.redd.it/award_images/t5_22cerq/vu6om0xnb7e41_This.png", 300)); + awards.add(new Award("award_1f0462ee-18f5-4f33-89cf-f1f79336a452", "GLOBAL", "Wholesome (Pro)", "When you come across a feel-good thing. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/0o2j782f00e41_WholesomeSuperpro.png", 500)); + awards.add(new Award("award_3dd248bc-3438-4c5b-98d4-24421fd6d670", "GLOBAL", "Coin Gift", "Give the gift of 250 Reddit Coins.", "https://i.redd.it/award_images/t5_22cerq/cr1mq4yysv541_CoinGift.png", 300)); + awards.add(new Award("award_2ae56630-cfe0-424e-b810-4945b9145358", "GLOBAL", "Helpful (Pro)", "Thank you stranger. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/trz28na8ajz31_Helpful.png", 500)); + awards.add(new Award("award_6220ecfe-4552-4949-aa13-fb1fb7db537c", "GLOBAL", "Super Heart Eyes", "When the love is out of control.", "https://www.redditstatic.com/gold/awards/icon/Superheart_512.png", 325)); + awards.add(new Award("award_5b39e8fd-7a58-4cbe-8ca0-bdedd5ed1f5a", "GLOBAL", "Doot 🎵 Doot", "Sometimes you just got to dance with the doots.", "https://www.redditstatic.com/gold/awards/icon/Updoot_512.png", 400)); + awards.add(new Award("award_9f928aff-c9f5-4e7e-aa91-8619dce60f1c", "GLOBAL", "Table Slap", "When laughter meets percussion", "https://www.redditstatic.com/gold/awards/icon/TableSlap_512.png", 325)); + awards.add(new Award("award_3409a4c0-ba69-43a0-be9f-27bc27c159cc", "GLOBAL", "Spit-take", "Shower them with laughs", "https://www.redditstatic.com/gold/awards/icon/Spits_drink_512.png", 325)); + awards.add(new Award("award_3267ca1c-127a-49e9-9a3d-4ba96224af18", "GLOBAL", "I'll Drink to That", "Let's sip to good health and good company", "https://i.redd.it/award_images/t5_22cerq/45aeu8mzvsj51_IllDrinktoThat.png", 100)); + awards.add(new Award("award_31260000-2f4a-4b40-ad20-f5aa46a577bf", "APPRECIATION", "Timeless Beauty", "Beauty that's forever. Gives 100 Coins each to the author and the community.", "https://i.redd.it/award_images/t5_22cerq/crhlsu5wzlc41_TimelessBeauty.png", 250)); + awards.add(new Award("award_69c94eb4-d6a3-48e7-9cf2-0f39fed8b87c", "GLOBAL", "Ally", "Listen, get educated, and get involved.", "https://i.redd.it/award_images/t5_22cerq/5nswjpyy44551_Ally.png", 50)); + awards.add(new Award("award_a903c949-ccc5-420d-8239-1bbefc424838", "GLOBAL", "Healthcare Hero", "Putting yourself on the line for us - you are the perfect super hero!", "https://i.redd.it/award_images/t5_22cerq/xs2na1t1v9p41_HealthcareHero.png", 50)); + awards.add(new Award("award_03c4f93d-efc7-463b-98a7-c01814462ab0", "GLOBAL", "I am disappoint", "I'm not mad, I'm just disappointed.", "https://i.redd.it/award_images/t5_22cerq/3ekkailk5s551_Iamdisappoint.png", 50)); + awards.add(new Award("award_d33fddd7-a58a-4472-b1a2-3157d8c8b76f", "GLOBAL", "Looking Busy", "Looking like you're working is hard work.", "https://i.redd.it/award_images/t5_22cerq/k0qzautvyyk51_LookingBusy.png", 50)); + awards.add(new Award("award_e1b2bf9e-8c62-4edc-9b6d-ffa44a7cb53b", "GLOBAL", "Recharge", "Feeling relaxed and restored", "https://i.redd.it/award_images/t5_22cerq/0lurnbnhqkl51_Recharge.png", 50)); + awards.add(new Award("award_80d4d339-95d0-43ac-b051-bc3fe0a9bab8", "GLOBAL", "Wearing is Caring", "Keep the community and yourself healthy and happy.", "https://i.redd.it/award_images/t5_22cerq/lcswc5d07hb51_WearingisCaring.png", 50)); + awards.add(new Award("award_b1b44fa1-8179-4d84-a9ed-f25bb81f1c5f", "GLOBAL", "Facepalm", "*Lowers face into palm*", "https://i.redd.it/award_images/t5_22cerq/ey2iodron2s41_Facepalm.png", 70)); + awards.add(new Award("award_99d95969-6100-45b2-b00c-0ec45ae19596", "GLOBAL", "Snek", "A smol, delicate danger noodle.", "https://i.redd.it/award_images/t5_22cerq/rc5iesz2z8t41_Snek.png", 70)); + awards.add(new Award("award_b92370bb-b7de-4fb3-9608-c5b4a22f714a", "GLOBAL", "Tree Hug", "Show nature some love.", "https://i.redd.it/award_images/t5_22cerq/fukjtec638u41_TreeHug.png", 70)); + awards.add(new Award("award_ae89e420-c4a5-47b8-a007-5dacf1c0f0d4", "GLOBAL", "Lawyer Up", "OBJECTION!", "https://i.redd.it/award_images/t5_22cerq/iq0sgwn5bzy41_LawyerUp.png", 75)); + awards.add(new Award("award_8352bdff-3e03-4189-8a08-82501dd8f835", "GLOBAL", "Hugz", "Everything is better with a good hug", "https://i.redd.it/award_images/t5_22cerq/niiatoknifn51_Hugz.png", 80)); + awards.add(new Award("award_869d4135-8738-41e5-8630-de593b4f049f", "GLOBAL", "'MURICA", "Did somebody say 'Murica?", "https://i.redd.it/award_images/t5_22cerq/18mwqw5th9e51_MURICA.png", 100)); + awards.add(new Award("award_81cf5c92-8500-498c-9c94-3e4034cece0a", "GLOBAL", "Dread", "Staring into the abyss and it's staring right back", "https://i.redd.it/award_images/t5_22cerq/nvfe4gyawnf51_Dread.png", 100)); + awards.add(new Award("award_483d8e29-bbe5-404e-a09a-c2d7b16c4fff", "GLOBAL", "Evil Cackle", "Laugh like a supervillain", "https://i.redd.it/award_images/t5_22cerq/43zl6dfcg9e51_EvilCackle.png", 100)); + awards.add(new Award("award_74fe5152-7906-4991-9016-bc2d8e261200", "GLOBAL", "Excited", "I don't know what to do with my hands!", "https://i.redd.it/award_images/t5_22cerq/x069ow7ewnf51_Excited.png", 100)); + awards.add(new Award("award_01178870-6a4f-4172-8f36-9ed5092ee4f9", "GLOBAL", "Glow Up", "You look amazing, glowing, incredible!", "https://i.redd.it/award_images/t5_22cerq/2754pa5jvsj51_GlowUp.png", 100)); + awards.add(new Award("award_19860e30-3331-4bac-b3d1-bd28de0c7974", "GLOBAL", "Heartwarming", "I needed this today", "https://i.redd.it/award_images/t5_22cerq/v1mxw8i6wnf51_Heartwarming.png", 100)); + awards.add(new Award("award_1da6ff27-7c0d-4524-9954-86e5cda5fcac", "GLOBAL", "Keep Calm", "Stop, chill, relax", "https://i.redd.it/award_images/t5_22cerq/g77c4oud7hb51_KeepCalm.png", 100)); + awards.add(new Award("award_1e516e18-cbee-4668-b338-32d5530f91fe", "GLOBAL", "Kiss", "You deserve a smooch", "https://i.redd.it/award_images/t5_22cerq/sb42u5gmwsj51_Kiss.png", 100)); + awards.add(new Award("award_b4072731-c0fb-4440-adc7-1063d6a5e6a0", "GLOBAL", "Masterpiece", "C'est magnifique", "https://i.redd.it/award_images/t5_22cerq/2juh333m40n51_Masterpiece.png", 100)); + awards.add(new Award("award_fbe9527a-adb3-430e-af1a-5fd3489e641b", "GLOBAL", "Shocked", "I'm genuinely flabbergasted.", "https://i.redd.it/award_images/t5_22cerq/fck3iedi2ug51_Shocked.png", 100)); + awards.add(new Award("award_0b41ba9b-8ad9-42c8-85b1-942d5462c830", "GLOBAL", "Starts Recording", "This should be good", "https://i.redd.it/award_images/t5_22cerq/zlrdwu9kh9e51_StartsRecording.png", 100)); + awards.add(new Award("award_43f3bf99-92d6-47ab-8205-130d26e7929f", "GLOBAL", "Tearing Up", "This hits me right in the feels", "https://i.redd.it/award_images/t5_22cerq/lop66ut2wnf51_TearingUp.png", 100)); + awards.add(new Award("award_ae7f17fb-6538-4c75-9ff4-5f48b4cdaa94", "GLOBAL", "Yummy", "That looks so good", "https://i.redd.it/award_images/t5_22cerq/a7dhg27hvnf51_Yummy.png", 100)); + awards.add(new Award("award_5f123e3d-4f48-42f4-9c11-e98b566d5897", "GLOBAL", "Wholesome", "When you come across a feel-good thing.", "https://i.redd.it/award_images/t5_22cerq/5izbv4fn0md41_Wholesome.png", 125)); + awards.add(new Award("award_77ba55a2-c33c-4351-ac49-807455a80148", "GLOBAL", "Bless Up", "Prayers up for the blessed.", "https://i.redd.it/award_images/t5_22cerq/trfv6ems1md41_BlessUp.png", 150)); + awards.add(new Award("award_c42dc561-0b41-40b6-a23d-ef7e110e739e", "GLOBAL", "Buff Doge", "So buff, wow", "https://i.redd.it/award_images/t5_22cerq/zc4a9vk5zmc51_BuffDoge.png", 150)); + awards.add(new Award("award_f44611f1-b89e-46dc-97fe-892280b13b82", "GLOBAL", "Helpful", "Thank you stranger. Shows the award.", "https://i.redd.it/award_images/t5_22cerq/klvxk1wggfd41_Helpful.png", 150)); + awards.add(new Award("award_88fdcafc-57a0-48db-99cc-76276bfaf28b", "GLOBAL", "Press F", "To pay respects.", "https://i.redd.it/award_images/t5_22cerq/tcofsbf92md41_PressF.png", 150)); + awards.add(new Award("award_a7f9cbd7-c0f1-4569-a913-ebf8d18de00b", "GLOBAL", "Take My Money", "I'm buying what you're selling", "https://i.redd.it/award_images/t5_22cerq/9jr8pv84v7i51_TakeMyMoney.png", 150)); + awards.add(new Award("award_a9968927-3f72-4af9-8bcd-aaf804838dc6", "GLOBAL", "Back Away", "...slowly", "https://i.redd.it/award_images/t5_22cerq/t5z1oc8t2ug51_BackAway.png", 200)); + awards.add(new Award("award_e813313c-1002-49bf-ac37-e966710f605f", "GLOBAL", "Giggle", "Innocent laughter", "https://www.redditstatic.com/gold/awards/icon/Giggle_512.png", 200)); + awards.add(new Award("award_1703f934-cf44-40cc-a96d-3729d0b48262", "GLOBAL", "I'd Like to Thank...", "My kindergarten teacher, my cat, my mom, and you.", "https://i.redd.it/award_images/t5_22cerq/8ad2jffnclf41_Thanks.png", 200)); + awards.add(new Award("award_b28d9565-4137-433d-bb65-5d4aa82ade4c", "GLOBAL", "I'm Deceased", "Call an ambulance, I'm laughing too hard.", "https://i.redd.it/award_images/t5_22cerq/2jd92wtn25g41_ImDeceased.png", 200)); + awards.add(new Award("award_4922c1be-3646-4d62-96ea-19a56798df51", "GLOBAL", "Looking", "I can't help but look.", "https://i.redd.it/award_images/t5_22cerq/kjpl76213ug51_Looking.png", 200)); + awards.add(new Award("award_9ee30a8f-463e-4ef7-9da9-a09f270ec026", "GLOBAL", "Stonks Falling", "Losing value fast.", "https://i.redd.it/award_images/t5_22cerq/ree13odobef41_StonksFalling.png", 200)); + awards.add(new Award("award_d125d124-5c03-490d-af3d-d07c462003da", "GLOBAL", "Stonks Rising", "To the MOON.", "https://i.redd.it/award_images/t5_22cerq/s5edqq9abef41_StonksRising.png", 200)); + awards.add(new Award("award_dc391ef9-0df8-468f-bd3c-7b177092de35", "GLOBAL", "This is 2020", "Every reason to be alarmed", "https://i.redd.it/award_images/t5_22cerq/ncon692ev7i51_Thisis2020.png", 200)); + awards.add(new Award("award_11be92ba-509e-46d3-991b-593239006521", "GLOBAL", "1UP", "Extra life", "https://www.redditstatic.com/gold/awards/icon/Levelup_512.png", 250)); + awards.add(new Award("award_351f8639-ee3b-4def-adf3-6b39980c278a", "GLOBAL", "2020 Vision", "Looking into the present.", "https://i.redd.it/award_images/t5_22cerq/48eychq6e9741_2020Vision.png", 300)); + awards.add(new Award("award_cc299d65-77de-4828-89de-708b088349a0", "GLOBAL", "GOAT", "Historical anomaly - greatest in eternity.", "https://i.redd.it/award_images/t5_22cerq/x52x5be57fd41_GOAT.png", 300)); + awards.add(new Award("award_8dc476c7-1478-4d41-b940-f139e58f7756", "GLOBAL", "Got the W", "", "https://i.redd.it/award_images/t5_22cerq/9avdcwgupta41_GottheW.png", 300)); + awards.add(new Award("award_28e8196b-d4e9-45bc-b612-cd4c7d3ed4b3", "GLOBAL", "Rocket Like", "When an upvote just isn't enough, smash the Rocket Like.", "https://i.redd.it/award_images/t5_22cerq/94pn64yuas941_RocketLike.png", 300)); + awards.add(new Award("award_3e000ecb-c1a4-49dc-af14-c8ac2029ca97", "GLOBAL", "Table Flip", "ARGH!", "https://i.redd.it/award_images/t5_22cerq/a05z7bb9v7i51_TableFlip.png", 300)); + awards.add(new Award("award_725b427d-320b-4d02-8fb0-8bb7aa7b78aa", "GLOBAL", "Updoot", "Sometimes you just got to doot.", "https://i.redd.it/award_images/t5_22cerq/7atjjqpy1mc41_Updoot.png", 300)); + awards.add(new Award("award_c043e7ef-8514-4862-99c6-45e36cec4f66", "GLOBAL", "OOF", "That hurts", "https://www.redditstatic.com/gold/awards/icon/OOF_512.png", 325)); + awards.add(new Award("award_2bc47247-b107-44a8-a78c-613da21869ff", "GLOBAL", "To The Stars", "Boldly go where we haven't been in a long, long time.", "https://www.redditstatic.com/gold/awards/icon/Rocket_512.png", 325)); + awards.add(new Award("award_2ff1fdd0-ff73-47e6-a43c-bde6d4de8fbd", "GLOBAL", "Into the Magic Portal", "Hope to make it to the other side.", "https://www.redditstatic.com/gold/awards/icon/TeleportIn_512.png", 350)); + awards.add(new Award("award_7fe72f36-1141-4a39-ba76-0d481889b390", "GLOBAL", "Out of the Magic Portal", "That was fun, but I'm glad to be back", "https://www.redditstatic.com/gold/awards/icon/TeleportOut_512.png", 350)); + awards.add(new Award("award_f7a4fd5e-7cd1-4c11-a1c9-c18d05902e81", "GLOBAL", "Crab Rave", "[Happy crab noises]", "https://www.redditstatic.com/gold/awards/icon/CrabRave_512.png", 400)); + awards.add(new Award("award_43c43a35-15c5-4f73-91ef-fe538426435a", "GLOBAL", "Bless Up (Pro)", "Prayers up for the blessed. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/xe5mw55w5v541_BlessUp.png", 500)); + awards.add(new Award("award_27d3176c-b388-4616-80ec-11b8ece5b7ee", "GLOBAL", "Snoo Nice", "Gives the author a week of Reddit Premium and 100 Coins to do with as they please.", "https://i.redd.it/award_images/t5_22cerq/9r7hexe6pta41_SnooNice.png", 500)); + awards.add(new Award("award_35c78e6e-507b-4f1d-b3d8-ed43840909a8", "GLOBAL", "Pot o' Coins", "The treasure at the end of the rainbow. Gives the author 800 Coins to do with as they please.", "https://i.redd.it/award_images/t5_22cerq/wg3lzllyg9n41_PotoCoins.png", 1000)); + awards.add(new Award("award_5eac457f-ebac-449b-93a7-eb17b557f03c", "PREMIUM", "LOVE!", "When you follow your heart, love is the answer", "https://i.redd.it/award_images/t5_22cerq/j3azv69qjfn51_LOVE.png", 20)); + awards.add(new Award("award_abb865cf-620b-4219-8777-3658cf9091fb", "PREMIUM", "Starstruck", "Can't stop seeing stars", "https://www.redditstatic.com/gold/awards/icon/Starstruck_512.png", 20)); + awards.add(new Award("award_b4ff447e-05a5-42dc-9002-63568807cfe6", "PREMIUM", "All-Seeing Upvote", "A glowing commendation for all to see", "https://i.redd.it/award_images/t5_22cerq/rg960rc47jj41_All-SeeingUpvote.png", 30)); + awards.add(new Award("award_a2506925-fc82-4d6c-ae3b-b7217e09d7f0", "PREMIUM", "Narwhal Salute", "A golden splash of respect", "https://i.redd.it/award_images/t5_22cerq/80j20o397jj41_NarwhalSalute.png", 30)); + awards.add(new Award("award_c4b2e438-16bb-4568-88e7-7893b7662944", "PREMIUM", "Wholesome Seal of Approval", "A glittering stamp for a feel-good thing", "https://i.redd.it/award_images/t5_22cerq/b9ks3a5k7jj41_WholesomeSealofApproval.png", 30)); + awards.add(new Award("award_9663243a-e77f-44cf-abc6-850ead2cd18d", "PREMIUM", "Bravo Grande!", "For an especially amazing showing.", "https://www.redditstatic.com/gold/awards/icon/SnooClappingPremium_512.png", 75)); + awards.add(new Award("award_92cb6518-a71a-4217-9f8f-7ecbd7ab12ba", "PREMIUM", "Take My Power", "Add my power to yours.", "https://www.redditstatic.com/gold/awards/icon/TakeMyPower_512.png", 75)); + awards.add(new Award("award_5fb42699-4911-42a2-884c-6fc8bdc36059", "APPRECIATION", "Cake", "Did someone say... cake?", "https://i.redd.it/award_images/t5_22cerq/aoa99054n2s41_Cake.png", 150)); + awards.add(new Award("award_f7562045-905d-413e-9ed2-0a16d4bfe349", "APPRECIATION", "Plus One", "You officially endorse and add your voice to the crowd.", "https://i.redd.it/award_images/t5_22cerq/6vgr8y21i9741_PlusOne.png", 200)); + awards.add(new Award("award_2adc49e8-d6c9-4923-9293-2bfab1648569", "APPRECIATION", "Awesome Answer", "For a winning take and the kind soul who nails a question. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/71v56o5a5v541_AwesomeAnswer.png", 250)); + awards.add(new Award("award_cc540de7-dfdb-4a68-9acf-6f9ce6b17d21", "APPRECIATION", "It's Cute!", "You made me UwU.", "https://i.redd.it/award_images/t5_22cerq/n94bgm83in941_ItsCute.png", 250)); + awards.add(new Award("award_9583d210-a7d0-4f3c-b0c7-369ad579d3d4", "APPRECIATION", "Mind Blown", "When a thing immediately combusts your brain. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/wa987k0p4v541_MindBlown.png", 250)); + awards.add(new Award("award_d306c865-0d49-4a36-a1ab-a4122a0e3480", "APPRECIATION", "Original", "When something new and creative wows you. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/b8xt4z8yajz31_Original.png", 250)); + awards.add(new Award("award_a67d649d-5aa5-407e-a98b-32fd9e3a9696", "APPRECIATION", "Today I Learned", "The more you know... Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/bph2png4ajz31_TodayILearned.png", 250)); + awards.add(new Award("award_d48aad4b-286f-4a3a-bb41-ec05b3cd87cc", "APPRECIATION", "Yas Queen", "YAAAAAAAAAAASSS.", "https://i.redd.it/award_images/t5_22cerq/kthj3e4h3bm41_YasQueen.png", 250)); + awards.add(new Award("award_a9009ea5-1a36-42ae-aab2-5967563ee054", "APPRECIATION", "Heart Eyes", "For love at first sight. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/12kz7a7j4v541_HeartEyes.png", 500)); + awards.add(new Award("award_a7a04d6a-8dd8-41bb-b906-04fa8f144014", "APPRECIATION", "Made Me Smile", "When you're smiling before you know it. Gives 100 Coins to both the author and the community.", "https://i.redd.it/award_images/t5_22cerq/hwnbr9l67s941_MadeMeSmile.png", 500)); + return awards; + } + + public String getId() { + return id; + } + + public String getAwardSubType() { + return awardSubType; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public String getIconUrl() { + return iconUrl; + } + + public int getCoinPrice() { + return coinPrice; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/award/GiveAward.java b/app/src/main/java/ml/docilealligator/infinityforreddit/award/GiveAward.java new file mode 100644 index 00000000..a6d7724a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/award/GiveAward.java @@ -0,0 +1,134 @@ +package ml.docilealligator.infinityforreddit.award; + +import android.os.AsyncTask; +import android.text.Html; + +import androidx.annotation.NonNull; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class GiveAward { + public interface GiveAwardListener { + void success(String awardsHTML, int awardCount); + void failed(int code, String message); + } + + public static void giveAwardV2(Retrofit oauthRetrofit, String accessToken, String thingFullName, String awardId, + boolean isAnonymous, GiveAwardListener giveAwardListener) { + Map params = new HashMap<>(); + params.put(APIUtils.GILD_TYPE, awardId); + params.put(APIUtils.IS_ANONYMOUS, Boolean.toString(isAnonymous)); + params.put(APIUtils.THING_ID_KEY, thingFullName); + oauthRetrofit.create(RedditAPI.class).awardThing(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseResponseAsyncTask(response.body(), new ParseResponseAsyncTask.ParseResponseAsyncTaskListener() { + @Override + public void success(String awardsHTML, int awardCount) { + giveAwardListener.success(awardsHTML, awardCount); + } + + @Override + public void failed(String errorMessage) { + giveAwardListener.failed(response.code(), response.body()); + } + }).execute(); + } else { + giveAwardListener.failed(response.code(), response.body()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + giveAwardListener.failed(0, t.getMessage()); + } + }); + } + + private static class ParseResponseAsyncTask extends AsyncTask { + + private String response; + private boolean error = false; + private String awardsHTML; + private int awardCount; + private String errorMessage = null; + private ParseResponseAsyncTaskListener parseResponseAsyncTaskListener; + + public ParseResponseAsyncTask(String response, ParseResponseAsyncTaskListener parseResponseAsyncTaskListener) { + this.response = response; + this.parseResponseAsyncTaskListener = parseResponseAsyncTaskListener; + } + + interface ParseResponseAsyncTaskListener { + void success(String awardsHTML, int awardCount); + void failed(String errorMessage); + } + + @Override + protected Void doInBackground(Void... voids) { + try { + //Check for error + JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); + + if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + JSONArray errorArray = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) + .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); + if (errorArray.length() != 0) { + String errorString; + if (errorArray.length() >= 2) { + errorString = errorArray.getString(1); + } else { + errorString = errorArray.getString(0); + } + errorMessage = errorString.substring(0, 1).toUpperCase() + errorString.substring(1); + error = true; + return null; + } + } + } catch (JSONException ignore) {} + + try { + JSONArray awardingsArray = new JSONObject(response).getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); + StringBuilder awardingsBuilder = new StringBuilder(); + awardCount = 0; + for (int i = 0; i < awardingsArray.length(); i++) { + JSONObject award = awardingsArray.getJSONObject(i); + int count = award.getInt(JSONUtils.COUNT_KEY); + awardCount += count; + String iconUrl = award.getString(JSONUtils.ICON_URL_KEY); + awardingsBuilder.append(" ").append("x").append(count).append(" "); + } + + awardsHTML = awardingsBuilder.toString(); + } catch (JSONException e) { + e.printStackTrace(); + error = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (error) { + parseResponseAsyncTaskListener.failed(errorMessage); + } else { + parseResponseAsyncTaskListener.success(awardsHTML, awardCount); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CommentMoreBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CommentMoreBottomSheetFragment.java new file mode 100644 index 00000000..5f9b4aa6 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CommentMoreBottomSheetFragment.java @@ -0,0 +1,197 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.FullMarkdownActivity; +import ml.docilealligator.infinityforreddit.activities.EditCommentActivity; +import ml.docilealligator.infinityforreddit.activities.GiveAwardActivity; +import ml.docilealligator.infinityforreddit.activities.ReportActivity; +import ml.docilealligator.infinityforreddit.activities.ViewPostDetailActivity; +import ml.docilealligator.infinityforreddit.activities.ViewUserDetailActivity; +import ml.docilealligator.infinityforreddit.comment.Comment; +import ml.docilealligator.infinityforreddit.R; + + +/** + * A simple {@link Fragment} subclass. + */ +public class CommentMoreBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_COMMENT = "ECF"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_EDIT_AND_DELETE_AVAILABLE = "EEADA"; + public static final String EXTRA_POSITION = "EP"; + public static final String EXTRA_COMMENT_MARKDOWN = "ECM"; + public static final String EXTRA_IS_NSFW = "EIN"; + @BindView(R.id.edit_text_view_comment_more_bottom_sheet_fragment) + TextView editTextView; + @BindView(R.id.delete_text_view_comment_more_bottom_sheet_fragment) + TextView deleteTextView; + @BindView(R.id.save_text_view_comment_more_bottom_sheet_fragment) + TextView shareTextView; + @BindView(R.id.copy_text_view_comment_more_bottom_sheet_fragment) + TextView copyTextView; + @BindView(R.id.give_award_text_view_comment_more_bottom_sheet_fragment) + TextView giveAwardTextView; + @BindView(R.id.view_full_markdown_text_view_comment_more_bottom_sheet_fragment) + TextView viewFullMarkdownTextView; + @BindView(R.id.report_view_comment_more_bottom_sheet_fragment) + TextView reportTextView; + @BindView(R.id.see_removed_view_comment_more_bottom_sheet_fragment) + TextView seeRemovedTextView; + private AppCompatActivity activity; + + public CommentMoreBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_comment_more_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + Bundle bundle = getArguments(); + if (bundle == null) { + dismiss(); + return rootView; + } + Comment comment = bundle.getParcelable(EXTRA_COMMENT); + if (comment == null) { + dismiss(); + return rootView; + } + String accessToken = bundle.getString(EXTRA_ACCESS_TOKEN); + boolean editAndDeleteAvailable = bundle.getBoolean(EXTRA_EDIT_AND_DELETE_AVAILABLE, false); + + if (accessToken != null && !accessToken.equals("")) { + giveAwardTextView.setVisibility(View.VISIBLE); + giveAwardTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, GiveAwardActivity.class); + intent.putExtra(GiveAwardActivity.EXTRA_THING_FULLNAME, comment.getFullName()); + intent.putExtra(GiveAwardActivity.EXTRA_ITEM_POSITION, bundle.getInt(EXTRA_POSITION)); + if (activity instanceof ViewPostDetailActivity) { + activity.startActivityForResult(intent, ViewPostDetailActivity.GIVE_AWARD_REQUEST_CODE); + } else if (activity instanceof ViewUserDetailActivity) { + activity.startActivityForResult(intent, ViewUserDetailActivity.GIVE_AWARD_REQUEST_CODE); + } + dismiss(); + }); + + if (editAndDeleteAvailable) { + editTextView.setVisibility(View.VISIBLE); + deleteTextView.setVisibility(View.VISIBLE); + + editTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, EditCommentActivity.class); + intent.putExtra(EditCommentActivity.EXTRA_ACCESS_TOKEN, accessToken); + intent.putExtra(EditCommentActivity.EXTRA_FULLNAME, comment.getFullName()); + intent.putExtra(EditCommentActivity.EXTRA_CONTENT, comment.getCommentMarkdown()); + intent.putExtra(EditCommentActivity.EXTRA_POSITION, bundle.getInt(EXTRA_POSITION)); + if (activity instanceof ViewPostDetailActivity) { + activity.startActivityForResult(intent, ViewPostDetailActivity.EDIT_COMMENT_REQUEST_CODE); + } else { + activity.startActivityForResult(intent, ViewUserDetailActivity.EDIT_COMMENT_REQUEST_CODE); + } + + dismiss(); + }); + + deleteTextView.setOnClickListener(view -> { + dismiss(); + if (activity instanceof ViewPostDetailActivity) { + ((ViewPostDetailActivity) activity).deleteComment(comment.getFullName(), bundle.getInt(EXTRA_POSITION)); + } else if (activity instanceof ViewUserDetailActivity) { + ((ViewUserDetailActivity) activity).deleteComment(comment.getFullName()); + } + }); + } + } + + shareTextView.setOnClickListener(view -> { + dismiss(); + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, comment.getPermalink()); + activity.startActivity(Intent.createChooser(intent, getString(R.string.share))); + } catch (ActivityNotFoundException e) { + Toast.makeText(activity, R.string.no_activity_found_for_share, Toast.LENGTH_SHORT).show(); + } + }); + + copyTextView.setOnClickListener(view -> { + dismiss(); + CopyTextBottomSheetFragment copyTextBottomSheetFragment = new CopyTextBottomSheetFragment(); + Bundle copyBundle = new Bundle(); + copyBundle.putString(CopyTextBottomSheetFragment.EXTRA_MARKDOWN, comment.getCommentMarkdown()); + copyBundle.putString(CopyTextBottomSheetFragment.EXTRA_RAW_TEXT, comment.getCommentRawText()); + copyTextBottomSheetFragment.setArguments(copyBundle); + copyTextBottomSheetFragment.show(activity.getSupportFragmentManager(), copyTextBottomSheetFragment.getTag()); + }); + + viewFullMarkdownTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, FullMarkdownActivity.class); + intent.putExtra(FullMarkdownActivity.EXTRA_IS_NSFW, bundle.getBoolean(EXTRA_IS_NSFW, false)); + intent.putExtra(FullMarkdownActivity.EXTRA_COMMENT_MARKDOWN, bundle.getString(EXTRA_COMMENT_MARKDOWN, "")); + activity.startActivity(intent); + + dismiss(); + }); + + reportTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, ReportActivity.class); + intent.putExtra(ReportActivity.EXTRA_SUBREDDIT_NAME, comment.getSubredditName()); + intent.putExtra(ReportActivity.EXTRA_THING_FULLNAME, comment.getFullName()); + activity.startActivity(intent); + + dismiss(); + }); + + if ("[deleted]".equals(comment.getAuthor()) || + "[deleted]".equals(comment.getCommentRawText()) || + "[removed]".equals(comment.getCommentRawText()) + ) { + seeRemovedTextView.setVisibility(View.VISIBLE); + + seeRemovedTextView.setOnClickListener(view -> { + dismiss(); + if (activity instanceof ViewPostDetailActivity) { + ((ViewPostDetailActivity) activity).showRemovedComment(comment, bundle.getInt(EXTRA_POSITION)); + } + }); + } + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (AppCompatActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java new file mode 100644 index 00000000..c96658c8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CopyTextBottomSheetFragment.java @@ -0,0 +1,115 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class CopyTextBottomSheetFragment extends RoundedBottomSheetDialogFragment { + public static final String EXTRA_RAW_TEXT = "ERT"; + public static final String EXTRA_MARKDOWN = "EM"; + + @BindView(R.id.copy_raw_text_text_view_copy_text_bottom_sheet_fragment) + TextView copyRawTextTextView; + @BindView(R.id.copy_markdown_text_view_copy_text_bottom_sheet_fragment) + TextView copyMarkdownTextView; + @BindView(R.id.copy_all_raw_text_text_view_copy_text_bottom_sheet_fragment) + TextView copyAllRawTextTextView; + @BindView(R.id.copy_all_markdown_text_view_copy_text_bottom_sheet_fragment) + TextView copyAllMarkdownTextView; + + private Activity activity; + + public CopyTextBottomSheetFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_copy_text_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + String rawText = getArguments().getString(EXTRA_RAW_TEXT); + String markdownText = getArguments().getString(EXTRA_MARKDOWN); + + copyRawTextTextView.setOnClickListener(view -> { + showCopyDialog(rawText); + dismiss(); + }); + + copyAllRawTextTextView.setOnClickListener(view -> { + copyText(rawText); + dismiss(); + }); + + if (markdownText != null) { + copyMarkdownTextView.setOnClickListener(view -> { + showCopyDialog(markdownText); + dismiss(); + }); + + copyAllMarkdownTextView.setOnClickListener(view -> { + copyText(markdownText); + dismiss(); + }); + } else { + copyMarkdownTextView.setVisibility(View.GONE); + copyAllMarkdownTextView.setVisibility(View.GONE); + } + + return rootView; + } + + private void showCopyDialog(String text) { + LayoutInflater inflater = activity.getLayoutInflater(); + View layout = inflater.inflate(R.layout.copy_text_material_dialog, null); + TextView textView = layout.findViewById(R.id.text_view_copy_text_material_dialog); + textView.setText(text); + new MaterialAlertDialogBuilder(activity, R.style.CopyTextMaterialAlertDialogTheme) + .setTitle(R.string.copy_text) + .setView(layout) + .setPositiveButton(R.string.copy_all, (dialogInterface, i) -> copyText(text)) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + private void copyText(String text) { + ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + ClipData clip = ClipData.newPlainText("simple text", text); + clipboard.setPrimaryClip(clip); + Toast.makeText(activity, R.string.copy_success, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(activity, R.string.copy_link_failed, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CreateThemeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CreateThemeBottomSheetFragment.java new file mode 100644 index 00000000..163c7732 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CreateThemeBottomSheetFragment.java @@ -0,0 +1,90 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.CustomizeThemeActivity; +import ml.docilealligator.infinityforreddit.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class CreateThemeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + @BindView(R.id.import_theme_text_view_create_theme_bottom_sheet_fragment) + TextView importTextView; + @BindView(R.id.light_theme_text_view_create_theme_bottom_sheet_fragment) + TextView lightThemeTextView; + @BindView(R.id.dark_theme_text_view_create_theme_bottom_sheet_fragment) + TextView darkThemeTextView; + @BindView(R.id.amoled_theme_text_view_create_theme_bottom_sheet_fragment) + TextView amoledThemeTextView; + private Activity activity; + + public interface SelectBaseThemeBottomSheetFragmentListener { + void importTheme(); + } + + public CreateThemeBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_create_theme_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + importTextView.setOnClickListener(view -> { + ((SelectBaseThemeBottomSheetFragmentListener) activity).importTheme(); + dismiss(); + }); + + lightThemeTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); + intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, getString(R.string.theme_name_indigo)); + startActivity(intent); + dismiss(); + }); + + darkThemeTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); + intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, getString(R.string.theme_name_indigo_dark)); + startActivity(intent); + dismiss(); + }); + + amoledThemeTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_CREATE_THEME, true); + intent.putExtra(CustomizeThemeActivity.EXTRA_IS_PREDEFIINED_THEME, true); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, getString(R.string.theme_name_indigo_amoled)); + startActivity(intent); + dismiss(); + }); + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CustomThemeOptionsBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CustomThemeOptionsBottomSheetFragment.java new file mode 100644 index 00000000..45d08549 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/CustomThemeOptionsBottomSheetFragment.java @@ -0,0 +1,91 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +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.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.CustomizeThemeActivity; +import ml.docilealligator.infinityforreddit.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class CustomThemeOptionsBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_THEME_NAME = "ETN"; + @BindView(R.id.theme_name_text_view_custom_theme_options_bottom_sheet_fragment) + TextView themeNameTextView; + @BindView(R.id.edit_theme_text_view_custom_theme_options_bottom_sheet_fragment) + TextView editThemeTextView; + @BindView(R.id.share_theme_text_view_custom_theme_options_bottom_sheet_fragment) + TextView shareThemeTextView; + @BindView(R.id.change_theme_name_text_view_custom_theme_options_bottom_sheet_fragment) + TextView changeThemeNameTextView; + @BindView(R.id.delete_theme_text_view_custom_theme_options_bottom_sheet_fragment) + TextView deleteTextView; + private String themeName; + private Activity activity; + + public CustomThemeOptionsBottomSheetFragment() { + // Required empty public constructor + } + + public interface CustomThemeOptionsBottomSheetFragmentListener { + void changeName(String oldThemeName); + void shareTheme(String themeName); + void delete(String themeName); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_custom_theme_options_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + themeName = getArguments().getString(EXTRA_THEME_NAME); + themeNameTextView.setText(themeName); + + editThemeTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_NAME, themeName); + startActivity(intent); + dismiss(); + }); + + shareThemeTextView.setOnClickListener(view -> { + ((CustomThemeOptionsBottomSheetFragmentListener) activity).shareTheme(themeName); + dismiss(); + }); + + changeThemeNameTextView.setOnClickListener(view -> { + ((CustomThemeOptionsBottomSheetFragmentListener) activity).changeName(themeName); + dismiss(); + }); + + deleteTextView.setOnClickListener(view -> { + ((CustomThemeOptionsBottomSheetFragmentListener) activity).delete(themeName); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (AppCompatActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FABMoreOptionsBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FABMoreOptionsBottomSheetFragment.java new file mode 100644 index 00000000..a0061ff8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FABMoreOptionsBottomSheetFragment.java @@ -0,0 +1,111 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; + +public class FABMoreOptionsBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final int FAB_OPTION_SUBMIT_POST = 0; + public static final int FAB_OPTION_REFRESH = 1; + public static final int FAB_OPTION_CHANGE_SORT_TYPE = 2; + public static final int FAB_OPTION_CHANGE_POST_LAYOUT = 3; + public static final int FAB_OPTION_SEARCH = 4; + public static final int FAB_OPTION_GO_TO_SUBREDDIT = 5; + public static final int FAB_OPTION_GO_TO_USER = 6; + public static final int FAB_RANDOM = 7; + + @BindView(R.id.submit_post_text_view_fab_more_options_bottom_sheet_fragment) + TextView submitPostTextView; + @BindView(R.id.refresh_text_view_fab_more_options_bottom_sheet_fragment) + TextView refreshTextView; + @BindView(R.id.change_sort_type_text_view_fab_more_options_bottom_sheet_fragment) + TextView changeSortTypeTextView; + @BindView(R.id.change_post_layout_text_view_fab_more_options_bottom_sheet_fragment) + TextView changePostLayoutTextView; + @BindView(R.id.search_text_view_fab_more_options_bottom_sheet_fragment) + TextView searchTextView; + @BindView(R.id.go_to_subreddit_text_view_fab_more_options_bottom_sheet_fragment) + TextView goToSubredditTextView; + @BindView(R.id.go_to_user_text_view_fab_more_options_bottom_sheet_fragment) + TextView goToUserTextView; + @BindView(R.id.random_text_view_fab_more_options_bottom_sheet_fragment) + TextView randomTextView; + private FABOptionSelectionCallback activity; + + public FABMoreOptionsBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_fab_more_options_bottom_sheet, container, false); + + ButterKnife.bind(this, rootView); + + submitPostTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_OPTION_SUBMIT_POST); + dismiss(); + }); + + refreshTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_OPTION_REFRESH); + dismiss(); + }); + + changeSortTypeTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_OPTION_CHANGE_SORT_TYPE); + dismiss(); + }); + + changePostLayoutTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_OPTION_CHANGE_POST_LAYOUT); + dismiss(); + }); + + searchTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_OPTION_SEARCH); + dismiss(); + }); + + goToSubredditTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_OPTION_GO_TO_SUBREDDIT); + dismiss(); + }); + + goToUserTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_OPTION_GO_TO_USER); + dismiss(); + }); + + randomTextView.setOnClickListener(view -> { + activity.fabOptionSelected(FAB_RANDOM); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (FABOptionSelectionCallback) context; + } + + public interface FABOptionSelectionCallback { + void fabOptionSelected(int option); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java new file mode 100644 index 00000000..b67a04c9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/FlairBottomSheetFragment.java @@ -0,0 +1,125 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.bottomsheet.BottomSheetDialogFragment; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.FlairBottomSheetRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FetchFlairs; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import retrofit2.Retrofit; + + +/** + * A simple {@link Fragment} subclass. + */ +public class FlairBottomSheetFragment extends BottomSheetDialogFragment { + + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + @BindView(R.id.progress_bar_flair_bottom_sheet_fragment) + ProgressBar progressBar; + @BindView(R.id.error_text_view_flair_bottom_sheet_fragment) + TextView errorTextView; + @BindView(R.id.recycler_view_bottom_sheet_fragment) + RecyclerView recyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String mAccessToken; + private String mSubredditName; + private Activity mActivity; + private FlairBottomSheetRecyclerViewAdapter mAdapter; + + public FlairBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_flair_bottom_sheet, container, false); + + ButterKnife.bind(this, rootView); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + mAdapter = new FlairBottomSheetRecyclerViewAdapter(mActivity, mCustomThemeWrapper, flair -> { + ((FlairSelectionCallback) mActivity).flairSelected(flair); + dismiss(); + }); + + recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); + recyclerView.setAdapter(mAdapter); + + mAccessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + mSubredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); + + fetchFlairs(); + + return rootView; + } + + private void fetchFlairs() { + FetchFlairs.fetchFlairsInSubreddit(mOauthRetrofit, mAccessToken, + mSubredditName, new FetchFlairs.FetchFlairsInSubredditListener() { + @Override + public void fetchSuccessful(ArrayList flairs) { + progressBar.setVisibility(View.GONE); + if (flairs == null || flairs.size() == 0) { + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.no_flair); + } else { + errorTextView.setVisibility(View.GONE); + mAdapter.changeDataset(flairs); + } + } + + @Override + public void fetchFailed() { + progressBar.setVisibility(View.GONE); + errorTextView.setVisibility(View.VISIBLE); + errorTextView.setText(R.string.error_loading_flairs); + errorTextView.setOnClickListener(view -> fetchFlairs()); + } + }); + } + + public interface FlairSelectionCallback { + void flairSelected(Flair flair); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/MultiRedditOptionsBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/MultiRedditOptionsBottomSheetFragment.java new file mode 100644 index 00000000..e5e20f8b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/MultiRedditOptionsBottomSheetFragment.java @@ -0,0 +1,72 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.EditMultiRedditActivity; +import ml.docilealligator.infinityforreddit.activities.SubscribedThingListingActivity; +import ml.docilealligator.infinityforreddit.multireddit.MultiReddit; +import ml.docilealligator.infinityforreddit.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class MultiRedditOptionsBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_MULTI_REDDIT = "EMR"; + + @BindView(R.id.edit_multi_reddit_text_view_multi_reddit_options_bottom_sheet_fragment) + TextView editMultiRedditTextView; + @BindView(R.id.delete_multi_reddit_text_view_multi_reddit_options_bottom_sheet_fragment) + TextView deleteMultiRedditTextView; + private SubscribedThingListingActivity subscribedThingListingActivity; + + public MultiRedditOptionsBottomSheetFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_multi_reddit_options_bottom_sheet, container, false); + + ButterKnife.bind(this, rootView); + + MultiReddit multiReddit = getArguments().getParcelable(EXTRA_MULTI_REDDIT); + + editMultiRedditTextView.setOnClickListener(view -> { + if (multiReddit != null) { + Intent editIntent = new Intent(subscribedThingListingActivity, EditMultiRedditActivity.class); + editIntent.putExtra(EditMultiRedditActivity.EXTRA_MULTI_PATH, multiReddit.getPath()); + startActivity(editIntent); + } + dismiss(); + }); + + deleteMultiRedditTextView.setOnClickListener(view -> { + subscribedThingListingActivity.deleteMultiReddit(multiReddit); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + subscribedThingListingActivity = (SubscribedThingListingActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostCommentSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostCommentSortTypeBottomSheetFragment.java new file mode 100644 index 00000000..575ceeb8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostCommentSortTypeBottomSheetFragment.java @@ -0,0 +1,119 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; + +/** + * A simple {@link Fragment} subclass. + */ +public class PostCommentSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + @BindView(R.id.best_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView bestTypeTextView; + @BindView(R.id.confidence_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView confidenceTypeTextView; + @BindView(R.id.top_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView topTypeTextView; + @BindView(R.id.new_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView newTypeTextView; + @BindView(R.id.controversial_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView controversialTypeTextView; + @BindView(R.id.old_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView oldTypeTextView; + @BindView(R.id.random_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView randomTypeTextView; + @BindView(R.id.qa_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView qaTypeTextView; + @BindView(R.id.live_type_text_view_post_comment_sort_type_bottom_sheet_fragment) + TextView liveTypeTextView; + private Activity activity; + public PostCommentSortTypeBottomSheetFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_post_comment_sort_type_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + bestTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.BEST)); + dismiss(); + }); + + confidenceTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.CONFIDENCE)); + dismiss(); + }); + + topTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.TOP)); + dismiss(); + }); + + newTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); + dismiss(); + }); + + controversialTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.CONTROVERSIAL)); + dismiss(); + }); + + oldTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.OLD)); + dismiss(); + }); + + randomTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.RANDOM)); + dismiss(); + }); + + qaTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.QA)); + dismiss(); + }); + + liveTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.LIVE)); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostLayoutBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostLayoutBottomSheetFragment.java new file mode 100644 index 00000000..13e5c324 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostLayoutBottomSheetFragment.java @@ -0,0 +1,65 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +/** + * A simple {@link Fragment} subclass. + */ +public class PostLayoutBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + @BindView(R.id.card_layout_text_view_post_layout_bottom_sheet_fragment) + TextView cardLayoutTextView; + @BindView(R.id.compact_layout_text_view_post_layout_bottom_sheet_fragment) + TextView compactLayoutTextView; + private Activity activity; + public PostLayoutBottomSheetFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_post_layot_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + cardLayoutTextView.setOnClickListener(view -> { + ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_CARD); + dismiss(); + }); + compactLayoutTextView.setOnClickListener(view -> { + ((PostLayoutSelectionCallback) activity).postLayoutSelected(SharedPreferencesUtils.POST_LAYOUT_COMPACT); + dismiss(); + }); + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } + + public interface PostLayoutSelectionCallback { + void postLayoutSelected(int postLayout); + } + +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java new file mode 100644 index 00000000..64b604ab --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java @@ -0,0 +1,91 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; + + +/** + * A simple {@link Fragment} subclass. + */ +public class PostTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final int TYPE_TEXT = 0; + public static final int TYPE_LINK = 1; + public static final int TYPE_IMAGE = 2; + public static final int TYPE_VIDEO = 3; + @BindView(R.id.text_type_linear_layout_post_type_bottom_sheet_fragment) + TextView textTypeTextView; + @BindView(R.id.link_type_linear_layout_post_type_bottom_sheet_fragment) + TextView linkTypeTextView; + @BindView(R.id.image_type_linear_layout_post_type_bottom_sheet_fragment) + TextView imageTypeTextView; + @BindView(R.id.video_type_linear_layout_post_type_bottom_sheet_fragment) + TextView videoTypeTextView; + private Activity activity; + + public PostTypeBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_post_type_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + textTypeTextView.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_TEXT); + dismiss(); + }); + + linkTypeTextView.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_LINK); + dismiss(); + }); + + imageTypeTextView.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_IMAGE); + dismiss(); + }); + + videoTypeTextView.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_VIDEO); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } + + public interface PostTypeSelectionCallback { + void postTypeSelected(int postType); + } + +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/RandomBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/RandomBottomSheetFragment.java new file mode 100644 index 00000000..fb10efed --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/RandomBottomSheetFragment.java @@ -0,0 +1,88 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; + +public class RandomBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_IS_NSFW = "EIN"; + public static final int RANDOM_SUBREDDIT = 0; + public static final int RANDOM_POST = 1; + public static final int RANDOM_NSFW_SUBREDDIT = 2; + public static final int RANDOM_NSFW_POST = 3; + + @BindView(R.id.random_subreddit_text_view_random_bottom_sheet_fragment) + TextView randomSubredditTextView; + @BindView(R.id.random_post_text_view_random_bottom_sheet_fragment) + TextView randomPostTextView; + @BindView(R.id.random_nsfw_subreddit_text_view_random_bottom_sheet_fragment) + TextView randomNSFWSubredditTextView; + @BindView(R.id.random_nsfw_post_text_view_random_bottom_sheet_fragment) + TextView randomNSFWPostTextView; + + private RandomOptionSelectionCallback activity; + + public RandomBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_random_bottom_sheet, container, false); + + ButterKnife.bind(this, rootView); + + boolean isNSFW = getArguments().getBoolean(EXTRA_IS_NSFW, false); + + if (!isNSFW) { + randomNSFWSubredditTextView.setVisibility(View.GONE); + randomNSFWPostTextView.setVisibility(View.GONE); + } else { + randomNSFWSubredditTextView.setOnClickListener(view -> { + activity.randomOptionSelected(RANDOM_NSFW_SUBREDDIT); + dismiss(); + }); + + randomNSFWPostTextView.setOnClickListener(view -> { + activity.randomOptionSelected(RANDOM_NSFW_POST); + dismiss(); + }); + } + + randomSubredditTextView.setOnClickListener(view -> { + activity.randomOptionSelected(RANDOM_SUBREDDIT); + dismiss(); + }); + + randomPostTextView.setOnClickListener(view -> { + activity.randomOptionSelected(RANDOM_POST); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (RandomOptionSelectionCallback) context; + } + + public interface RandomOptionSelectionCallback { + void randomOptionSelected(int option); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchPostSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchPostSortTypeBottomSheetFragment.java new file mode 100644 index 00000000..98fe7801 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchPostSortTypeBottomSheetFragment.java @@ -0,0 +1,90 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; + + +/** + * A simple {@link Fragment} subclass. + */ +public class SearchPostSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + @BindView(R.id.relevance_type_text_view_search_sort_type_bottom_sheet_fragment) + TextView relevanceTypeTextView; + @BindView(R.id.hot_type_text_view_search_sort_type_bottom_sheet_fragment) + TextView hotTypeTextView; + @BindView(R.id.top_type_text_view_search_sort_type_bottom_sheet_fragment) + TextView topTypeTextView; + @BindView(R.id.new_type_text_view_search_sort_type_bottom_sheet_fragment) + TextView newTypeTextView; + @BindView(R.id.comments_type_text_view_search_sort_type_bottom_sheet_fragment) + TextView commentsTypeTextView; + private Activity activity; + public SearchPostSortTypeBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_search_post_sort_type_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + relevanceTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.RELEVANCE.name()); + dismiss(); + }); + + hotTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.HOT.name()); + dismiss(); + }); + + topTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.TOP.name()); + dismiss(); + }); + + newTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); + dismiss(); + }); + + commentsTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.COMMENTS.name()); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchUserAndSubredditSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchUserAndSubredditSortTypeBottomSheetFragment.java new file mode 100644 index 00000000..2c04b848 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SearchUserAndSubredditSortTypeBottomSheetFragment.java @@ -0,0 +1,76 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; + + +/** + * A simple {@link Fragment} subclass. + */ +public class SearchUserAndSubredditSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_FRAGMENT_POSITION = "EFP"; + @BindView(R.id.relevance_type_text_view_search_user_and_subreddit_sort_type_bottom_sheet_fragment) + TextView relevanceTypeTextView; + @BindView(R.id.activity_type_text_view_search_user_and_subreddit_sort_type_bottom_sheet_fragment) + TextView activityTypeTextView; + private Activity activity; + public SearchUserAndSubredditSortTypeBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_search_user_and_subreddit_sort_type_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + int position = getArguments() != null ? getArguments().getInt(EXTRA_FRAGMENT_POSITION) : -1; + if(position < 0) { + dismiss(); + return rootView; + } + + relevanceTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).searchUserAndSubredditSortTypeSelected(new SortType(SortType.Type.RELEVANCE), position); + dismiss(); + }); + + activityTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).searchUserAndSubredditSortTypeSelected(new SortType(SortType.Type.ACTIVITY), position); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SetAsWallpaperBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SetAsWallpaperBottomSheetFragment.java new file mode 100644 index 00000000..05d31cf3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SetAsWallpaperBottomSheetFragment.java @@ -0,0 +1,79 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; + +public class SetAsWallpaperBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_VIEW_PAGER_POSITION = "EVPP"; + + @BindView(R.id.home_screen_text_view_set_as_wallpaper_bottom_sheet_fragment) + TextView homeScreenTextvView; + @BindView(R.id.lock_screen_text_view_set_as_wallpaper_bottom_sheet_fragment) + TextView lockScreenTextView; + @BindView(R.id.both_text_view_set_as_wallpaper_bottom_sheet_fragment) + TextView bothTextView; + private Activity mActivity; + + public SetAsWallpaperBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_set_as_wallpaper_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + Bundle bundle = getArguments(); + int viewPagerPosition = bundle == null ? -1 : bundle.getInt(EXTRA_VIEW_PAGER_POSITION); + + bothTextView.setOnClickListener(view -> { + if (mActivity instanceof SetAsWallpaperCallback) { + ((SetAsWallpaperCallback) mActivity).setToBoth(viewPagerPosition); + } + dismiss(); + }); + + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + homeScreenTextvView.setVisibility(View.VISIBLE); + lockScreenTextView.setVisibility(View.VISIBLE); + + homeScreenTextvView.setOnClickListener(view -> { + if (mActivity instanceof SetAsWallpaperCallback) { + ((SetAsWallpaperCallback) mActivity).setToHomeScreen(viewPagerPosition); + } + dismiss(); + }); + + lockScreenTextView.setOnClickListener(view -> { + if (mActivity instanceof SetAsWallpaperCallback) { + ((SetAsWallpaperCallback) mActivity).setToLockScreen(viewPagerPosition); + } + dismiss(); + }); + } + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.mActivity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/ShareLinkBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/ShareLinkBottomSheetFragment.java new file mode 100644 index 00000000..bf2f1cc9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/ShareLinkBottomSheetFragment.java @@ -0,0 +1,142 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class ShareLinkBottomSheetFragment extends RoundedBottomSheetDialogFragment { + public static final String EXTRA_POST_LINK = "EPL"; + public static final String EXTRA_MEDIA_LINK = "EML"; + public static final String EXTRA_MEDIA_TYPE = "EMT"; + + @BindView(R.id.share_post_link_text_view_share_link_bottom_sheet_fragment) + TextView sharePostLinkTextView; + @BindView(R.id.share_media_link_text_view_share_link_bottom_sheet_fragment) + TextView shareMediaLinkTextView; + @BindView(R.id.copy_post_link_text_view_share_link_bottom_sheet_fragment) + TextView copyPostLinkTextView; + @BindView(R.id.copy_media_link_text_view_share_link_bottom_sheet_fragment) + TextView copyMediaLinkTextView; + + private Activity activity; + + public ShareLinkBottomSheetFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_share_link_bottom_sheet, container, false); + + ButterKnife.bind(this, rootView); + + String postLink = getArguments().getString(EXTRA_POST_LINK); + String mediaLink = getArguments().containsKey(EXTRA_MEDIA_LINK) ? getArguments().getString(EXTRA_MEDIA_LINK) : null; + + if (mediaLink != null) { + shareMediaLinkTextView.setVisibility(View.VISIBLE); + copyMediaLinkTextView.setVisibility(View.VISIBLE); + + int mediaType = getArguments().getInt(EXTRA_MEDIA_TYPE); + switch (mediaType) { + case Post.IMAGE_TYPE: + shareMediaLinkTextView.setText(R.string.share_image_link); + copyMediaLinkTextView.setText(R.string.copy_image_link); + shareMediaLinkTextView.setCompoundDrawablesWithIntrinsicBounds( + activity.getDrawable(R.drawable.ic_image_24dp), null, null, null); + break; + case Post.GIF_TYPE: + shareMediaLinkTextView.setText(R.string.share_gif_link); + copyMediaLinkTextView.setText(R.string.copy_gif_link); + shareMediaLinkTextView.setCompoundDrawablesWithIntrinsicBounds( + activity.getDrawable(R.drawable.ic_image_24dp), null, null, null); + break; + case Post.VIDEO_TYPE: + shareMediaLinkTextView.setText(R.string.share_video_link); + copyMediaLinkTextView.setText(R.string.copy_video_link); + shareMediaLinkTextView.setCompoundDrawablesWithIntrinsicBounds( + activity.getDrawable(R.drawable.ic_outline_video_24dp), null, null, null); + break; + case Post.LINK_TYPE: + case Post.NO_PREVIEW_LINK_TYPE: + shareMediaLinkTextView.setText(R.string.share_link); + copyMediaLinkTextView.setText(R.string.copy_link); + break; + } + + shareMediaLinkTextView.setOnClickListener(view -> { + shareLink(mediaLink); + dismiss(); + }); + copyMediaLinkTextView.setOnClickListener(view -> { + copyLink(mediaLink); + dismiss(); + }); + } + + sharePostLinkTextView.setOnClickListener(view -> { + shareLink(postLink); + dismiss(); + }); + copyPostLinkTextView.setOnClickListener(view -> { + copyLink(postLink); + dismiss(); + }); + return rootView; + } + + private void shareLink(String link) { + try { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, link); + activity.startActivity(Intent.createChooser(intent, getString(R.string.share))); + } catch (ActivityNotFoundException e) { + Toast.makeText(activity, R.string.no_activity_found_for_share, Toast.LENGTH_SHORT).show(); + } + } + + private void copyLink(String link) { + ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + ClipData clip = ClipData.newPlainText("simple text", link); + clipboard.setPrimaryClip(clip); + Toast.makeText(activity, R.string.copy_success, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(activity, R.string.copy_link_failed, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (AppCompatActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTimeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTimeBottomSheetFragment.java new file mode 100644 index 00000000..65f5c172 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTimeBottomSheetFragment.java @@ -0,0 +1,112 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; + +/** + * A simple {@link Fragment} subclass. + */ +public class SortTimeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_SORT_TYPE = "EST"; + + @BindView(R.id.hour_text_view_sort_time_bottom_sheet_fragment) + TextView hourTextView; + @BindView(R.id.day_text_view_sort_time_bottom_sheet_fragment) + TextView dayTextView; + @BindView(R.id.week_text_view_sort_time_bottom_sheet_fragment) + TextView weekTextView; + @BindView(R.id.month_text_view_sort_time_bottom_sheet_fragment) + TextView monthTextView; + @BindView(R.id.year_text_view_sort_time_bottom_sheet_fragment) + TextView yearTextView; + @BindView(R.id.all_time_text_view_sort_time_bottom_sheet_fragment) + TextView allTimeTextView; + private Activity activity; + public SortTimeBottomSheetFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_sort_time_bottom_sheet, container, false); + + ButterKnife.bind(this, rootView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + String sortType = getArguments() != null ? getArguments().getString(EXTRA_SORT_TYPE) : null; + if(sortType == null) { + dismiss(); + return rootView; + } + + hourTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity) + .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.HOUR)); + dismiss(); + }); + + dayTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity) + .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.DAY)); + dismiss(); + }); + + weekTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity) + .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.WEEK)); + dismiss(); + }); + + monthTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity) + .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.MONTH)); + dismiss(); + }); + + yearTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity) + .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.YEAR)); + dismiss(); + }); + + allTimeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity) + .sortTypeSelected(new SortType(SortType.Type.valueOf(sortType), SortType.Time.ALL)); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTypeBottomSheetFragment.java new file mode 100644 index 00000000..40549cd1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/SortTypeBottomSheetFragment.java @@ -0,0 +1,102 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; + + +/** + * A simple {@link Fragment} subclass. + */ +public class SortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_NO_BEST_TYPE = "ENBT"; + @BindView(R.id.best_type_text_view_sort_type_bottom_sheet_fragment) + TextView bestTypeTextView; + @BindView(R.id.hot_type_text_view_sort_type_bottom_sheet_fragment) + TextView hotTypeTextView; + @BindView(R.id.new_type_text_view_sort_type_bottom_sheet_fragment) + TextView newTypeTextView; + @BindView(R.id.rising_type_text_view_sort_type_bottom_sheet_fragment) + TextView risingTypeTextView; + @BindView(R.id.top_type_text_view_sort_type_bottom_sheet_fragment) + TextView topTypeTextView; + @BindView(R.id.controversial_type_text_view_sort_type_bottom_sheet_fragment) + TextView controversialTypeTextView; + private Activity activity; + public SortTypeBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_sort_type_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + if (getArguments() == null || getArguments().getBoolean(EXTRA_NO_BEST_TYPE)) { + bestTypeTextView.setVisibility(View.GONE); + } else { + bestTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.BEST)); + dismiss(); + }); + } + + hotTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.HOT)); + dismiss(); + }); + + newTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); + dismiss(); + }); + + risingTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.RISING)); + dismiss(); + }); + + topTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.TOP.name()); + dismiss(); + }); + + controversialTypeTextView.setOnClickListener(view -> { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.CONTROVERSIAL.name()); + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java new file mode 100644 index 00000000..6ce44743 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UrlMenuBottomSheetFragment.java @@ -0,0 +1,87 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + +import android.app.Activity; +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.R; + +public class UrlMenuBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + public static final String EXTRA_URL = "EU"; + @BindView(R.id.open_link_text_view_url_menu_bottom_sheet_fragment) + TextView openLinkTextView; + @BindView(R.id.copy_link_text_view_url_menu_bottom_sheet_fragment) + TextView copyLinkTextView; + @BindView(R.id.share_link_text_view_url_menu_bottom_sheet_fragment) + TextView shareLinkTextView; + private Activity activity; + + public UrlMenuBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_url_menu_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + String url = getArguments().getString(EXTRA_URL); + + openLinkTextView.setOnClickListener(view -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse(url)); + activity.startActivity(intent); + dismiss(); + }); + + copyLinkTextView.setOnClickListener(view -> { + ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); + if (clipboard != null) { + ClipData clip = ClipData.newPlainText("simple text", url); + clipboard.setPrimaryClip(clip); + Toast.makeText(activity, R.string.copy_success, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(activity, R.string.copy_link_failed, Toast.LENGTH_SHORT).show(); + } + dismiss(); + }); + + shareLinkTextView.setOnClickListener(view -> { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, url); + if (intent.resolveActivity(activity.getPackageManager()) != null) { + startActivity(intent); + } else { + Toast.makeText(activity, R.string.no_app, Toast.LENGTH_SHORT).show(); + } + dismiss(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UserThingSortTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UserThingSortTypeBottomSheetFragment.java new file mode 100644 index 00000000..31524d30 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/UserThingSortTypeBottomSheetFragment.java @@ -0,0 +1,86 @@ +package ml.docilealligator.infinityforreddit.bottomsheetfragments; + + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.SortTypeSelectionCallback; + + +/** + * A simple {@link Fragment} subclass. + */ +public class UserThingSortTypeBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + @BindView(R.id.new_type_text_view_user_thing_sort_type_bottom_sheet_fragment) + TextView newTypeTextView; + @BindView(R.id.hot_type_text_view_user_thing_sort_type_bottom_sheet_fragment) + TextView hotTypeTextView; + @BindView(R.id.top_type_text_view_user_thing_sort_type_bottom_sheet_fragment) + TextView topTypeTextView; + @BindView(R.id.controversial_type_text_view_user_thing_sort_type_bottom_sheet_fragment) + TextView controversialTypeTextView; + public UserThingSortTypeBottomSheetFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_user_thing_sort_type_bottom_sheet, container, false); + + ButterKnife.bind(this, rootView); + + Activity activity = getActivity(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + newTypeTextView.setOnClickListener(view -> { + if (activity != null) { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.NEW)); + } + dismiss(); + }); + + hotTypeTextView.setOnClickListener(view -> { + if (activity != null) { + ((SortTypeSelectionCallback) activity).sortTypeSelected(new SortType(SortType.Type.HOT)); + } + dismiss(); + }); + + topTypeTextView.setOnClickListener(view -> { + if (activity != null) { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.TOP.name()); + } + dismiss(); + }); + + controversialTypeTextView.setOnClickListener(view -> { + if (activity != null) { + ((SortTypeSelectionCallback) activity).sortTypeSelected(SortType.Type.CONTROVERSIAL.name()); + } + dismiss(); + }); + + return rootView; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/NetworkWifiStatusReceiver.java b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/NetworkWifiStatusReceiver.java new file mode 100644 index 00000000..fc7355a5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/broadcastreceivers/NetworkWifiStatusReceiver.java @@ -0,0 +1,22 @@ +package ml.docilealligator.infinityforreddit.broadcastreceivers; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class NetworkWifiStatusReceiver extends BroadcastReceiver { + private NetworkWifiStatusReceiverListener networkWifiStatusReceiverListener; + + public interface NetworkWifiStatusReceiverListener { + void networkStatusChange(); + } + + public NetworkWifiStatusReceiver(NetworkWifiStatusReceiverListener listener) { + networkWifiStatusReceiverListener = listener; + } + + @Override + public void onReceive(Context context, Intent intent) { + networkWifiStatusReceiverListener.networkStatusChange(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java new file mode 100644 index 00000000..aa915171 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/Comment.java @@ -0,0 +1,390 @@ +package ml.docilealligator.infinityforreddit.comment; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.utils.APIUtils; + +public class Comment implements Parcelable { + public static final int VOTE_TYPE_NO_VOTE = 0; + public static final int VOTE_TYPE_UPVOTE = 1; + public static final int VOTE_TYPE_DOWNVOTE = -1; + public static final Creator CREATOR = new Creator() { + @Override + public Comment createFromParcel(Parcel in) { + return new Comment(in); + } + + @Override + public Comment[] newArray(int size) { + return new Comment[size]; + } + }; + private String id; + private String fullName; + private String author; + private String authorFlair; + private String authorFlairHTML; + private String linkAuthor; + private long commentTimeMillis; + private String commentMarkdown; + private String commentRawText; + private String linkId; + private String subredditName; + private String parentId; + private int score; + private int voteType; + private boolean isSubmitter; + private String distinguished; + private String permalink; + private String awards; + private int depth; + private boolean collapsed; + private boolean hasReply; + private boolean scoreHidden; + private boolean saved; + private boolean isExpanded; + private boolean hasExpandedBefore; + private ArrayList children; + private ArrayList moreChildrenFullnames; + private int moreChildrenStartingIndex; + private boolean isPlaceHolder; + private boolean isLoadingMoreChildren; + private boolean loadMoreChildrenFailed; + + public Comment(String id, String fullName, String author, String authorFlair, + String authorFlairHTML, String linkAuthor, + long commentTimeMillis, String commentMarkdown, String commentRawText, + String linkId, String subredditName, String parentId, int score, + int voteType, boolean isSubmitter, String distinguished, String permalink, + String awards, int depth, boolean collapsed, boolean hasReply, + boolean scoreHidden, boolean saved) { + this.id = id; + this.fullName = fullName; + this.author = author; + this.authorFlair = authorFlair; + this.authorFlairHTML = authorFlairHTML; + this.linkAuthor = linkAuthor; + this.commentTimeMillis = commentTimeMillis; + this.commentMarkdown = commentMarkdown; + this.commentRawText = commentRawText; + this.linkId = linkId; + this.subredditName = subredditName; + this.parentId = parentId; + this.score = score; + this.voteType = voteType; + this.isSubmitter = isSubmitter; + this.distinguished = distinguished; + this.permalink = APIUtils.API_BASE_URI + permalink; + this.awards = awards; + this.depth = depth; + this.collapsed = collapsed; + this.hasReply = hasReply; + this.scoreHidden = scoreHidden; + this.saved = saved; + this.isExpanded = false; + this.hasExpandedBefore = false; + moreChildrenStartingIndex = 0; + isPlaceHolder = false; + } + + public Comment(String parentFullName, int depth) { + this.fullName = parentFullName; + this.depth = depth; + isPlaceHolder = true; + isLoadingMoreChildren = false; + loadMoreChildrenFailed = false; + } + + protected Comment(Parcel in) { + id = in.readString(); + fullName = in.readString(); + author = in.readString(); + authorFlair = in.readString(); + authorFlairHTML = in.readString(); + linkAuthor = in.readString(); + commentTimeMillis = in.readLong(); + commentMarkdown = in.readString(); + commentRawText = in.readString(); + linkId = in.readString(); + subredditName = in.readString(); + parentId = in.readString(); + score = in.readInt(); + voteType = in.readInt(); + isSubmitter = in.readByte() != 0; + distinguished = in.readString(); + permalink = in.readString(); + awards = in.readString(); + depth = in.readInt(); + collapsed = in.readByte() != 0; + hasReply = in.readByte() != 0; + scoreHidden = in.readByte() != 0; + isExpanded = in.readByte() != 0; + hasExpandedBefore = in.readByte() != 0; + children = in.readArrayList(Comment.class.getClassLoader()); + moreChildrenFullnames = in.readArrayList(Comment.class.getClassLoader()); + moreChildrenStartingIndex = in.readInt(); + isPlaceHolder = in.readByte() != 0; + isLoadingMoreChildren = in.readByte() != 0; + loadMoreChildrenFailed = in.readByte() != 0; + } + + public String getId() { + return id; + } + + public String getFullName() { + return fullName; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getAuthorFlair() { + return authorFlair; + } + + public String getAuthorFlairHTML() { + return authorFlairHTML; + } + + public String getLinkAuthor() { + return linkAuthor; + } + + public long getCommentTimeMillis() { + return commentTimeMillis; + } + + public String getCommentMarkdown() { + return commentMarkdown; + } + + public void setCommentMarkdown(String commentMarkdown) { + this.commentMarkdown = commentMarkdown; + } + + public String getCommentRawText() { + return commentRawText; + } + + public void setCommentRawText(String commentRawText) { + this.commentRawText = commentRawText; + } + + public String getLinkId() { + return linkId; + } + + public String getSubredditName() { + return subredditName; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public int getScore() { + return score; + } + + public void setScore(int score) { + this.score = score; + } + + public boolean isSubmitter() { + return isSubmitter; + } + + public boolean isModerator() { + return distinguished != null && distinguished.equals("moderator"); + } + + public String getPermalink() { + return permalink; + } + + public String getAwards() { + return awards; + } + + public void addAwards(String newAwardsHTML) { + awards += newAwardsHTML; + } + + public int getDepth() { + return depth; + } + + public boolean isCollapsed() { + return collapsed; + } + + public boolean hasReply() { + return hasReply; + } + + public void setHasReply(boolean hasReply) { + this.hasReply = hasReply; + } + + public boolean isScoreHidden() { + return scoreHidden; + } + + public boolean isSaved() { + return saved; + } + + public void setSaved(boolean saved) { + this.saved = saved; + } + + public boolean isExpanded() { + return isExpanded; + } + + public void setExpanded(boolean isExpanded) { + this.isExpanded = isExpanded; + if (isExpanded && !hasExpandedBefore) { + hasExpandedBefore = true; + } + } + + public boolean hasExpandedBefore() { + return hasExpandedBefore; + } + + public int getVoteType() { + return voteType; + } + + public void setVoteType(int voteType) { + this.voteType = voteType; + } + + public ArrayList getChildren() { + return children; + } + + public void setChildren(ArrayList children) { + this.children = children; + } + + public void addChildren(ArrayList moreChildren) { + if (children == null || children.size() == 0) { + setChildren(moreChildren); + } else { + if (children.size() > 1 && children.get(children.size() - 1).isPlaceHolder) { + children.addAll(children.size() - 2, moreChildren); + } else { + children.addAll(moreChildren); + } + } + } + + public void addChild(Comment comment) { + addChild(comment, 0); + } + + public void addChild(Comment comment, int position) { + if (children == null) { + children = new ArrayList<>(); + } + children.add(position, comment); + } + + public ArrayList getMoreChildrenFullnames() { + return moreChildrenFullnames; + } + + public void setMoreChildrenFullnames(ArrayList moreChildrenFullnames) { + this.moreChildrenFullnames = moreChildrenFullnames; + } + + public boolean hasMoreChildrenFullnames() { + return moreChildrenFullnames != null; + } + + public void removeMoreChildrenFullnames() { + moreChildrenFullnames.clear(); + } + + public int getMoreChildrenStartingIndex() { + return moreChildrenStartingIndex; + } + + public void setMoreChildrenStartingIndex(int moreChildrenStartingIndex) { + this.moreChildrenStartingIndex = moreChildrenStartingIndex; + } + + public boolean isPlaceHolder() { + return isPlaceHolder; + } + + public boolean isLoadingMoreChildren() { + return isLoadingMoreChildren; + } + + public void setLoadingMoreChildren(boolean isLoadingMoreChildren) { + this.isLoadingMoreChildren = isLoadingMoreChildren; + } + + public boolean isLoadMoreChildrenFailed() { + return loadMoreChildrenFailed; + } + + public void setLoadMoreChildrenFailed(boolean loadMoreChildrenFailed) { + this.loadMoreChildrenFailed = loadMoreChildrenFailed; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(id); + parcel.writeString(fullName); + parcel.writeString(author); + parcel.writeString(authorFlair); + parcel.writeString(authorFlairHTML); + parcel.writeString(linkAuthor); + parcel.writeLong(commentTimeMillis); + parcel.writeString(commentMarkdown); + parcel.writeString(commentRawText); + parcel.writeString(linkId); + parcel.writeString(subredditName); + parcel.writeString(parentId); + parcel.writeInt(score); + parcel.writeInt(voteType); + parcel.writeByte((byte) (isSubmitter ? 1 : 0)); + parcel.writeString(distinguished); + parcel.writeString(permalink); + parcel.writeString(awards); + parcel.writeInt(depth); + parcel.writeByte((byte) (collapsed ? 1 : 0)); + parcel.writeByte((byte) (hasReply ? 1 : 0)); + parcel.writeByte((byte) (scoreHidden ? 1 : 0)); + parcel.writeByte((byte) (isExpanded ? 1 : 0)); + parcel.writeByte((byte) (hasExpandedBefore ? 1 : 0)); + parcel.writeList(children); + parcel.writeList(moreChildrenFullnames); + parcel.writeInt(moreChildrenStartingIndex); + parcel.writeByte((byte) (isPlaceHolder ? 1 : 0)); + parcel.writeByte((byte) (isLoadingMoreChildren ? 1 : 0)); + parcel.writeByte((byte) (loadMoreChildrenFailed ? 1 : 0)); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java new file mode 100644 index 00000000..42aeaf9e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSource.java @@ -0,0 +1,271 @@ +package ml.docilealligator.infinityforreddit.comment; + +import android.os.AsyncTask; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.PageKeyedDataSource; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class CommentDataSource extends PageKeyedDataSource { + + private Retrofit retrofit; + private Locale locale; + @Nullable + private String accessToken; + private String username; + private SortType sortType; + private boolean areSavedComments; + + private MutableLiveData paginationNetworkStateLiveData; + private MutableLiveData initialLoadStateLiveData; + private MutableLiveData hasPostLiveData; + + private LoadParams params; + private LoadCallback callback; + + CommentDataSource(Retrofit retrofit, Locale locale, @Nullable String accessToken, String username, SortType sortType, + boolean areSavedComments) { + this.retrofit = retrofit; + this.locale = locale; + this.accessToken = accessToken; + this.username = username; + this.sortType = sortType; + this.areSavedComments = areSavedComments; + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasPostLiveData = new MutableLiveData<>(); + } + + MutableLiveData getPaginationNetworkStateLiveData() { + return paginationNetworkStateLiveData; + } + + MutableLiveData getInitialLoadStateLiveData() { + return initialLoadStateLiveData; + } + + MutableLiveData hasPostLiveData() { + return hasPostLiveData; + } + + void retryLoadingMore() { + loadAfter(params, callback); + } + + @Override + public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { + initialLoadStateLiveData.postValue(NetworkState.LOADING); + + RedditAPI api = retrofit.create(RedditAPI.class); + Call commentsCall; + if (areSavedComments) { + if (sortType.getTime() != null) { + commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, + null, sortType.getType().value, sortType.getTime().value, + APIUtils.getOAuthHeader(accessToken)); + } else { + commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, + null, sortType.getType().value, APIUtils.getOAuthHeader(accessToken)); + } + } else { + if (accessToken == null) { + if (sortType.getTime() != null) { + commentsCall = api.getUserComments(username, null, sortType.getType().value, + sortType.getTime().value); + } else { + commentsCall = api.getUserComments(username, null, sortType.getType().value); + } + } else { + if (sortType.getTime() != null) { + commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), username, + null, sortType.getType().value, sortType.getTime().value); + } else { + commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), username, + null, sortType.getType().value); + } + } + } + commentsCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseCommentAsyncTask(response.body(), locale, new ParseCommentAsyncTask.ParseCommentAsyncTaskListener() { + @Override + public void parseSuccessful(ArrayList comments, String after) { + if (comments.size() == 0) { + hasPostLiveData.postValue(false); + } else { + hasPostLiveData.postValue(true); + } + + if (after == null || after.equals("") || after.equals("null")) { + callback.onResult(comments, null, null); + } else { + callback.onResult(comments, null, after); + } + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void parseFailed() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }).execute(); + } else { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } + + @Override + public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { + + } + + @Override + public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { + this.params = params; + this.callback = callback; + + paginationNetworkStateLiveData.postValue(NetworkState.LOADING); + + RedditAPI api = retrofit.create(RedditAPI.class); + Call commentsCall; + if (areSavedComments) { + if (sortType.getTime() != null) { + commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, params.key, + sortType.getType().value, sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + } else { + commentsCall = api.getUserSavedCommentsOauth(username, PostDataSource.USER_WHERE_SAVED, params.key, + sortType.getType().value, APIUtils.getOAuthHeader(accessToken)); + } + } else { + if (accessToken == null) { + if (sortType.getTime() != null) { + commentsCall = api.getUserComments(username, params.key, sortType.getType().value, + sortType.getTime().value); + } else { + commentsCall = api.getUserComments(username, params.key, sortType.getType().value); + } + } else { + if (sortType.getTime() != null) { + commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), + username, params.key, sortType.getType().value, sortType.getTime().value); + } else { + commentsCall = api.getUserCommentsOauth(APIUtils.getOAuthHeader(accessToken), + username, params.key, sortType.getType().value); + } + } + } + commentsCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseCommentAsyncTask(response.body(), locale, new ParseCommentAsyncTask.ParseCommentAsyncTaskListener() { + @Override + public void parseSuccessful(ArrayList comments, String after) { + if (after == null || after.equals("") || after.equals("null")) { + callback.onResult(comments, null); + } else { + callback.onResult(comments, after); + } + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void parseFailed() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }).execute(); + } else { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); + } + }); + } + + private static class ParseCommentAsyncTask extends AsyncTask, ArrayList> { + private String after; + private Locale locale; + private JSONArray commentsJSONArray; + private boolean parseFailed; + private ParseCommentAsyncTaskListener parseCommentAsyncTaskListener; + + ParseCommentAsyncTask(String response, Locale locale, ParseCommentAsyncTaskListener parseCommentAsyncTaskListener) { + this.locale = locale; + this.parseCommentAsyncTaskListener = parseCommentAsyncTaskListener; + try { + JSONObject data = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY); + commentsJSONArray = data.getJSONArray(JSONUtils.CHILDREN_KEY); + after = data.getString(JSONUtils.AFTER_KEY); + parseFailed = false; + } catch (JSONException e) { + parseFailed = true; + e.printStackTrace(); + } + } + + @Override + protected ArrayList doInBackground(Void... voids) { + if (parseFailed) { + return null; + } + + ArrayList comments = new ArrayList<>(); + for (int i = 0; i < commentsJSONArray.length(); i++) { + try { + JSONObject commentJSON = commentsJSONArray.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + comments.add(ParseComment.parseSingleComment(commentJSON, 0, locale)); + } catch (JSONException ignored) { + } + } + return comments; + } + + @Override + protected void onPostExecute(ArrayList commentData) { + super.onPostExecute(commentData); + if (commentData != null) { + parseCommentAsyncTaskListener.parseSuccessful(commentData, after); + } else { + parseCommentAsyncTaskListener.parseFailed(); + } + } + + interface ParseCommentAsyncTaskListener { + void parseSuccessful(ArrayList comments, String after); + + void parseFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSourceFactory.java new file mode 100644 index 00000000..6f89215c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentDataSourceFactory.java @@ -0,0 +1,56 @@ +package ml.docilealligator.infinityforreddit.comment; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.DataSource; + +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +class CommentDataSourceFactory extends DataSource.Factory { + private Retrofit retrofit; + private Locale locale; + private String accessToken; + private String username; + private SortType sortType; + private boolean areSavedComments; + + private CommentDataSource commentDataSource; + private MutableLiveData commentDataSourceLiveData; + + CommentDataSourceFactory(Retrofit retrofit, Locale locale, @Nullable String accessToken, + String username, SortType sortType, + boolean areSavedComments) { + this.retrofit = retrofit; + this.locale = locale; + this.accessToken = accessToken; + this.username = username; + this.sortType = sortType; + this.areSavedComments = areSavedComments; + commentDataSourceLiveData = new MutableLiveData<>(); + } + + @NonNull + @Override + public DataSource create() { + commentDataSource = new CommentDataSource(retrofit, locale, accessToken, username, sortType, + areSavedComments); + commentDataSourceLiveData.postValue(commentDataSource); + return commentDataSource; + } + + public MutableLiveData getCommentDataSourceLiveData() { + return commentDataSourceLiveData; + } + + CommentDataSource getCommentDataSource() { + return commentDataSource; + } + + void changeSortType(SortType sortType) { + this.sortType = sortType; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentViewModel.java new file mode 100644 index 00000000..9848d499 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/CommentViewModel.java @@ -0,0 +1,105 @@ +package ml.docilealligator.infinityforreddit.comment; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Transformations; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.LivePagedListBuilder; +import androidx.paging.PagedList; + +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +public class CommentViewModel extends ViewModel { + private CommentDataSourceFactory commentDataSourceFactory; + private LiveData paginationNetworkState; + private LiveData initialLoadingState; + private LiveData hasCommentLiveData; + private LiveData> comments; + private MutableLiveData sortTypeLiveData; + + public CommentViewModel(Retrofit retrofit, Locale locale, String accessToken, String username, SortType sortType, + boolean areSavedComments) { + commentDataSourceFactory = new CommentDataSourceFactory(retrofit, locale, accessToken, username, sortType, + areSavedComments); + + initialLoadingState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(), + CommentDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(), + CommentDataSource::getPaginationNetworkStateLiveData); + hasCommentLiveData = Transformations.switchMap(commentDataSourceFactory.getCommentDataSourceLiveData(), + CommentDataSource::hasPostLiveData); + + sortTypeLiveData = new MutableLiveData<>(); + sortTypeLiveData.postValue(sortType); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + comments = Transformations.switchMap(sortTypeLiveData, sort -> { + commentDataSourceFactory.changeSortType(sortTypeLiveData.getValue()); + return (new LivePagedListBuilder(commentDataSourceFactory, pagedListConfig)).build(); + }); + } + + public LiveData> getComments() { + return comments; + } + + public LiveData getPaginationNetworkState() { + return paginationNetworkState; + } + + public LiveData getInitialLoadingState() { + return initialLoadingState; + } + + public LiveData hasComment() { + return hasCommentLiveData; + } + + public void refresh() { + commentDataSourceFactory.getCommentDataSource().invalidate(); + } + + public void retryLoadingMore() { + commentDataSourceFactory.getCommentDataSource().retryLoadingMore(); + } + + public void changeSortType(SortType sortType) { + sortTypeLiveData.postValue(sortType); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Retrofit retrofit; + private Locale locale; + private String accessToken; + private String username; + private SortType sortType; + private boolean areSavedComments; + + public Factory(Retrofit retrofit, Locale locale, String accessToken, String username, + SortType sortType, boolean areSavedComments) { + this.retrofit = retrofit; + this.locale = locale; + this.accessToken = accessToken; + this.username = username; + this.sortType = sortType; + this.areSavedComments = areSavedComments; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new CommentViewModel(retrofit, locale, accessToken, username, sortType, areSavedComments); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java new file mode 100644 index 00000000..a21335f4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchComment.java @@ -0,0 +1,138 @@ +package ml.docilealligator.infinityforreddit.comment; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchComment { + public static void fetchComments(Retrofit retrofit, @Nullable String accessToken, String article, + String commentId, String sortType, boolean expandChildren, + Locale locale, FetchCommentListener fetchCommentListener) { + RedditAPI api = retrofit.create(RedditAPI.class); + Call comments; + if (accessToken == null) { + if (commentId == null) { + comments = api.getPostAndCommentsById(article, sortType); + } else { + comments = api.getPostAndCommentsSingleThreadById(article, commentId, sortType); + } + } else { + if (commentId == null) { + comments = api.getPostAndCommentsByIdOauth(article, sortType, APIUtils.getOAuthHeader(accessToken)); + } else { + comments = api.getPostAndCommentsSingleThreadByIdOauth(article, commentId, sortType, + APIUtils.getOAuthHeader(accessToken)); + } + } + + comments.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseComment.parseComment(response.body(), new ArrayList<>(), + locale, expandChildren, new ParseComment.ParseCommentListener() { + @Override + public void onParseCommentSuccess(ArrayList expandedComments, + String parentId, ArrayList moreChildrenFullnames) { + fetchCommentListener.onFetchCommentSuccess(expandedComments, parentId, + moreChildrenFullnames); + } + + @Override + public void onParseCommentFailed() { + fetchCommentListener.onFetchCommentFailed(); + } + }); + } else { + fetchCommentListener.onFetchCommentFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchCommentListener.onFetchCommentFailed(); + } + }); + } + + public static void fetchMoreComment(Retrofit retrofit, @Nullable String accessToken, + ArrayList allChildren, int startingIndex, + int depth, boolean expandChildren, Locale locale, + FetchMoreCommentListener fetchMoreCommentListener) { + if (allChildren == null) { + return; + } + + StringBuilder stringBuilder = new StringBuilder(); + for (int i = 0; i < 100; i++) { + if (allChildren.size() <= startingIndex + i) { + break; + } + stringBuilder.append(allChildren.get(startingIndex + i)).append(","); + } + + if (stringBuilder.length() == 0) { + return; + } + + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + + RedditAPI api = retrofit.create(RedditAPI.class); + Call moreComments; + if (accessToken == null) { + moreComments = api.getInfo(stringBuilder.toString()); + } else { + moreComments = api.getInfoOauth(stringBuilder.toString(), APIUtils.getOAuthHeader(accessToken)); + } + + moreComments.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseComment.parseMoreComment(response.body(), new ArrayList<>(), locale, + depth, expandChildren, new ParseComment.ParseCommentListener() { + @Override + public void onParseCommentSuccess(ArrayList expandedComments, + String parentId, ArrayList moreChildrenFullnames) { + fetchMoreCommentListener.onFetchMoreCommentSuccess(expandedComments, + startingIndex + 100); + } + + @Override + public void onParseCommentFailed() { + fetchMoreCommentListener.onFetchMoreCommentFailed(); + } + }); + } else { + fetchMoreCommentListener.onFetchMoreCommentFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchMoreCommentListener.onFetchMoreCommentFailed(); + } + }); + } + + public interface FetchCommentListener { + void onFetchCommentSuccess(ArrayList expandedComments, String parentId, ArrayList children); + + void onFetchCommentFailed(); + } + + public interface FetchMoreCommentListener { + void onFetchMoreCommentSuccess(ArrayList expandedComments, int childrenStartingIndex); + + void onFetchMoreCommentFailed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchRemovedComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchRemovedComment.java new file mode 100644 index 00000000..4ce0754a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/FetchRemovedComment.java @@ -0,0 +1,97 @@ +package ml.docilealligator.infinityforreddit.comment; + +import android.os.AsyncTask; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; + +import ml.docilealligator.infinityforreddit.apis.PushshiftAPI; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchRemovedComment { + + public static void fetchRemovedComment(Retrofit retrofit, Comment comment, FetchRemovedCommentListener listener) { + retrofit.create(PushshiftAPI.class).getRemovedComment(comment.getId()) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseCommentAsyncTask(response.body(), comment, listener).execute(); + } else { + listener.fetchFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + t.printStackTrace(); + listener.fetchFailed(); + } + }); + } + + private static Comment parseRemovedComment(JSONObject result, Comment comment) throws JSONException { + String id = result.getString(JSONUtils.ID_KEY); + String author = result.getString(JSONUtils.AUTHOR_KEY); + String body = Utils.modifyMarkdown(result.optString(JSONUtils.BODY_KEY).trim()); + + if ( id.equals(comment.getId()) && + (!author.equals(comment.getAuthor()) || + !body.equals(comment.getCommentRawText())) + ) { + comment.setAuthor(author); + comment.setCommentMarkdown(body); + comment.setCommentRawText(body); + return comment; + } else { + return null; + } + } + + public interface FetchRemovedCommentListener { + void fetchSuccess(Comment comment); + + void fetchFailed(); + } + + private static class ParseCommentAsyncTask extends AsyncTask { + + private String responseBody; + private FetchRemovedCommentListener listener; + Comment comment; + + public ParseCommentAsyncTask(String responseBody, Comment comment, FetchRemovedCommentListener listener) { + this.responseBody = responseBody; + this.comment = comment; + this.listener = listener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject commentJSON = new JSONObject(responseBody).getJSONArray(JSONUtils.DATA_KEY).getJSONObject(0); + comment = parseRemovedComment(commentJSON, comment); + } catch (JSONException e) { + e.printStackTrace(); + comment = null; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (comment != null) + listener.fetchSuccess(comment); + else + listener.fetchFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java new file mode 100644 index 00000000..0b38c530 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/ParseComment.java @@ -0,0 +1,324 @@ +package ml.docilealligator.infinityforreddit.comment; + +import android.os.AsyncTask; +import android.text.Html; + +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; + +import static ml.docilealligator.infinityforreddit.comment.Comment.VOTE_TYPE_DOWNVOTE; +import static ml.docilealligator.infinityforreddit.comment.Comment.VOTE_TYPE_NO_VOTE; +import static ml.docilealligator.infinityforreddit.comment.Comment.VOTE_TYPE_UPVOTE; + +public class ParseComment { + public static void parseComment(String response, ArrayList commentData, Locale locale, + boolean expandChildren, ParseCommentListener parseCommentListener) { + try { + JSONArray childrenArray = new JSONArray(response); + String parentId = childrenArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY) + .getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.NAME_KEY); + childrenArray = childrenArray.getJSONObject(1).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + + new ParseCommentAsyncTask(childrenArray, commentData, locale, parentId, 0, expandChildren, parseCommentListener).execute(); + } catch (JSONException e) { + e.printStackTrace(); + parseCommentListener.onParseCommentFailed(); + } + } + + static void parseMoreComment(String response, ArrayList commentData, Locale locale, + int depth, boolean expandChildren, ParseCommentListener parseCommentListener) { + try { + JSONArray childrenArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + new ParseCommentAsyncTask(childrenArray, commentData, locale, null, depth, expandChildren, parseCommentListener).execute(); + } catch (JSONException e) { + e.printStackTrace(); + parseCommentListener.onParseCommentFailed(); + } + } + + static void parseSentComment(String response, int depth, Locale locale, + ParseSentCommentListener parseSentCommentListener) { + new ParseSentCommentAsyncTask(response, depth, locale, parseSentCommentListener).execute(); + } + + private static void parseCommentRecursion(JSONArray comments, ArrayList newCommentData, + ArrayList moreChildrenFullnames, int depth, Locale locale) throws JSONException { + int actualCommentLength; + + if (comments.length() == 0) { + return; + } + + JSONObject more = comments.getJSONObject(comments.length() - 1).getJSONObject(JSONUtils.DATA_KEY); + + //Maybe moreChildrenFullnames contain only commentsJSONArray and no more info + if (more.has(JSONUtils.COUNT_KEY)) { + JSONArray childrenArray = more.getJSONArray(JSONUtils.CHILDREN_KEY); + + for (int i = 0; i < childrenArray.length(); i++) { + moreChildrenFullnames.add("t1_" + childrenArray.getString(i)); + } + + actualCommentLength = comments.length() - 1; + } else { + actualCommentLength = comments.length(); + } + + for (int i = 0; i < actualCommentLength; i++) { + JSONObject data = comments.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + Comment singleComment = parseSingleComment(data, depth, locale); + + if (data.get(JSONUtils.REPLIES_KEY) instanceof JSONObject) { + JSONArray childrenArray = data.getJSONObject(JSONUtils.REPLIES_KEY) + .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + ArrayList children = new ArrayList<>(); + ArrayList nextMoreChildrenFullnames = new ArrayList<>(); + parseCommentRecursion(childrenArray, children, nextMoreChildrenFullnames, singleComment.getDepth(), + locale); + singleComment.addChildren(children); + singleComment.setMoreChildrenFullnames(nextMoreChildrenFullnames); + } + + newCommentData.add(singleComment); + } + } + + private static void expandChildren(ArrayList comments, ArrayList visibleComments, + boolean setExpanded) { + for (Comment c : comments) { + visibleComments.add(c); + if (c.hasReply()) { + if (setExpanded) { + c.setExpanded(true); + } + expandChildren(c.getChildren(), visibleComments, setExpanded); + } else { + c.setExpanded(true); + } + if (c.hasMoreChildrenFullnames() && c.getMoreChildrenFullnames().size() > c.getMoreChildrenStartingIndex()) { + //Add a load more placeholder + Comment placeholder = new Comment(c.getFullName(), c.getDepth() + 1); + visibleComments.add(placeholder); + c.addChild(placeholder, c.getChildren().size()); + } + } + } + + static Comment parseSingleComment(JSONObject singleCommentData, int depth, Locale locale) throws JSONException { + String id = singleCommentData.getString(JSONUtils.ID_KEY); + String fullName = singleCommentData.getString(JSONUtils.NAME_KEY); + String author = singleCommentData.getString(JSONUtils.AUTHOR_KEY); + StringBuilder authorFlairHTMLBuilder = new StringBuilder(); + if (singleCommentData.has(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY)) { + JSONArray flairArray = singleCommentData.getJSONArray(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY); + for (int i = 0; i < flairArray.length(); i++) { + JSONObject flairObject = flairArray.getJSONObject(i); + String e = flairObject.getString(JSONUtils.E_KEY); + if (e.equals("text")) { + authorFlairHTMLBuilder.append(Html.escapeHtml(flairObject.getString(JSONUtils.T_KEY))); + } else if (e.equals("emoji")) { + authorFlairHTMLBuilder.append(""); + } + } + } + String authorFlair = singleCommentData.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) ? "" : singleCommentData.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY); + String linkAuthor = singleCommentData.has(JSONUtils.LINK_AUTHOR_KEY) ? singleCommentData.getString(JSONUtils.LINK_AUTHOR_KEY) : null; + String linkId = singleCommentData.getString(JSONUtils.LINK_ID_KEY).substring(3); + String subredditName = singleCommentData.getString(JSONUtils.SUBREDDIT_KEY); + String parentId = singleCommentData.getString(JSONUtils.PARENT_ID_KEY); + boolean isSubmitter = singleCommentData.getBoolean(JSONUtils.IS_SUBMITTER_KEY); + String distinguished = singleCommentData.getString(JSONUtils.DISTINGUISHED_KEY); + String commentMarkdown = ""; + if (!singleCommentData.isNull(JSONUtils.BODY_KEY)) { + commentMarkdown = Utils.modifyMarkdown(singleCommentData.getString(JSONUtils.BODY_KEY).trim()); + } + String commentRawText = Utils.trimTrailingWhitespace( + Html.fromHtml(singleCommentData.getString(JSONUtils.BODY_HTML_KEY))).toString(); + String permalink = Html.fromHtml(singleCommentData.getString(JSONUtils.PERMALINK_KEY)).toString(); + StringBuilder awardingsBuilder = new StringBuilder(); + JSONArray awardingsArray = singleCommentData.getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); + for (int i = 0; i < awardingsArray.length(); i++) { + JSONObject award = awardingsArray.getJSONObject(i); + int count = award.getInt(JSONUtils.COUNT_KEY); + JSONArray icons = award.getJSONArray(JSONUtils.RESIZED_ICONS_KEY); + if (icons.length() > 4) { + String iconUrl = icons.getJSONObject(3).getString(JSONUtils.URL_KEY); + awardingsBuilder.append(" ").append("x").append(count).append(" "); + } else if (icons.length() > 0) { + String iconUrl = icons.getJSONObject(icons.length() - 1).getString(JSONUtils.URL_KEY); + awardingsBuilder.append(" ").append("x").append(count).append(" "); + } + } + int score = singleCommentData.getInt(JSONUtils.SCORE_KEY); + int voteType; + if (singleCommentData.isNull(JSONUtils.LIKES_KEY)) { + voteType = VOTE_TYPE_NO_VOTE; + } else { + voteType = singleCommentData.getBoolean(JSONUtils.LIKES_KEY) ? VOTE_TYPE_UPVOTE : VOTE_TYPE_DOWNVOTE; + score -= voteType; + } + long submitTime = singleCommentData.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; + boolean scoreHidden = singleCommentData.getBoolean(JSONUtils.SCORE_HIDDEN_KEY); + boolean saved = singleCommentData.getBoolean(JSONUtils.SAVED_KEY); + + if (singleCommentData.has(JSONUtils.DEPTH_KEY)) { + depth = singleCommentData.getInt(JSONUtils.DEPTH_KEY); + } + + boolean collapsed = singleCommentData.getBoolean(JSONUtils.COLLAPSED_KEY); + boolean hasReply = !(singleCommentData.get(JSONUtils.REPLIES_KEY) instanceof String); + + return new Comment(id, fullName, author, authorFlair, authorFlairHTMLBuilder.toString(), + linkAuthor, submitTime, commentMarkdown, commentRawText, + linkId, subredditName, parentId, score, voteType, isSubmitter, distinguished, + permalink, awardingsBuilder.toString(),depth, collapsed, hasReply, scoreHidden, saved); + } + + @Nullable + private static String parseSentCommentErrorMessage(String response) { + try { + JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); + + if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) + .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); + if (error.length() != 0) { + String errorString; + if (error.length() >= 2) { + errorString = error.getString(1); + } else { + errorString = error.getString(0); + } + return errorString.substring(0, 1).toUpperCase() + errorString.substring(1); + } else { + return null; + } + } else { + return null; + } + } catch (JSONException e) { + e.printStackTrace(); + } + + return null; + } + + public interface ParseCommentListener { + void onParseCommentSuccess(ArrayList expandedComments, String parentId, + ArrayList moreChildrenFullnames); + + void onParseCommentFailed(); + } + + interface ParseSentCommentListener { + void onParseSentCommentSuccess(Comment comment); + + void onParseSentCommentFailed(@Nullable String errorMessage); + } + + private static class ParseCommentAsyncTask extends AsyncTask { + private JSONArray commentsJSONArray; + private ArrayList comments; + private ArrayList newComments; + private ArrayList expandedNewComments; + private ArrayList moreChildrenFullnames; + private Locale locale; + private String parentId; + private int depth; + private boolean expandChildren; + private ParseCommentListener parseCommentListener; + private boolean parseFailed; + + ParseCommentAsyncTask(JSONArray commentsJSONArray, ArrayList comments, Locale locale, + @Nullable String parentId, int depth, boolean expandChildren, + ParseCommentListener parseCommentListener) { + this.commentsJSONArray = commentsJSONArray; + this.comments = comments; + newComments = new ArrayList<>(); + expandedNewComments = new ArrayList<>(); + moreChildrenFullnames = new ArrayList<>(); + this.locale = locale; + this.parentId = parentId; + this.depth = depth; + this.expandChildren = expandChildren; + parseFailed = false; + this.parseCommentListener = parseCommentListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + parseCommentRecursion(commentsJSONArray, newComments, moreChildrenFullnames, depth, locale); + expandChildren(newComments, expandedNewComments, expandChildren); + } catch (JSONException e) { + parseFailed = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!parseFailed) { + if (expandChildren) { + comments.addAll(expandedNewComments); + } else { + comments.addAll(newComments); + } + parseCommentListener.onParseCommentSuccess(comments, parentId, moreChildrenFullnames); + } else { + parseCommentListener.onParseCommentFailed(); + } + } + } + + private static class ParseSentCommentAsyncTask extends AsyncTask { + private String response; + private int depth; + private Locale locale; + private ParseSentCommentListener parseSentCommentListener; + private boolean parseFailed; + private String errorMessage; + private Comment comment; + + ParseSentCommentAsyncTask(String response, int depth, Locale locale, ParseSentCommentListener parseSentCommentListener) { + this.response = response; + this.depth = depth; + this.locale = locale; + this.parseSentCommentListener = parseSentCommentListener; + parseFailed = false; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject sentCommentData = new JSONObject(response); + comment = parseSingleComment(sentCommentData, depth, locale); + } catch (JSONException e) { + e.printStackTrace(); + errorMessage = parseSentCommentErrorMessage(response); + parseFailed = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (parseFailed) { + parseSentCommentListener.onParseSentCommentFailed(errorMessage); + } else { + parseSentCommentListener.onParseSentCommentSuccess(comment); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java new file mode 100644 index 00000000..114cc30e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/comment/SendComment.java @@ -0,0 +1,61 @@ +package ml.docilealligator.infinityforreddit.comment; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class SendComment { + + public static void sendComment(String commentMarkdown, String thingFullname, int parentDepth, + Locale locale, Retrofit oauthRetrofit, String accessToken, + SendCommentListener sendCommentListener) { + Map headers = APIUtils.getOAuthHeader(accessToken); + Map params = new HashMap<>(); + params.put(APIUtils.API_TYPE_KEY, "json"); + params.put(APIUtils.RETURN_RTJSON_KEY, "true"); + params.put(APIUtils.TEXT_KEY, commentMarkdown); + params.put(APIUtils.THING_ID_KEY, thingFullname); + + oauthRetrofit.create(RedditAPI.class).sendCommentOrReplyToMessage(headers, params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseComment.parseSentComment(response.body(), parentDepth, locale, new ParseComment.ParseSentCommentListener() { + @Override + public void onParseSentCommentSuccess(Comment comment) { + sendCommentListener.sendCommentSuccess(comment); + } + + @Override + public void onParseSentCommentFailed(@Nullable String errorMessage) { + sendCommentListener.sendCommentFailed(errorMessage); + } + }); + } else { + sendCommentListener.sendCommentFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + sendCommentListener.sendCommentFailed(t.getMessage()); + } + }); + } + + public interface SendCommentListener { + void sendCommentSuccess(Comment comment); + + void sendCommentFailed(String errorMessage); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java new file mode 100644 index 00000000..fb9bda02 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomTheme.java @@ -0,0 +1,280 @@ +package ml.docilealligator.infinityforreddit.customtheme; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +import com.google.gson.Gson; + +import java.util.ArrayList; + +@Entity(tableName = "custom_themes") +public class CustomTheme { + @PrimaryKey + @NonNull + @ColumnInfo(name = "name") + public String name; + @ColumnInfo(name = "is_light_theme") + public boolean isLightTheme; + @ColumnInfo(name = "is_dark_theme") + public boolean isDarkTheme; + @ColumnInfo(name = "is_amoled_theme") + public boolean isAmoledTheme; + @ColumnInfo(name = "color_primary") + public int colorPrimary; + @ColumnInfo(name = "color_primary_dark") + public int colorPrimaryDark; + @ColumnInfo(name = "color_accent") + public int colorAccent; + @ColumnInfo(name = "color_primary_light_theme") + public int colorPrimaryLightTheme; + @ColumnInfo(name = "primary_text_color") + public int primaryTextColor; + @ColumnInfo(name = "secondary_text_color") + public int secondaryTextColor; + @ColumnInfo(name = "post_title_color") + public int postTitleColor; + @ColumnInfo(name = "post_content_color") + public int postContentColor; + @ColumnInfo(name = "comment_color") + public int commentColor; + @ColumnInfo(name = "button_text_color") + public int buttonTextColor; + @ColumnInfo(name = "background_color") + public int backgroundColor; + @ColumnInfo(name = "card_view_background_color") + public int cardViewBackgroundColor; + @ColumnInfo(name = "comment_background_color") + public int commentBackgroundColor; + @ColumnInfo(name = "bottom_app_bar_background_color") + public int bottomAppBarBackgroundColor; + @ColumnInfo(name = "primary_icon_color") + public int primaryIconColor; + @ColumnInfo(name = "bottom_app_bar_icon_color") + public int bottomAppBarIconColor; + @ColumnInfo(name = "post_icon_and_info_color") + public int postIconAndInfoColor; + @ColumnInfo(name = "comment_icon_and_info_color") + public int commentIconAndInfoColor; + @ColumnInfo(name = "toolbar_primary_text_and_icon_color") + public int toolbarPrimaryTextAndIconColor; + @ColumnInfo(name = "toolbar_secondary_text_color") + public int toolbarSecondaryTextColor; + @ColumnInfo(name = "circular_progress_bar_background") + public int circularProgressBarBackground; + @ColumnInfo(name = "tab_layout_with_expanded_collapsing_toolbar_tab_background") + public int tabLayoutWithExpandedCollapsingToolbarTabBackground; + @ColumnInfo(name = "tab_layout_with_expanded_collapsing_toolbar_text_color") + public int tabLayoutWithExpandedCollapsingToolbarTextColor; + @ColumnInfo(name = "tab_layout_with_expanded_collapsing_toolbar_tab_indicator") + public int tabLayoutWithExpandedCollapsingToolbarTabIndicator; + @ColumnInfo(name = "tab_layout_with_collapsed_collapsing_toolbar_tab_background") + public int tabLayoutWithCollapsedCollapsingToolbarTabBackground; + @ColumnInfo(name = "tab_layout_with_collapsed_collapsing_toolbar_text_color") + public int tabLayoutWithCollapsedCollapsingToolbarTextColor; + @ColumnInfo(name = "tab_layout_with_collapsed_collapsing_toolbar_tab_indicator") + public int tabLayoutWithCollapsedCollapsingToolbarTabIndicator; + @ColumnInfo(name = "nav_bar_color") + public int navBarColor; + @ColumnInfo(name = "upvoted") + public int upvoted; + @ColumnInfo(name = "downvoted") + public int downvoted; + @ColumnInfo(name = "post_type_background_color") + public int postTypeBackgroundColor; + @ColumnInfo(name = "post_type_text_color") + public int postTypeTextColor; + @ColumnInfo(name = "spoiler_background_color") + public int spoilerBackgroundColor; + @ColumnInfo(name = "spoiler_text_color") + public int spoilerTextColor; + @ColumnInfo(name = "nsfw_background_color") + public int nsfwBackgroundColor; + @ColumnInfo(name = "nsfw_text_color") + public int nsfwTextColor; + @ColumnInfo(name = "flair_background_color") + public int flairBackgroundColor; + @ColumnInfo(name = "flair_text_color") + public int flairTextColor; + @ColumnInfo(name = "awards_background_color") + public int awardsBackgroundColor; + @ColumnInfo(name = "awards_text_color") + public int awardsTextColor; + @ColumnInfo(name = "archived_tint") + public int archivedTint; + @ColumnInfo(name = "locked_icon_tint") + public int lockedIconTint; + @ColumnInfo(name = "crosspost_icon_tint") + public int crosspostIconTint; + @ColumnInfo(name = "stickied_post_icon_tint") + public int stickiedPostIconTint; + @ColumnInfo(name = "no_preview_post_type_icon_tint") + public int noPreviewPostTypeIconTint; + @ColumnInfo(name = "subscribed") + public int subscribed; + @ColumnInfo(name = "unsubscribed") + public int unsubscribed; + @ColumnInfo(name = "username") + public int username; + @ColumnInfo(name = "subreddit") + public int subreddit; + @ColumnInfo(name = "author_flair_text_color") + public int authorFlairTextColor; + @ColumnInfo(name = "submitter") + public int submitter; + @ColumnInfo(name = "moderator") + public int moderator; + @ColumnInfo(name = "single_comment_thread_background_color") + public int singleCommentThreadBackgroundColor; + @ColumnInfo(name = "unread_message_background_color") + public int unreadMessageBackgroundColor; + @ColumnInfo(name = "divider_color") + public int dividerColor; + @ColumnInfo(name = "no_preview_link_background_color") + public int noPreviewPostTypeBackgroundColor; + @ColumnInfo(name = "vote_and_reply_unavailable_button_color") + public int voteAndReplyUnavailableButtonColor; + @ColumnInfo(name = "comment_vertical_bar_color_1") + public int commentVerticalBarColor1; + @ColumnInfo(name = "comment_vertical_bar_color_2") + public int commentVerticalBarColor2; + @ColumnInfo(name = "comment_vertical_bar_color_3") + public int commentVerticalBarColor3; + @ColumnInfo(name = "comment_vertical_bar_color_4") + public int commentVerticalBarColor4; + @ColumnInfo(name = "comment_vertical_bar_color_5") + public int commentVerticalBarColor5; + @ColumnInfo(name = "comment_vertical_bar_color_6") + public int commentVerticalBarColor6; + @ColumnInfo(name = "comment_vertical_bar_color_7") + public int commentVerticalBarColor7; + @ColumnInfo(name = "fab_icon_color") + public int fabIconColor; + @ColumnInfo(name = "chip_text_color") + public int chipTextColor; + @ColumnInfo(name = "link_color") + public int linkColor; + @ColumnInfo(name = "received_message_text_color") + public int receivedMessageTextColor; + @ColumnInfo(name = "sent_message_text_color") + public int sentMessageTextColor; + @ColumnInfo(name = "received_message_background_color") + public int receivedMessageBackgroundColor; + @ColumnInfo(name = "sent_message_background_color") + public int sentMessageBackgroundColor; + @ColumnInfo(name = "send_message_icon_color") + public int sendMessageIconColor; + @ColumnInfo(name = "fully_collapsed_comment_background_color") + public int fullyCollapsedCommentBackgroundColor; + @ColumnInfo(name = "awarded_comment_background_color") + public int awardedCommentBackgroundColor; + @ColumnInfo(name = "is_light_status_bar") + public boolean isLightStatusBar; + @ColumnInfo(name = "is_light_nav_bar") + public boolean isLightNavBar; + @ColumnInfo(name = "is_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface") + public boolean isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface; + + public CustomTheme() {} + + public CustomTheme(@NonNull String name) { + this.name = name; + } + + public String getJSONModel() { + Gson gson = new Gson(); + return gson.toJson(this); + } + + public static CustomTheme convertSettingsItemsToCustomTheme(ArrayList customThemeSettingsItems, String themeName) { + CustomTheme customTheme = new CustomTheme(themeName); + + if (customThemeSettingsItems.isEmpty()) { + return customTheme; + } + + customTheme.isLightTheme = customThemeSettingsItems.get(0).isEnabled; + customTheme.isDarkTheme = customThemeSettingsItems.get(1).isEnabled; + customTheme.isAmoledTheme = customThemeSettingsItems.get(2).isEnabled; + customTheme.colorPrimary = customThemeSettingsItems.get(3).colorValue; + customTheme.colorPrimaryDark = customThemeSettingsItems.get(4).colorValue; + customTheme.colorAccent = customThemeSettingsItems.get(5).colorValue; + customTheme.colorPrimaryLightTheme = customThemeSettingsItems.get(6).colorValue; + customTheme.primaryTextColor = customThemeSettingsItems.get(7).colorValue; + customTheme.secondaryTextColor = customThemeSettingsItems.get(8).colorValue; + customTheme.postTitleColor = customThemeSettingsItems.get(9).colorValue; + customTheme.postContentColor = customThemeSettingsItems.get(10).colorValue; + customTheme.commentColor = customThemeSettingsItems.get(11).colorValue; + customTheme.buttonTextColor = customThemeSettingsItems.get(12).colorValue; + customTheme.chipTextColor = customThemeSettingsItems.get(13).colorValue; + customTheme.linkColor = customThemeSettingsItems.get(14).colorValue; + customTheme.receivedMessageTextColor = customThemeSettingsItems.get(15).colorValue; + customTheme.sentMessageTextColor = customThemeSettingsItems.get(16).colorValue; + customTheme.backgroundColor = customThemeSettingsItems.get(17).colorValue; + customTheme.cardViewBackgroundColor = customThemeSettingsItems.get(18).colorValue; + customTheme.commentBackgroundColor = customThemeSettingsItems.get(19).colorValue; + customTheme.fullyCollapsedCommentBackgroundColor = customThemeSettingsItems.get(20).colorValue; + customTheme.awardedCommentBackgroundColor = customThemeSettingsItems.get(21).colorValue; + customTheme.receivedMessageBackgroundColor = customThemeSettingsItems.get(22).colorValue; + customTheme.sentMessageBackgroundColor = customThemeSettingsItems.get(23).colorValue; + customTheme.bottomAppBarBackgroundColor = customThemeSettingsItems.get(24).colorValue; + customTheme.primaryIconColor = customThemeSettingsItems.get(25).colorValue; + customTheme.bottomAppBarIconColor = customThemeSettingsItems.get(26).colorValue; + customTheme.postIconAndInfoColor = customThemeSettingsItems.get(27).colorValue; + customTheme.commentIconAndInfoColor = customThemeSettingsItems.get(28).colorValue; + customTheme.fabIconColor = customThemeSettingsItems.get(29).colorValue; + customTheme.sendMessageIconColor = customThemeSettingsItems.get(30).colorValue; + customTheme.toolbarPrimaryTextAndIconColor = customThemeSettingsItems.get(31).colorValue; + customTheme.toolbarSecondaryTextColor = customThemeSettingsItems.get(32).colorValue; + customTheme.circularProgressBarBackground = customThemeSettingsItems.get(33).colorValue; + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = customThemeSettingsItems.get(34).colorValue; + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = customThemeSettingsItems.get(35).colorValue; + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(36).colorValue; + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = customThemeSettingsItems.get(37).colorValue; + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = customThemeSettingsItems.get(38).colorValue; + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = customThemeSettingsItems.get(39).colorValue; + customTheme.upvoted = customThemeSettingsItems.get(40).colorValue; + customTheme.downvoted = customThemeSettingsItems.get(41).colorValue; + customTheme.postTypeBackgroundColor = customThemeSettingsItems.get(42).colorValue; + customTheme.postTypeTextColor = customThemeSettingsItems.get(43).colorValue; + customTheme.spoilerBackgroundColor = customThemeSettingsItems.get(44).colorValue; + customTheme.spoilerTextColor = customThemeSettingsItems.get(45).colorValue; + customTheme.nsfwBackgroundColor = customThemeSettingsItems.get(46).colorValue; + customTheme.nsfwTextColor = customThemeSettingsItems.get(47).colorValue; + customTheme.flairBackgroundColor = customThemeSettingsItems.get(48).colorValue; + customTheme.flairTextColor = customThemeSettingsItems.get(49).colorValue; + customTheme.awardsBackgroundColor = customThemeSettingsItems.get(50).colorValue; + customTheme.awardsTextColor = customThemeSettingsItems.get(51).colorValue; + customTheme.archivedTint = customThemeSettingsItems.get(52).colorValue; + customTheme.lockedIconTint = customThemeSettingsItems.get(53).colorValue; + customTheme.crosspostIconTint = customThemeSettingsItems.get(54).colorValue; + customTheme.stickiedPostIconTint = customThemeSettingsItems.get(55).colorValue; + customTheme.noPreviewPostTypeIconTint = customThemeSettingsItems.get(56).colorValue; + customTheme.subscribed = customThemeSettingsItems.get(57).colorValue; + customTheme.unsubscribed = customThemeSettingsItems.get(58).colorValue; + customTheme.username = customThemeSettingsItems.get(59).colorValue; + customTheme.subreddit = customThemeSettingsItems.get(60).colorValue; + customTheme.authorFlairTextColor = customThemeSettingsItems.get(61).colorValue; + customTheme.submitter = customThemeSettingsItems.get(62).colorValue; + customTheme.moderator = customThemeSettingsItems.get(63).colorValue; + customTheme.singleCommentThreadBackgroundColor = customThemeSettingsItems.get(64).colorValue; + customTheme.unreadMessageBackgroundColor = customThemeSettingsItems.get(65).colorValue; + customTheme.dividerColor = customThemeSettingsItems.get(66).colorValue; + customTheme.noPreviewPostTypeBackgroundColor = customThemeSettingsItems.get(67).colorValue; + customTheme.voteAndReplyUnavailableButtonColor = customThemeSettingsItems.get(68).colorValue; + customTheme.commentVerticalBarColor1 = customThemeSettingsItems.get(69).colorValue; + customTheme.commentVerticalBarColor2 = customThemeSettingsItems.get(70).colorValue; + customTheme.commentVerticalBarColor3 = customThemeSettingsItems.get(71).colorValue; + customTheme.commentVerticalBarColor4 = customThemeSettingsItems.get(72).colorValue; + customTheme.commentVerticalBarColor5 = customThemeSettingsItems.get(73).colorValue; + customTheme.commentVerticalBarColor6 = customThemeSettingsItems.get(74).colorValue; + customTheme.commentVerticalBarColor7 = customThemeSettingsItems.get(75).colorValue; + customTheme.navBarColor = customThemeSettingsItems.get(76).colorValue; + customTheme.isLightStatusBar = customThemeSettingsItems.get(77).isEnabled; + customTheme.isLightNavBar = customThemeSettingsItems.get(78).isEnabled; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = customThemeSettingsItems.get(79).isEnabled; + + return customTheme; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeDao.java new file mode 100644 index 00000000..0b779316 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeDao.java @@ -0,0 +1,57 @@ +package ml.docilealligator.infinityforreddit.customtheme; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface CustomThemeDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(CustomTheme customTheme); + + @Query("SELECT * FROM custom_themes") + LiveData> getAllCustomThemes(); + + @Query("SELECT * FROM custom_themes WHERE is_light_theme = 1 LIMIT 1") + CustomTheme getLightCustomTheme(); + + @Query("SELECT * FROM custom_themes WHERE is_dark_theme = 1 LIMIT 1") + CustomTheme getDarkCustomTheme(); + + @Query("SELECT * FROM custom_themes WHERE is_amoled_theme = 1 LIMIT 1") + CustomTheme getAmoledCustomTheme(); + + @Query("SELECT * FROM custom_themes WHERE is_light_theme = 1 LIMIT 1") + LiveData getLightCustomThemeLiveData(); + + @Query("SELECT * FROM custom_themes WHERE is_dark_theme = 1 LIMIT 1") + LiveData getDarkCustomThemeLiveData(); + + @Query("SELECT * FROM custom_themes WHERE is_amoled_theme = 1 LIMIT 1") + LiveData getAmoledCustomThemeLiveData(); + + @Query("SELECT * FROM custom_themes WHERE name = :name COLLATE NOCASE LIMIT 1") + CustomTheme getCustomTheme(String name); + + @Query("UPDATE custom_themes SET is_light_theme = 0 WHERE is_light_theme = 1") + void unsetLightTheme(); + + @Query("UPDATE custom_themes SET is_dark_theme = 0 WHERE is_dark_theme = 1") + void unsetDarkTheme(); + + @Query("UPDATE custom_themes SET is_amoled_theme = 0 WHERE is_amoled_theme = 1") + void unsetAmoledTheme(); + + @Query("DELETE FROM custom_themes WHERE name = :name") + void deleteCustomTheme(String name); + + @Query("UPDATE custom_themes SET name = :newName WHERE name = :oldName") + void updateName(String oldName, String newName); + + @Query("DELETE FROM custom_themes") + void deleteAllCustomThemes(); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeRepository.java new file mode 100644 index 00000000..c3e07f22 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeRepository.java @@ -0,0 +1,37 @@ +package ml.docilealligator.infinityforreddit.customtheme; + +import androidx.lifecycle.LiveData; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class CustomThemeRepository { + private LiveData> mAllCustomThemes; + private LiveData mCurrentLightCustomTheme; + private LiveData mCurrentDarkCustomTheme; + private LiveData mCurrentAmoledCustomTheme; + + CustomThemeRepository(RedditDataRoomDatabase redditDataRoomDatabase) { + mAllCustomThemes = redditDataRoomDatabase.customThemeDao().getAllCustomThemes(); + mCurrentLightCustomTheme = redditDataRoomDatabase.customThemeDao().getLightCustomThemeLiveData(); + mCurrentDarkCustomTheme = redditDataRoomDatabase.customThemeDao().getDarkCustomThemeLiveData(); + mCurrentAmoledCustomTheme = redditDataRoomDatabase.customThemeDao().getAmoledCustomThemeLiveData(); + } + + LiveData> getAllCustomThemes() { + return mAllCustomThemes; + } + + LiveData getCurrentLightCustomTheme() { + return mCurrentLightCustomTheme; + } + + LiveData getCurrentDarkCustomTheme() { + return mCurrentDarkCustomTheme; + } + + LiveData getCurrentAmoledCustomTheme() { + return mCurrentAmoledCustomTheme; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeSettingsItem.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeSettingsItem.java new file mode 100644 index 00000000..56ad8718 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeSettingsItem.java @@ -0,0 +1,398 @@ +package ml.docilealligator.infinityforreddit.customtheme; + +import android.content.Context; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.R; + +public class CustomThemeSettingsItem implements Parcelable { + public String itemName; + public String itemDetails; + public int colorValue; + public boolean isEnabled; + + private CustomThemeSettingsItem(String itemName, String itemDetails, int colorValue) { + this.itemName = itemName; + this.itemDetails = itemDetails; + this.colorValue = colorValue; + } + + private CustomThemeSettingsItem(String itemName, boolean isEnabled) { + this.itemName = itemName; + this.isEnabled = isEnabled; + } + + protected CustomThemeSettingsItem(Parcel in) { + itemName = in.readString(); + itemDetails = in.readString(); + colorValue = in.readInt(); + isEnabled = in.readByte() != 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public CustomThemeSettingsItem createFromParcel(Parcel in) { + return new CustomThemeSettingsItem(in); + } + + @Override + public CustomThemeSettingsItem[] newArray(int size) { + return new CustomThemeSettingsItem[size]; + } + }; + + public static ArrayList convertCustomThemeToSettingsItem(Context context, + CustomTheme customTheme, + int androidVersion) { + ArrayList customThemeSettingsItems = new ArrayList<>(); + + if (customTheme == null) { + return customThemeSettingsItems; + } + + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_is_light_theme), + customTheme.isLightTheme + )); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_is_dark_theme), + customTheme.isDarkTheme + )); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_is_amoled_theme), + customTheme.isAmoledTheme + )); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_color_primary), + context.getString(R.string.theme_item_color_primary_detail), + customTheme.colorPrimary)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_color_primary_dark), + context.getString(R.string.theme_item_color_primary_dark_detail), + customTheme.colorPrimaryDark)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_color_accent), + context.getString(R.string.theme_item_color_accent_detail), + customTheme.colorAccent)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_color_primary_light_theme), + context.getString(R.string.theme_item_color_primary_light_theme_detail), + customTheme.colorPrimaryLightTheme)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_primary_text_color), + context.getString(R.string.theme_item_primary_text_color_detail), + customTheme.primaryTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_secondary_text_color), + context.getString(R.string.theme_item_secondary_text_color_detail), + customTheme.secondaryTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_post_title_color), + context.getString(R.string.theme_item_post_title_color_detail), + customTheme.postTitleColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_post_content_color), + context.getString(R.string.theme_item_post_content_color_detail), + customTheme.postContentColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_color), + context.getString(R.string.theme_item_comment_color_detail), + customTheme.commentColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_button_text_color), + context.getString(R.string.theme_item_button_text_color_detail), + customTheme.buttonTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_chip_text_color), + context.getString(R.string.theme_item_chip_text_color_detail), + customTheme.chipTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_link_color), + context.getString(R.string.theme_item_link_color_detail), + customTheme.linkColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_received_message_text_color), + context.getString(R.string.theme_item_received_message_text_color_detail), + customTheme.receivedMessageTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_sent_message_text_color), + context.getString(R.string.theme_item_sent_message_text_color_detail), + customTheme.sentMessageTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_background_color), + context.getString(R.string.theme_item_background_color_detail), + customTheme.backgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_card_view_background_color), + context.getString(R.string.theme_item_card_view_background_color_detail), + customTheme.cardViewBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_background_color), + context.getString(R.string.theme_item_comment_background_color_detail), + customTheme.commentBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_fully_collapsed_comment_background_color), + context.getString(R.string.theme_item_fully_collapsed_comment_background_color_detail), + customTheme.fullyCollapsedCommentBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_awarded_comment_background_color), + context.getString(R.string.theme_item_awarded_comment_background_color_detail), + customTheme.awardedCommentBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_received_message_background_color), + context.getString(R.string.theme_item_received_message_background_color_detail), + customTheme.receivedMessageBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_sent_message_background_color), + context.getString(R.string.theme_item_sent_message_background_color_detail), + customTheme.sentMessageBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_bottom_app_bar_background_color), + context.getString(R.string.theme_item_bottom_app_bar_background_color_detail), + customTheme.bottomAppBarBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_primary_icon_color), + context.getString(R.string.theme_item_primary_icon_color_detail), + customTheme.primaryIconColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_bottom_app_bar_icon_color), + context.getString(R.string.theme_item_bottom_app_bar_icon_color_detail), + customTheme.bottomAppBarIconColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_post_icon_and_info_color), + context.getString(R.string.theme_item_post_icon_and_info_color_detail), + customTheme.postIconAndInfoColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_icon_and_info_color), + context.getString(R.string.theme_item_comment_icon_and_info_color_detail), + customTheme.commentIconAndInfoColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_fab_icon_color), + context.getString(R.string.theme_item_fab_icon_color_detail), + customTheme.fabIconColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_send_message_icon_color), + context.getString(R.string.theme_item_send_message_icon_color_detail), + customTheme.sendMessageIconColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_toolbar_primary_text_and_icon_color), + context.getString(R.string.theme_item_toolbar_primary_text_and_icon_color_detail), + customTheme.toolbarPrimaryTextAndIconColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_toolbar_secondary_text_color), + context.getString(R.string.theme_item_toolbar_secondary_text_color_detail), + customTheme.toolbarSecondaryTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_circular_progress_bar_background_color), + context.getString(R.string.theme_item_circular_progress_bar_background_color_detail), + customTheme.circularProgressBarBackground)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background), + context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_background_detail), + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color), + context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_text_color_detail), + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator), + context.getString(R.string.theme_item_tab_layout_with_expanded_collapsing_toolbar_tab_indicator_detail), + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background), + context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_background_detail), + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color), + context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_text_color_detail), + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator), + context.getString(R.string.theme_item_tab_layout_with_collapsed_collapsing_toolbar_tab_indicator_detail), + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_upvoted_color), + context.getString(R.string.theme_item_upvoted_color_detail), + customTheme.upvoted)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_downvoted_color), + context.getString(R.string.theme_item_downvoted_color_detail), + customTheme.downvoted)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_post_type_background_color), + context.getString(R.string.theme_item_post_type_background_color_detail), + customTheme.postTypeBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_post_type_text_color), + context.getString(R.string.theme_item_post_type_text_color_detail), + customTheme.postTypeTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_spoiler_background_color), + context.getString(R.string.theme_item_spoiler_background_color_detail), + customTheme.spoilerBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_spoiler_text_color), + context.getString(R.string.theme_item_spoiler_text_color_detail), + customTheme.spoilerTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_nsfw_background_color), + context.getString(R.string.theme_item_nsfw_background_color_detail), + customTheme.nsfwBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_nsfw_text_color), + context.getString(R.string.theme_item_nsfw_text_color_detail), + customTheme.nsfwTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_flair_background_color), + context.getString(R.string.theme_item_flair_background_color_detail), + customTheme.flairBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_flair_text_color), + context.getString(R.string.theme_item_flair_text_color_detail), + customTheme.flairTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_awards_background_color), + context.getString(R.string.theme_item_awards_background_color_detail), + customTheme.awardsBackgroundColor + )); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_awards_text_color), + context.getString(R.string.theme_item_awards_text_color_detail), + customTheme.awardsTextColor + )); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_archived_tint), + context.getString(R.string.theme_item_archived_tint_detail), + customTheme.archivedTint)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_locked_icon_tint), + context.getString(R.string.theme_item_locked_icon_tint_detail), + customTheme.lockedIconTint)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_crosspost_icon_tint), + context.getString(R.string.theme_item_crosspost_icon_tint_detail), + customTheme.crosspostIconTint)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_stickied_post_icon_tint), + context.getString(R.string.theme_item_stickied_post_icon_tint_detail), + customTheme.stickiedPostIconTint)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_no_preview_post_type_icon_tint), + context.getString(R.string.theme_item_no_preview_post_type_icon_tint_detail), + customTheme.noPreviewPostTypeIconTint + )); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_subscribed_color), + context.getString(R.string.theme_item_subscribed_color_detail), + customTheme.subscribed)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_unsubscribed_color), + context.getString(R.string.theme_item_unsubscribed_color_detail), + customTheme.unsubscribed)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_username_color), + context.getString(R.string.theme_item_username_color_detail), + customTheme.username)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_subreddit_color), + context.getString(R.string.theme_item_subreddit_color_detail), + customTheme.subreddit)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_author_flair_text_color), + context.getString(R.string.theme_item_author_flair_text_color_detail), + customTheme.authorFlairTextColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_submitter_color), + context.getString(R.string.theme_item_submitter_color_detail), + customTheme.submitter)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_moderator_color), + context.getString(R.string.theme_item_moderator_color_detail), + customTheme.moderator)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_single_comment_thread_background_color), + context.getString(R.string.theme_item_single_comment_thread_background_color_detail), + customTheme.singleCommentThreadBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_unread_message_background_color), + context.getString(R.string.theme_item_unread_message_background_color_detail), + customTheme.unreadMessageBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_divider_color), + context.getString(R.string.theme_item_divider_color_detail), + customTheme.dividerColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_no_preview_post_type_background_color), + context.getString(R.string.theme_item_no_preview_post_type_background_color_detail), + customTheme.noPreviewPostTypeBackgroundColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_vote_and_reply_unavailable_button_color), + context.getString(R.string.theme_item_vote_and_reply_unavailable_button_color_detail), + customTheme.voteAndReplyUnavailableButtonColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_vertical_bar_color_1), + context.getString(R.string.theme_item_comment_vertical_bar_color_1_detail), + customTheme.commentVerticalBarColor1)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_vertical_bar_color_2), + context.getString(R.string.theme_item_comment_vertical_bar_color_2_detail), + customTheme.commentVerticalBarColor2)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_vertical_bar_color_3), + context.getString(R.string.theme_item_comment_vertical_bar_color_3_detail), + customTheme.commentVerticalBarColor3)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_vertical_bar_color_4), + context.getString(R.string.theme_item_comment_vertical_bar_color_4_detail), + customTheme.commentVerticalBarColor4)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_vertical_bar_color_5), + context.getString(R.string.theme_item_comment_vertical_bar_color_5_detail), + customTheme.commentVerticalBarColor5)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_vertical_bar_color_6), + context.getString(R.string.theme_item_comment_vertical_bar_color_6_detail), + customTheme.commentVerticalBarColor6)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_comment_vertical_bar_color_7), + context.getString(R.string.theme_item_comment_vertical_bar_color_7_detail), + customTheme.commentVerticalBarColor7)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_nav_bar_color), + context.getString(R.string.theme_item_nav_bar_color_detail), + customTheme.navBarColor)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_light_status_bar), + customTheme.isLightStatusBar)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_light_nav_bar), + customTheme.isLightNavBar)); + customThemeSettingsItems.add(new CustomThemeSettingsItem( + context.getString(R.string.theme_item_change_status_bar_icon_color_after_toolbar_collapsed_in_immersive_interface), + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface)); + if (androidVersion < Build.VERSION_CODES.O) { + customThemeSettingsItems.get(customThemeSettingsItems.size() - 2).itemDetails = context.getString(R.string.theme_item_available_on_android_8); + } + if (androidVersion < Build.VERSION_CODES.M) { + customThemeSettingsItems.get(customThemeSettingsItems.size() - 3).itemDetails = context.getString(R.string.theme_item_available_on_android_6); + } + return customThemeSettingsItems; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(itemName); + parcel.writeString(itemDetails); + parcel.writeInt(colorValue); + parcel.writeByte((byte) (isEnabled ? 1 : 0)); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeViewModel.java new file mode 100644 index 00000000..d7abf17b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeViewModel.java @@ -0,0 +1,55 @@ +package ml.docilealligator.infinityforreddit.customtheme; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class CustomThemeViewModel extends ViewModel { + private LiveData> mAllCustomThemes; + private LiveData mCurrentLightTheme; + private LiveData mCurrentDarkTheme; + private LiveData mCurrentAmoledTheme; + + public CustomThemeViewModel(RedditDataRoomDatabase redditDataRoomDatabase) { + CustomThemeRepository customThemeRepository = new CustomThemeRepository(redditDataRoomDatabase); + mAllCustomThemes = customThemeRepository.getAllCustomThemes(); + mCurrentLightTheme = customThemeRepository.getCurrentLightCustomTheme(); + mCurrentDarkTheme = customThemeRepository.getCurrentDarkCustomTheme(); + mCurrentAmoledTheme = customThemeRepository.getCurrentAmoledCustomTheme(); + } + + public LiveData> getAllCustomThemes() { + return mAllCustomThemes; + } + + public LiveData getCurrentLightThemeLiveData() { + return mCurrentLightTheme; + } + + public LiveData getCurrentDarkThemeLiveData() { + return mCurrentDarkTheme; + } + + public LiveData getCurrentAmoledThemeLiveData() { + return mCurrentAmoledTheme; + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private RedditDataRoomDatabase mRedditDataRoomDatabase; + + public Factory(RedditDataRoomDatabase redditDataRoomDatabase) { + mRedditDataRoomDatabase = redditDataRoomDatabase; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new CustomThemeViewModel(mRedditDataRoomDatabase); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java new file mode 100644 index 00000000..8621559f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customtheme/CustomThemeWrapper.java @@ -0,0 +1,1427 @@ +package ml.docilealligator.infinityforreddit.customtheme; + +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Color; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; + +import static ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils.AMOLED; +import static ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils.DARK; + +public class CustomThemeWrapper { + private SharedPreferences lightThemeSharedPreferences; + private SharedPreferences darkThemeSharedPreferences; + private SharedPreferences amoledThemeSharedPreferences; + private int themeType; + + public CustomThemeWrapper(SharedPreferences lightThemeSharedPreferences, + SharedPreferences darkThemeSharedPreferences, + SharedPreferences amoledThemeSharedPreferences) { + this.lightThemeSharedPreferences = lightThemeSharedPreferences; + this.darkThemeSharedPreferences = darkThemeSharedPreferences; + this.amoledThemeSharedPreferences = amoledThemeSharedPreferences; + } + + private SharedPreferences getThemeSharedPreferences() { + switch (themeType) { + case DARK: + return darkThemeSharedPreferences; + case AMOLED: + return amoledThemeSharedPreferences; + default: + return lightThemeSharedPreferences; + } + } + + private int getDefaultColor(String normalHex, String darkHex, String amoledDarkHex) { + switch (themeType) { + case DARK: + return Color.parseColor(darkHex); + case AMOLED: + return Color.parseColor(amoledDarkHex); + default: + return Color.parseColor(normalHex); + } + } + + public void setThemeType(int themeType) { + this.themeType = themeType; + } + + public int getColorPrimary() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY, + getDefaultColor("#1565C0", "#242424", "#000000")); + } + + public int getColorPrimaryDark() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_DARK, + getDefaultColor("#0D47A1", "#121212", "#000000")); + } + + public int getColorAccent() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_ACCENT, + getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + } + + public int getColorPrimaryLightTheme() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COLOR_PRIMARY_LIGHT_THEME, + getDefaultColor("#1565C0", "#1565C0", "#1565C0")); + } + + public int getPrimaryTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.PRIMARY_TEXT_COLOR, + getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); + } + + public int getSecondaryTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SECONDARY_TEXT_COLOR, + getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); + } + + public int getPostTitleColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_TITLE_COLOR, + getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); + } + + public int getPostContentColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_CONTENT_COLOR, + getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); + } + + public int getCommentColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_COLOR, + getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); + } + + public int getButtonTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BUTTON_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BACKGROUND_COLOR, + getDefaultColor("#FFFFFF", "#121212", "#000000")); + } + + public int getCardViewBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CARD_VIEW_BACKGROUND_COLOR, + getDefaultColor("#FFFFFF", "#242424", "#000000")); + } + + public int getCommentBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_BACKGROUND_COLOR, + getDefaultColor("#FFFFFF", "#242424", "#000000")); + } + + public int getBottomAppBarBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_BACKGROUND_COLOR, + getDefaultColor("#FFFFFF", "#121212", "#000000")); + } + + public int getPrimaryIconColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.PRIMARY_ICON_COLOR, + getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); + } + + public int getBottomAppBarIconColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.BOTTOM_APP_BAR_ICON_COLOR, + getDefaultColor("#000000", "#FFFFFF", "#FFFFFF")); + } + + public int getPostIconAndInfoColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_ICON_AND_INFO_COLOR, + getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); + } + + public int getCommentIconAndInfoColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_ICON_AND_INFO_COLOR, + getDefaultColor("#8A000000", "#B3FFFFFF", "#B3FFFFFF")); + } + + public int getToolbarPrimaryTextAndIconColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getToolbarSecondaryTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TOOLBAR_SECONDARY_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getCircularProgressBarBackground() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CIRCULAR_PROGRESS_BAR_BACKGROUND, + getDefaultColor("#FFFFFF", "#242424", "#000000")); + } + + public int getTabLayoutWithExpandedCollapsingToolbarTabBackground() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, + getDefaultColor("#FFFFFF", "#242424", "#000000")); + } + + public int getTabLayoutWithExpandedCollapsingToolbarTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR, + getDefaultColor("#1565C0", "#FFFFFF", "#FFFFFF")); + } + + public int getTabLayoutWithExpandedCollapsingToolbarTabIndicator() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR, + getDefaultColor("#1565C0", "#FFFFFF", "#FFFFFF")); + } + + public int getTabLayoutWithCollapsedCollapsingToolbarTabBackground() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, + getDefaultColor("#1565C0", "#242424", "#000000")); + } + + public int getTabLayoutWithCollapsedCollapsingToolbarTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getTabLayoutWithCollapsedCollapsingToolbarTabIndicator() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getUpvoted() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UPVOTED, + getDefaultColor("#E91E63", "#E91E63", "#E91E63")); + } + + public int getDownvoted() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.DOWNVOTED, + getDefaultColor("#007DDE", "#007DDE", "#007DDE")); + } + + public int getPostTypeBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_TYPE_BACKGROUND_COLOR, + getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); + } + + public int getPostTypeTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.POST_TYPE_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getSpoilerBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SPOILER_BACKGROUND_COLOR, + getDefaultColor("#EE02EB", "#EE02EB", "#EE02EB")); + } + + public int getSpoilerTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SPOILER_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getNsfwBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NSFW_BACKGROUND_COLOR, + getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + } + + public int getNsfwTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NSFW_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getFlairBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FLAIR_BACKGROUND_COLOR, + getDefaultColor("#00AA8C", "#00AA8C", "#00AA8C")); + } + + public int getFlairTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FLAIR_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getAwardsBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AWARDS_BACKGROUND_COLOR, + getDefaultColor("#EEAB02", "#EEAB02", "#EEAB02")); + } + + public int getAwardsTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AWARDS_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getArchivedIconTint() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.ARCHIVED_ICON_TINT, + getDefaultColor("#B4009F", "#B4009F", "#B4009F")); + } + + public int getLockedIconTint() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.LOCKED_ICON_TINT, + getDefaultColor("#EE7302", "#EE7302", "#EE7302")); + } + + public int getCrosspostIconTint() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CROSSPOST_ICON_TINT, + getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + } + + public int getStickiedPostIconTint() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.STICKIED_POST_ICON_TINT, + getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); + } + + public int getNoPreviewPostTypeIconTint() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NO_PREVIEW_POST_TYPE_ICON_TINT, + getDefaultColor("#808080", "#808080", "#808080")); + } + + public int getSubscribed() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBSCRIBED, + getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + } + + public int getUnsubscribed() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UNSUBSCRIBED, + getDefaultColor("#0D47A1", "#1565C0", "#1565C0")); + } + + public int getUsername() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.USERNAME, + getDefaultColor("#0D47A1", "#1E88E5", "#1E88E5")); + } + + public int getSubreddit() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBREDDIT, + getDefaultColor("#E91E63", "#E91E63", "#E91E63")); + } + + public int getAuthorFlairTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AUTHOR_FLAIR_TEXT_COLOR, + getDefaultColor("#EE02C4", "#EE02C4", "#EE02C4")); + } + + public int getSubmitter() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SUBMITTER, + getDefaultColor("#EE8A02", "#EE8A02", "#EE8A02")); + } + + public int getModerator() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.MODERATOR, + getDefaultColor("#00BA81", "#00BA81", "#00BA81")); + } + + public int getSingleCommentThreadBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SINGLE_COMMENT_THREAD_BACKGROUND_COLOR, + getDefaultColor("#B3E5F9", "#123E77", "#123E77")); + } + + public int getUnreadMessageBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.UNREAD_MESSAGE_BACKGROUND_COLOR, + getDefaultColor("#B3E5F9", "#123E77", "#123E77")); + } + + public int getDividerColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.DIVIDER_COLOR, + getDefaultColor("#E0E0E0", "#69666C", "#69666C")); + } + + public int getNoPreviewPostTypeBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NO_PREVIEW_POST_TYPE_BACKGROUND_COLOR, + getDefaultColor("#E0E0E0", "#424242", "#424242")); + } + + public int getVoteAndReplyUnavailableButtonColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.VOTE_AND_REPLY_UNAVAILABLE_BUTTON_COLOR, + getDefaultColor("#F0F0F0", "#3C3C3C", "#3C3C3C")); + } + + public int getCommentVerticalBarColor1() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_1, + getDefaultColor("#1565C0", "#1565C0", "#1565C0")); + } + + public int getCommentVerticalBarColor2() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_2, + getDefaultColor("#EE02BE", "#C300B3", "#C300B3")); + } + + public int getCommentVerticalBarColor3() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_3, + getDefaultColor("#02DFEE", "#00B8DA", "#00B8DA")); + } + + public int getCommentVerticalBarColor4() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_4, + getDefaultColor("#EED502", "#EDCA00", "#EDCA00")); + } + + public int getCommentVerticalBarColor5() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_5, + getDefaultColor("#EE0220", "#EE0219", "#EE0219")); + } + + public int getCommentVerticalBarColor6() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_6, + getDefaultColor("#02EE6E", "#00B925", "#00B925")); + } + + public int getCommentVerticalBarColor7() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.COMMENT_VERTICAL_BAR_COLOR_7, + getDefaultColor("#EE4602", "#EE4602", "#EE4602")); + } + + public int getFABIconColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FAB_ICON_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getChipTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.CHIP_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getLinkColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.LINK_COLOR, + getDefaultColor("#FF4081", "#FF4081", "#FF4081")); + } + + public int getReceivedMessageTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.RECEIVED_MESSAGE_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getSentMessageTextColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SENT_MESSAGE_TEXT_COLOR, + getDefaultColor("#FFFFFF", "#FFFFFF", "#FFFFFF")); + } + + public int getReceivedMessageBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.RECEIVED_MESSAGE_BACKROUND_COLOR, + getDefaultColor("#4185F4", "#4185F4", "#4185F4")); + } + + public int getSentMessageBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SENT_MESSAGE_BACKGROUND_COLOR, + getDefaultColor("#31BF7D", "#31BF7D", "#31BF7D")); + } + + public int getSendMessageIconColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.SEND_MESSAGE_ICON_COLOR, + getDefaultColor("#4185F4", "#4185F4", "#4185F4")); + } + + public int getFullyCollapsedCommentBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.FULLY_COLLAPSED_COMMENT_BACKGROUND_COLOR, + getDefaultColor("#8EDFBA", "#21C561", "#21C561")); + } + + public int getAwardedCommentBackgroundColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.AWARDED_COMMENT_BACKGROUND_COLOR, + getDefaultColor("#FFFFFF", "#242424", "#000000")); + } + + public int getNavBarColor() { + return getThemeSharedPreferences().getInt(CustomThemeSharedPreferencesUtils.NAV_BAR_COLOR, + getDefaultColor("#FFFFFF", "#121212", "#000000")); + } + + public boolean isLightStatusBar() { + return getThemeSharedPreferences().getBoolean(CustomThemeSharedPreferencesUtils.LIGHT_STATUS_BAR, false); + } + + public boolean isLightNavBar() { + return getThemeSharedPreferences().getBoolean(CustomThemeSharedPreferencesUtils.LIGHT_NAV_BAR, + themeType == CustomThemeSharedPreferencesUtils.LIGHT); + } + + public boolean isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface() { + return getThemeSharedPreferences().getBoolean( + CustomThemeSharedPreferencesUtils.CHANGE_STATUS_BAR_ICON_COLOR_AFTER_TOOLBAR_COLLAPSED_IN_IMMERSIVE_INTERFACE, + themeType == CustomThemeSharedPreferencesUtils.LIGHT); + } + + public static CustomTheme getPredefinedCustomTheme(Context context, String name) { + if (name.equals(context.getString(R.string.theme_name_indigo_dark))) { + return getIndigoDark(context); + } else if (name.equals(context.getString(R.string.theme_name_indigo_amoled))) { + return getIndigoAmoled(context); + } else if (name.equals(context.getString(R.string.theme_name_white))) { + return getWhite(context); + } else if (name.equals(context.getString(R.string.theme_name_white_dark))) { + return getWhiteDark(context); + } else if (name.equals(context.getString(R.string.theme_name_white_amoled))) { + return getWhiteAmoled(context); + } else if (name.equals(context.getString(R.string.theme_name_red))) { + return getRed(context); + } else if (name.equals(context.getString(R.string.theme_name_red_dark))) { + return getRedDark(context); + } else if (name.equals(context.getString(R.string.theme_name_red_amoled))) { + return getRedAmoled(context); + } else if (name.equals(context.getString(R.string.theme_name_dracula))) { + return getDracula(context); + } else if (name.equals(context.getString(R.string.theme_name_calm_pastel))) { + return getCalmPastel(context); + } else { + return getIndigo(context); + } + } + + public static ArrayList getPredefinedThemes(Context context) { + ArrayList customThemes = new ArrayList<>(); + customThemes.add(getIndigo(context)); + customThemes.add(getIndigoDark(context)); + customThemes.add(getIndigoAmoled(context)); + customThemes.add(getWhite(context)); + customThemes.add(getWhiteDark(context)); + customThemes.add(getWhiteAmoled(context)); + customThemes.add(getRed(context)); + customThemes.add(getRedDark(context)); + customThemes.add(getRedAmoled(context)); + customThemes.add(getDracula(context)); + customThemes.add(getCalmPastel(context)); + return customThemes; + } + + public static CustomTheme getIndigo(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_indigo)); + customTheme.isLightTheme = true; + customTheme.isDarkTheme = false; + customTheme.isAmoledTheme = false; + customTheme.colorPrimary = Color.parseColor("#1565C0"); + customTheme.colorPrimaryDark = Color.parseColor("#0D47A1"); + customTheme.colorAccent = Color.parseColor("#FF4081"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); + customTheme.primaryTextColor = Color.parseColor("#000000"); + customTheme.secondaryTextColor = Color.parseColor("#8A000000"); + customTheme.postTitleColor = Color.parseColor("#000000"); + customTheme.postContentColor = Color.parseColor("#8A000000"); + customTheme.commentColor = Color.parseColor("#000000"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#FFFFFF"); + customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.primaryIconColor = Color.parseColor("#000000"); + customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); + customTheme.postIconAndInfoColor = Color.parseColor("#8A000000"); + customTheme.commentIconAndInfoColor = Color.parseColor("#8A000000"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#1565C0"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#1565C0"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#1565C0"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#0D47A1"); + customTheme.username = Color.parseColor("#0D47A1"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#B3E5F9"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#B3E5F9"); + customTheme.dividerColor = Color.parseColor("#E0E0E0"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.navBarColor = Color.parseColor("#FFFFFF"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = true; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = true; + + return customTheme; + } + + public static CustomTheme getIndigoDark(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_indigo_dark)); + customTheme.isLightTheme = false; + customTheme.isDarkTheme = true; + customTheme.isAmoledTheme = false; + customTheme.colorPrimary = Color.parseColor("#242424"); + customTheme.colorPrimaryDark = Color.parseColor("#121212"); + customTheme.colorAccent = Color.parseColor("#FF4081"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); + customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); + customTheme.postTitleColor = Color.parseColor("#FFFFFF"); + customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentColor = Color.parseColor("#FFFFFF"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#121212"); + customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); + customTheme.commentBackgroundColor = Color.parseColor("#242424"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); + customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); + customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.username = Color.parseColor("#1E88E5"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); + customTheme.dividerColor = Color.parseColor("#69666C"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#242424"); + customTheme.navBarColor = Color.parseColor("#121212"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = false; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + public static CustomTheme getIndigoAmoled(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_indigo_amoled)); + customTheme.isLightTheme = false; + customTheme.isDarkTheme = false; + customTheme.isAmoledTheme = true; + customTheme.colorPrimary = Color.parseColor("#000000"); + customTheme.colorPrimaryDark = Color.parseColor("#000000"); + customTheme.colorAccent = Color.parseColor("#FF4081"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#1565C0"); + customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); + customTheme.postTitleColor = Color.parseColor("#FFFFFF"); + customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentColor = Color.parseColor("#FFFFFF"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#000000"); + customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.commentBackgroundColor = Color.parseColor("#000000"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); + customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); + customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.username = Color.parseColor("#1E88E5"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); + customTheme.dividerColor = Color.parseColor("#69666C"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#000000"); + customTheme.navBarColor = Color.parseColor("#000000"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = false; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + private static CustomTheme getWhite(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_white)); + customTheme.isLightTheme = true; + customTheme.isDarkTheme = false; + customTheme.isAmoledTheme = false; + customTheme.colorPrimary = Color.parseColor("#FFFFFF"); + customTheme.colorPrimaryDark = Color.parseColor("#FFFFFF"); + customTheme.colorAccent = Color.parseColor("#000000"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#FFFFFF"); + customTheme.primaryTextColor = Color.parseColor("#000000"); + customTheme.secondaryTextColor = Color.parseColor("#8A000000"); + customTheme.postTitleColor = Color.parseColor("#000000"); + customTheme.postContentColor = Color.parseColor("#8A000000"); + customTheme.commentColor = Color.parseColor("#000000"); + customTheme.buttonTextColor = Color.parseColor("#000000"); + customTheme.backgroundColor = Color.parseColor("#FFFFFF"); + customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.primaryIconColor = Color.parseColor("#000000"); + customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); + customTheme.postIconAndInfoColor = Color.parseColor("#3C4043"); + customTheme.commentIconAndInfoColor = Color.parseColor("#3C4043"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#3C4043"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#3C4043"); + customTheme.circularProgressBarBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#0D47A1"); + customTheme.username = Color.parseColor("#0D47A1"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#B3E5F9"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#B3E5F9"); + customTheme.dividerColor = Color.parseColor("#E0E0E0"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#000000"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.navBarColor = Color.parseColor("#FFFFFF"); + customTheme.isLightStatusBar = true; + customTheme.isLightNavBar = true; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + private static CustomTheme getWhiteDark(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_white_dark)); + customTheme.isLightTheme = false; + customTheme.isDarkTheme = true; + customTheme.isAmoledTheme = false; + customTheme.colorPrimary = Color.parseColor("#242424"); + customTheme.colorPrimaryDark = Color.parseColor("#121212"); + customTheme.colorAccent = Color.parseColor("#FFFFFF"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#121212"); + customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); + customTheme.postTitleColor = Color.parseColor("#FFFFFF"); + customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentColor = Color.parseColor("#FFFFFF"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#121212"); + customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); + customTheme.commentBackgroundColor = Color.parseColor("#242424"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); + customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); + customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.username = Color.parseColor("#1E88E5"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); + customTheme.dividerColor = Color.parseColor("#69666C"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#242424"); + customTheme.navBarColor = Color.parseColor("#121212"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = false; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + private static CustomTheme getWhiteAmoled(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_white_amoled)); + customTheme.isLightTheme = false; + customTheme.isDarkTheme = false; + customTheme.isAmoledTheme = true; + customTheme.colorPrimary = Color.parseColor("#000000"); + customTheme.colorPrimaryDark = Color.parseColor("#000000"); + customTheme.colorAccent = Color.parseColor("#FFFFFF"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#000000"); + customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); + customTheme.postTitleColor = Color.parseColor("#FFFFFF"); + customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentColor = Color.parseColor("#FFFFFF"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#000000"); + customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.commentBackgroundColor = Color.parseColor("#000000"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); + customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); + customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.username = Color.parseColor("#1E88E5"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); + customTheme.dividerColor = Color.parseColor("#69666C"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#000000"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#000000"); + customTheme.navBarColor = Color.parseColor("#000000"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = false; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + private static CustomTheme getRed(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_red)); + customTheme.isLightTheme = true; + customTheme.isDarkTheme = false; + customTheme.isAmoledTheme = false; + customTheme.colorPrimary = Color.parseColor("#EE0270"); + customTheme.colorPrimaryDark = Color.parseColor("#C60466"); + customTheme.colorAccent = Color.parseColor("#02EE80"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#EE0270"); + customTheme.primaryTextColor = Color.parseColor("#000000"); + customTheme.secondaryTextColor = Color.parseColor("#8A000000"); + customTheme.postTitleColor = Color.parseColor("#000000"); + customTheme.postContentColor = Color.parseColor("#8A000000"); + customTheme.commentColor = Color.parseColor("#000000"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#FFFFFF"); + customTheme.cardViewBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.commentBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.primaryIconColor = Color.parseColor("#000000"); + customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); + customTheme.postIconAndInfoColor = Color.parseColor("#8A000000"); + customTheme.commentIconAndInfoColor = Color.parseColor("#8A000000"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#EE0270"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#EE0270"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#EE0270"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#0D47A1"); + customTheme.username = Color.parseColor("#0D47A1"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#B3E5F9"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#B3E5F9"); + customTheme.dividerColor = Color.parseColor("#E0E0E0"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#FFFFFF"); + customTheme.navBarColor = Color.parseColor("#FFFFFF"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = true; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = true; + + return customTheme; + } + + private static CustomTheme getRedDark(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_red_dark)); + customTheme.isLightTheme = false; + customTheme.isDarkTheme = true; + customTheme.isAmoledTheme = false; + customTheme.colorPrimary = Color.parseColor("#242424"); + customTheme.colorPrimaryDark = Color.parseColor("#121212"); + customTheme.colorAccent = Color.parseColor("#02EE80"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#EE0270"); + customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); + customTheme.postTitleColor = Color.parseColor("#FFFFFF"); + customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentColor = Color.parseColor("#FFFFFF"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#121212"); + customTheme.cardViewBackgroundColor = Color.parseColor("#242424"); + customTheme.commentBackgroundColor = Color.parseColor("#242424"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#121212"); + customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); + customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#242424"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.username = Color.parseColor("#1E88E5"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); + customTheme.dividerColor = Color.parseColor("#69666C"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#242424"); + customTheme.navBarColor = Color.parseColor("#121212"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = false; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + private static CustomTheme getRedAmoled(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_red_amoled)); + customTheme.isLightTheme = false; + customTheme.isDarkTheme = false; + customTheme.isAmoledTheme = true; + customTheme.colorPrimary = Color.parseColor("#000000"); + customTheme.colorPrimaryDark = Color.parseColor("#000000"); + customTheme.colorAccent = Color.parseColor("#02EE80"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#EE0270"); + customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); + customTheme.postTitleColor = Color.parseColor("#FFFFFF"); + customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentColor = Color.parseColor("#FFFFFF"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#000000"); + customTheme.cardViewBackgroundColor = Color.parseColor("#000000"); + customTheme.commentBackgroundColor = Color.parseColor("#000000"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#000000"); + customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); + customTheme.postIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentIconAndInfoColor = Color.parseColor("#B3FFFFFF"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#000000"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#1565C0"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#1565C0"); + customTheme.username = Color.parseColor("#1E88E5"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#123E77"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#123E77"); + customTheme.dividerColor = Color.parseColor("#69666C"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#424242"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#3C3C3C"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#C300B3"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#00B8DA"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EDCA00"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0219"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#00B925"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#000000"); + customTheme.navBarColor = Color.parseColor("#000000"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = false; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + private static CustomTheme getDracula(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_dracula)); + customTheme.isLightTheme = true; + customTheme.isDarkTheme = true; + customTheme.isAmoledTheme = true; + customTheme.colorPrimary = Color.parseColor("#393A59"); + customTheme.colorPrimaryDark = Color.parseColor("#393A59"); + customTheme.colorAccent = Color.parseColor("#F8F8F2"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#393A59"); + customTheme.primaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.secondaryTextColor = Color.parseColor("#B3FFFFFF"); + customTheme.postTitleColor = Color.parseColor("#FFFFFF"); + customTheme.postContentColor = Color.parseColor("#B3FFFFFF"); + customTheme.commentColor = Color.parseColor("#FFFFFF"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#282A36"); + customTheme.cardViewBackgroundColor = Color.parseColor("#393A59"); + customTheme.commentBackgroundColor = Color.parseColor("#393A59"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#393A59"); + customTheme.primaryIconColor = Color.parseColor("#FFFFFF"); + customTheme.bottomAppBarIconColor = Color.parseColor("#FFFFFF"); + customTheme.postIconAndInfoColor = Color.parseColor("#FFFFFF"); + customTheme.commentIconAndInfoColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#FFFFFF"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#FFFFFF"); + customTheme.circularProgressBarBackground = Color.parseColor("#393A59"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#393A59"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#393A59"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#FFFFFF"); + customTheme.upvoted = Color.parseColor("#FF008C"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#1565C0"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#FFFFFF"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#0D47A1"); + customTheme.username = Color.parseColor("#1E88E5"); + customTheme.subreddit = Color.parseColor("#FF4B9C"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#5F5B85"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#5F5B85"); + customTheme.dividerColor = Color.parseColor("#69666C"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#6272A4"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#777C82"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#8BE9FD"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#50FA7B"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#FFB86C"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#FF79C6"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#BD93F9"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#FF5555"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#F1FA8C"); + customTheme.fabIconColor = Color.parseColor("#FFFFFF"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#21C561"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#393A59"); + customTheme.navBarColor = Color.parseColor("#393A59"); + customTheme.isLightStatusBar = false; + customTheme.isLightNavBar = false; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } + + private static CustomTheme getCalmPastel(Context context) { + CustomTheme customTheme = new CustomTheme(context.getString(R.string.theme_name_calm_pastel)); + customTheme.isLightTheme = true; + customTheme.isDarkTheme = false; + customTheme.isAmoledTheme = false; + customTheme.colorPrimary = Color.parseColor("#D48AE0"); + customTheme.colorPrimaryDark = Color.parseColor("#D476E0"); + customTheme.colorAccent = Color.parseColor("#775EFF"); + customTheme.colorPrimaryLightTheme = Color.parseColor("#D48AE0"); + customTheme.primaryTextColor = Color.parseColor("#000000"); + customTheme.secondaryTextColor = Color.parseColor("#8A000000"); + customTheme.postTitleColor = Color.parseColor("#000000"); + customTheme.postContentColor = Color.parseColor("#8A000000"); + customTheme.commentColor = Color.parseColor("#000000"); + customTheme.buttonTextColor = Color.parseColor("#FFFFFF"); + customTheme.backgroundColor = Color.parseColor("#DAD0DE"); + customTheme.cardViewBackgroundColor = Color.parseColor("#C0F0F4"); + customTheme.commentBackgroundColor = Color.parseColor("#C0F0F4"); + customTheme.bottomAppBarBackgroundColor = Color.parseColor("#D48AE0"); + customTheme.primaryIconColor = Color.parseColor("#000000"); + customTheme.bottomAppBarIconColor = Color.parseColor("#000000"); + customTheme.postIconAndInfoColor = Color.parseColor("#000000"); + customTheme.commentIconAndInfoColor = Color.parseColor("#000000"); + customTheme.toolbarPrimaryTextAndIconColor = Color.parseColor("#3C4043"); + customTheme.toolbarSecondaryTextColor = Color.parseColor("#3C4043"); + customTheme.circularProgressBarBackground = Color.parseColor("#D48AE0"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground = Color.parseColor("#FFFFFF"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor = Color.parseColor("#D48AE0"); + customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator = Color.parseColor("#D48AE0"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground = Color.parseColor("#D48AE0"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor = Color.parseColor("#3C4043"); + customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator = Color.parseColor("#3C4043"); + customTheme.upvoted = Color.parseColor("#E91E63"); + customTheme.downvoted = Color.parseColor("#007DDE"); + customTheme.postTypeBackgroundColor = Color.parseColor("#0D47A1"); + customTheme.postTypeTextColor = Color.parseColor("#FFFFFF"); + customTheme.spoilerBackgroundColor = Color.parseColor("#EE02EB"); + customTheme.spoilerTextColor = Color.parseColor("#FFFFFF"); + customTheme.nsfwBackgroundColor = Color.parseColor("#FF4081"); + customTheme.nsfwTextColor = Color.parseColor("#FFFFFF"); + customTheme.flairBackgroundColor = Color.parseColor("#00AA8C"); + customTheme.flairTextColor = Color.parseColor("#FFFFFF"); + customTheme.awardsBackgroundColor = Color.parseColor("#EEAB02"); + customTheme.awardsTextColor = Color.parseColor("#FFFFFF"); + customTheme.archivedTint = Color.parseColor("#B4009F"); + customTheme.lockedIconTint = Color.parseColor("#EE7302"); + customTheme.crosspostIconTint = Color.parseColor("#FF4081"); + customTheme.stickiedPostIconTint = Color.parseColor("#0D47A1"); + customTheme.noPreviewPostTypeIconTint = Color.parseColor("#808080"); + customTheme.subscribed = Color.parseColor("#FF4081"); + customTheme.unsubscribed = Color.parseColor("#0D47A1"); + customTheme.username = Color.parseColor("#0D47A1"); + customTheme.subreddit = Color.parseColor("#E91E63"); + customTheme.authorFlairTextColor = Color.parseColor("#EE02C4"); + customTheme.submitter = Color.parseColor("#EE8A02"); + customTheme.moderator = Color.parseColor("#00BA81"); + customTheme.singleCommentThreadBackgroundColor = Color.parseColor("#25D5E5"); + customTheme.unreadMessageBackgroundColor = Color.parseColor("#25D5E5"); + customTheme.dividerColor = Color.parseColor("#E0E0E0"); + customTheme.noPreviewPostTypeBackgroundColor = Color.parseColor("#E0E0E0"); + customTheme.voteAndReplyUnavailableButtonColor = Color.parseColor("#F0F0F0"); + customTheme.commentVerticalBarColor1 = Color.parseColor("#1565C0"); + customTheme.commentVerticalBarColor2 = Color.parseColor("#EE02BE"); + customTheme.commentVerticalBarColor3 = Color.parseColor("#02DFEE"); + customTheme.commentVerticalBarColor4 = Color.parseColor("#EED502"); + customTheme.commentVerticalBarColor5 = Color.parseColor("#EE0220"); + customTheme.commentVerticalBarColor6 = Color.parseColor("#02EE6E"); + customTheme.commentVerticalBarColor7 = Color.parseColor("#EE4602"); + customTheme.fabIconColor = Color.parseColor("#000000"); + customTheme.chipTextColor = Color.parseColor("#FFFFFF"); + customTheme.linkColor = Color.parseColor("#FF4081"); + customTheme.receivedMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.sentMessageTextColor = Color.parseColor("#FFFFFF"); + customTheme.receivedMessageBackgroundColor = Color.parseColor("#4185F4"); + customTheme.sentMessageBackgroundColor = Color.parseColor("#31BF7D"); + customTheme.sendMessageIconColor = Color.parseColor("#4185F4"); + customTheme.fullyCollapsedCommentBackgroundColor = Color.parseColor("#8EDFBA"); + customTheme.awardedCommentBackgroundColor = Color.parseColor("#C0F0F4"); + customTheme.navBarColor = Color.parseColor("#D48AE0"); + customTheme.isLightStatusBar = true; + customTheme.isLightNavBar = true; + customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface = false; + + return customTheme; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioBigImageView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioBigImageView.java new file mode 100644 index 00000000..d001faa3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioBigImageView.java @@ -0,0 +1,60 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; + +import com.github.piasy.biv.view.BigImageView; + +public class AspectRatioBigImageView extends BigImageView { + private float ratio; + + public AspectRatioBigImageView(Context context) { + super(context); + ratio = 1.0F; + } + + public AspectRatioBigImageView(Context context, AttributeSet attrs) { + super(context, attrs); + this.ratio = 1.0F; + this.init(context, attrs); + } + + public AspectRatioBigImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + this.ratio = 1.0F; + this.init(context, attrs); + } + + public final float getRatio() { + return this.ratio; + } + + public final void setRatio(float var1) { + this.ratio = var1; + } + + private void init(Context context, AttributeSet attrs) { + if (attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView); + this.ratio = a.getFloat(com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView_ari_ratio, 1.0F); + a.recycle(); + } + + } + + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int width = this.getMeasuredWidth(); + int height = this.getMeasuredHeight(); + if (width != 0 || height != 0) { + if (width > 0) { + height = (int) ((float) width * this.ratio); + } else { + width = (int) ((float) height / this.ratio); + } + + this.setMeasuredDimension(width, height); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioGifImageView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioGifImageView.java new file mode 100644 index 00000000..bd735f90 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioGifImageView.java @@ -0,0 +1,54 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; + +import pl.droidsonroids.gif.GifImageView; + +public class AspectRatioGifImageView extends GifImageView { + private float ratio; + + public AspectRatioGifImageView(Context context) { + super(context); + this.ratio = 1.0F; + } + + public AspectRatioGifImageView(Context context, AttributeSet attrs) { + super(context, attrs); + this.ratio = 1.0F; + this.init(context, attrs); + } + + public final float getRatio() { + return this.ratio; + } + + public final void setRatio(float var1) { + this.ratio = var1; + } + + private void init(Context context, AttributeSet attrs) { + if (attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView); + this.ratio = a.getFloat(com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView_ari_ratio, 1.0F); + a.recycle(); + } + + } + + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int width = this.getMeasuredWidth(); + int height = this.getMeasuredHeight(); + if (width != 0 || height != 0) { + if (width > 0) { + height = (int) ((float) width * this.ratio); + } else { + width = (int) ((float) height / this.ratio); + } + + this.setMeasuredDimension(width, height); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioSubsamplingScaleImageView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioSubsamplingScaleImageView.java new file mode 100644 index 00000000..dffdb9af --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/AspectRatioSubsamplingScaleImageView.java @@ -0,0 +1,54 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; + +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; + +public class AspectRatioSubsamplingScaleImageView extends SubsamplingScaleImageView { + private float ratio; + + public AspectRatioSubsamplingScaleImageView(Context context) { + super(context); + ratio = 1.0F; + } + + public AspectRatioSubsamplingScaleImageView(Context context, AttributeSet attr) { + super(context, attr); + this.ratio = 1.0F; + this.init(context, attr); + } + + public final float getRatio() { + return this.ratio; + } + + public final void setRatio(float var1) { + this.ratio = var1; + } + + private void init(Context context, AttributeSet attrs) { + if (attrs != null) { + TypedArray a = context.obtainStyledAttributes(attrs, com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView); + this.ratio = a.getFloat(com.santalu.aspectratioimageview.R.styleable.AspectRatioImageView_ari_ratio, 1.0F); + a.recycle(); + } + + } + + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int width = this.getMeasuredWidth(); + int height = this.getMeasuredHeight(); + if (width != 0 || height != 0) { + if (width > 0) { + height = (int) ((float) width * this.ratio); + } else { + width = (int) ((float) height / this.ratio); + } + + this.setMeasuredDimension(width, height); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ColorPickerDialog.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ColorPickerDialog.java new file mode 100644 index 00000000..6c6428fe --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/ColorPickerDialog.java @@ -0,0 +1,153 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.graphics.Color; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.SeekBar; +import android.widget.Toast; + +import androidx.appcompat.app.AlertDialog; + +import ml.docilealligator.infinityforreddit.R; + +public class ColorPickerDialog extends AlertDialog { + private View colorView; + private EditText colorValueEditText; + private SeekBar seekBarA; + private SeekBar seekBarR; + private SeekBar seekBarG; + private SeekBar seekBarB; + private Button cancelButton; + private Button okButton; + private int colorValue; + private boolean changeColorValueEditText = true; + private ColorPickerListener colorPickerListener; + + public interface ColorPickerListener { + void onColorPicked(int color); + } + + public ColorPickerDialog(Context context, int color, ColorPickerListener colorPickerListener) { + super(context); + + View rootView = getLayoutInflater().inflate(R.layout.color_picker, null); + colorView = rootView.findViewById(R.id.color_view_color_picker); + colorValueEditText = rootView.findViewById(R.id.color_edit_text_color_picker); + seekBarA = rootView.findViewById(R.id.a_seek_bar_color_picker); + seekBarR = rootView.findViewById(R.id.r_seek_bar_color_picker); + seekBarG = rootView.findViewById(R.id.g_seek_bar_color_picker); + seekBarB = rootView.findViewById(R.id.b_seek_bar_color_picker); + cancelButton = rootView.findViewById(R.id.cancel_button_color_picker); + okButton = rootView.findViewById(R.id.ok_button_color_picker); + + colorView.setBackgroundColor(color); + colorValueEditText.setText(Integer.toHexString(color).toUpperCase()); + colorValueEditText.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { + + } + + @Override + public void afterTextChanged(Editable editable) { + String s = editable.toString(); + if (s.length() == 6) { + try { + changeColorValueEditText = false; + colorValue = Color.parseColor("#" + s); + colorView.setBackgroundColor(colorValue); + seekBarA.setProgress(255); + seekBarR.setProgress(Integer.parseInt(s.substring(0, 2), 16)); + seekBarG.setProgress(Integer.parseInt(s.substring(2, 4), 16)); + seekBarB.setProgress(Integer.parseInt(s.substring(4, 6), 16)); + changeColorValueEditText = true; + } catch (IllegalArgumentException ignored) { + + } + } else if (s.length() == 8) { + try { + changeColorValueEditText = false; + colorValue = Color.parseColor("#" + s); + colorView.setBackgroundColor(colorValue); + seekBarA.setProgress(Integer.parseInt(s.substring(0, 2), 16)); + seekBarR.setProgress(Integer.parseInt(s.substring(2, 4), 16)); + seekBarG.setProgress(Integer.parseInt(s.substring(4, 6), 16)); + seekBarB.setProgress(Integer.parseInt(s.substring(6, 8), 16)); + changeColorValueEditText = true; + } catch (IllegalArgumentException ignored) { + + } + } + } + }); + + String colorHex = Integer.toHexString(color); + if (colorHex.length() == 8) { + colorValue = Color.parseColor("#" + colorHex); + seekBarA.setProgress(Integer.parseInt(colorHex.substring(0, 2), 16)); + seekBarR.setProgress(Integer.parseInt(colorHex.substring(2, 4), 16)); + seekBarG.setProgress(Integer.parseInt(colorHex.substring(4, 6), 16)); + seekBarB.setProgress(Integer.parseInt(colorHex.substring(6, 8), 16)); + } else if (colorHex.length() == 6) { + colorValue = Color.parseColor("#" + colorHex); + seekBarA.setProgress(255); + seekBarR.setProgress(Integer.parseInt(colorHex.substring(0, 2), 16)); + seekBarG.setProgress(Integer.parseInt(colorHex.substring(2, 4), 16)); + seekBarB.setProgress(Integer.parseInt(colorHex.substring(4, 6), 16)); + } + setOnSeekBarChangeListener(seekBarA); + setOnSeekBarChangeListener(seekBarR); + setOnSeekBarChangeListener(seekBarG); + setOnSeekBarChangeListener(seekBarB); + + cancelButton.setOnClickListener(view -> dismiss()); + okButton.setOnClickListener(view -> { + try { + colorValue = Color.parseColor("#" + colorValueEditText.getText().toString()); + colorPickerListener.onColorPicked(colorValue); + dismiss(); + } catch (IllegalArgumentException e) { + Toast.makeText(context, R.string.invalid_color, Toast.LENGTH_SHORT).show(); + } + }); + + setView(rootView); + } + + private void setOnSeekBarChangeListener(SeekBar seekBar) { + seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int i, boolean b) { + if (changeColorValueEditText) { + int aValue = seekBarA.getProgress(); + int rValue = seekBarR.getProgress(); + int gValue = seekBarG.getProgress(); + int bValue = seekBarB.getProgress(); + String colorHex = String.format("%02x%02x%02x%02x", aValue, rValue, gValue, bValue).toUpperCase(); + colorValue = Color.parseColor("#" + colorHex); + colorView.setBackgroundColor(colorValue); + colorValueEditText.setText(colorHex); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CustomToroContainer.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CustomToroContainer.java new file mode 100644 index 00000000..3df8b083 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/CustomToroContainer.java @@ -0,0 +1,27 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.util.AttributeSet; + +import androidx.annotation.Nullable; + +import im.ene.toro.widget.Container; + +public class CustomToroContainer extends Container { + public CustomToroContainer(Context context) { + super(context); + } + + public CustomToroContainer(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + } + + public CustomToroContainer(Context context, @Nullable AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + public void onWindowVisibilityChanged(int visibility) { + super.onWindowVisibilityChanged(visibility); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LollipopBugFixedWebView.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LollipopBugFixedWebView.java new file mode 100644 index 00000000..6392902d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/LollipopBugFixedWebView.java @@ -0,0 +1,28 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.content.res.Configuration; +import android.os.Build; +import android.util.AttributeSet; +import android.webkit.WebView; + +public class LollipopBugFixedWebView extends WebView{ + public LollipopBugFixedWebView(Context context) { + super(getFixedContext(context)); + } + + public LollipopBugFixedWebView(Context context, AttributeSet attrs) { + super(getFixedContext(context), attrs); + } + + public LollipopBugFixedWebView(Context context, AttributeSet attrs, int defStyleAttr) { + super(getFixedContext(context), attrs, defStyleAttr); + } + + // To fix Android Lollipop WebView problem create a new configuration on that Android version only + private static Context getFixedContext(Context context) { + if (Build.VERSION.SDK_INT == 21 || Build.VERSION.SDK_INT == 22) // Android Lollipop 5.0 & 5.1 + return context.createConfigurationContext(new Configuration()); + return context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java new file mode 100644 index 00000000..a654b437 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/customviews/MarkwonLinearLayoutManager.java @@ -0,0 +1,42 @@ +package ml.docilealligator.infinityforreddit.customviews; + +import android.content.Context; +import android.view.View; +import android.view.ViewTreeObserver; +import android.widget.HorizontalScrollView; + +import androidx.recyclerview.widget.LinearLayoutManager; + +public class MarkwonLinearLayoutManager extends LinearLayoutManager { + public interface HorizontalScrollViewScrolledListener { + void onScrolledLeft(); + void onScrolledRight(); + } + + private HorizontalScrollViewScrolledListener horizontalScrollViewScrolledListener; + + public MarkwonLinearLayoutManager(Context context, HorizontalScrollViewScrolledListener horizontalScrollViewScrolledListener) { + super(context); + this.horizontalScrollViewScrolledListener = horizontalScrollViewScrolledListener; + } + + @Override + public void addView(View child) { + super.addView(child); + if (child instanceof HorizontalScrollView) { + child.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() { + private int x = 0; + @Override + public void onScrollChanged() { + if (child.getScrollX() < x) { + horizontalScrollViewScrolledListener.onScrolledLeft(); + } else { + horizontalScrollViewScrolledListener.onScrolledRight(); + } + + x = child.getScrollX(); + } + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeAutoplayNsfwVideosEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeAutoplayNsfwVideosEvent.java new file mode 100644 index 00000000..53f35bad --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeAutoplayNsfwVideosEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeAutoplayNsfwVideosEvent { + public boolean autoplayNsfwVideos; + + public ChangeAutoplayNsfwVideosEvent(boolean autoplayNsfwVideos) { + this.autoplayNsfwVideos = autoplayNsfwVideos; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java new file mode 100644 index 00000000..cb2a3ec2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeCompactLayoutToolbarHiddenByDefaultEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeCompactLayoutToolbarHiddenByDefaultEvent { + public boolean compactLayoutToolbarHiddenByDefault; + + public ChangeCompactLayoutToolbarHiddenByDefaultEvent(boolean compactLayoutToolbarHiddenByDefault) { + this.compactLayoutToolbarHiddenByDefault = compactLayoutToolbarHiddenByDefault; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeConfirmToExitEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeConfirmToExitEvent.java new file mode 100644 index 00000000..fbfc4ae3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeConfirmToExitEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeConfirmToExitEvent { + public boolean confirmToExit; + + public ChangeConfirmToExitEvent(boolean confirmToExit) { + this.confirmToExit = confirmToExit; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDataSavingModeEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDataSavingModeEvent.java new file mode 100644 index 00000000..3d77ecb5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDataSavingModeEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeDataSavingModeEvent { + public String dataSavingMode; + + public ChangeDataSavingModeEvent(String dataSavingMode) { + this.dataSavingMode = dataSavingMode; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDefaultPostLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDefaultPostLayoutEvent.java new file mode 100644 index 00000000..3b60d2e1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDefaultPostLayoutEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeDefaultPostLayoutEvent { + public int defaultPostLayout; + + public ChangeDefaultPostLayoutEvent(int defaultPostLayout) { + this.defaultPostLayout = defaultPostLayout; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableImagePreviewEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableImagePreviewEvent.java new file mode 100644 index 00000000..d167c7e0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableImagePreviewEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeDisableImagePreviewEvent { + public boolean disableImagePreview; + + public ChangeDisableImagePreviewEvent(boolean disableImagePreview) { + this.disableImagePreview = disableImagePreview; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableSwipingBetweenTabsEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableSwipingBetweenTabsEvent.java new file mode 100644 index 00000000..ad1da23b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeDisableSwipingBetweenTabsEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeDisableSwipingBetweenTabsEvent { + public boolean disableSwipingBetweenTabs; + + public ChangeDisableSwipingBetweenTabsEvent(boolean disableSwipingBetweenTabs) { + this.disableSwipingBetweenTabs = disableSwipingBetweenTabs; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeEnableSwipeActionSwitchEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeEnableSwipeActionSwitchEvent.java new file mode 100644 index 00000000..27a33440 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeEnableSwipeActionSwitchEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeEnableSwipeActionSwitchEvent { + public boolean enableSwipeAction; + + public ChangeEnableSwipeActionSwitchEvent(boolean enableSwipeAction) { + this.enableSwipeAction = enableSwipeAction; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLockBottomAppBarEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLockBottomAppBarEvent.java new file mode 100644 index 00000000..c960c68c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLockBottomAppBarEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeLockBottomAppBarEvent { + public boolean lockBottomAppBar; + + public ChangeLockBottomAppBarEvent(boolean lockBottomAppBar) { + this.lockBottomAppBar = lockBottomAppBar; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLongPressToHideToolbarInCompactLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLongPressToHideToolbarInCompactLayoutEvent.java new file mode 100644 index 00000000..2b14c0bc --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeLongPressToHideToolbarInCompactLayoutEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeLongPressToHideToolbarInCompactLayoutEvent { + public boolean longPressToHideToolbarInCompactLayout; + + public ChangeLongPressToHideToolbarInCompactLayoutEvent(boolean longPressToHideToolbarInCompactLayout) { + this.longPressToHideToolbarInCompactLayout = longPressToHideToolbarInCompactLayout; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteAutoplayingVideosEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteAutoplayingVideosEvent.java new file mode 100644 index 00000000..b13681e7 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteAutoplayingVideosEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeMuteAutoplayingVideosEvent { + public boolean muteAutoplayingVideos; + + public ChangeMuteAutoplayingVideosEvent(boolean muteAutoplayingVideos) { + this.muteAutoplayingVideos = muteAutoplayingVideos; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteNSFWVideoEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteNSFWVideoEvent.java new file mode 100644 index 00000000..78d98488 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeMuteNSFWVideoEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeMuteNSFWVideoEvent { + public boolean muteNSFWVideo; + + public ChangeMuteNSFWVideoEvent(boolean muteNSFWVideo) { + this.muteNSFWVideo = muteNSFWVideo; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWBlurEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWBlurEvent.java new file mode 100644 index 00000000..cc4f5987 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWBlurEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeNSFWBlurEvent { + public boolean needBlurNSFW; + + public ChangeNSFWBlurEvent(boolean needBlurNSFW) { + this.needBlurNSFW = needBlurNSFW; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWEvent.java new file mode 100644 index 00000000..f7042086 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNSFWEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeNSFWEvent { + public boolean nsfw; + + public ChangeNSFWEvent(boolean nsfw) { + this.nsfw = nsfw; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNetworkStatusEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNetworkStatusEvent.java new file mode 100644 index 00000000..5d9540e1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeNetworkStatusEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeNetworkStatusEvent { + public int connectedNetwork; + + public ChangeNetworkStatusEvent(int connectedNetwork) { + this.connectedNetwork = connectedNetwork; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangePostLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangePostLayoutEvent.java new file mode 100644 index 00000000..d414c01a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangePostLayoutEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangePostLayoutEvent { + public int postLayout; + + public ChangePostLayoutEvent(int postLayout) { + this.postLayout = postLayout; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeRequireAuthToAccountSectionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeRequireAuthToAccountSectionEvent.java new file mode 100644 index 00000000..a01e89bd --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeRequireAuthToAccountSectionEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeRequireAuthToAccountSectionEvent { + public boolean requireAuthToAccountSection; + + public ChangeRequireAuthToAccountSectionEvent(boolean requireAuthToAccountSection) { + this.requireAuthToAccountSection = requireAuthToAccountSection; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSavePostFeedScrolledPositionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSavePostFeedScrolledPositionEvent.java new file mode 100644 index 00000000..cc8cfdef --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSavePostFeedScrolledPositionEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeSavePostFeedScrolledPositionEvent { + public boolean savePostFeedScrolledPosition; + + public ChangeSavePostFeedScrolledPositionEvent(boolean savePostFeedScrolledPosition) { + this.savePostFeedScrolledPosition = savePostFeedScrolledPosition; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowAbsoluteNumberOfVotesEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowAbsoluteNumberOfVotesEvent.java new file mode 100644 index 00000000..1fb29aa4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowAbsoluteNumberOfVotesEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeShowAbsoluteNumberOfVotesEvent { + public boolean showAbsoluteNumberOfVotes; + + public ChangeShowAbsoluteNumberOfVotesEvent(boolean showAbsoluteNumberOfVotes) { + this.showAbsoluteNumberOfVotes = showAbsoluteNumberOfVotes; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowElapsedTimeEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowElapsedTimeEvent.java new file mode 100644 index 00000000..5e88e78d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeShowElapsedTimeEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeShowElapsedTimeEvent { + public boolean showElapsedTime; + + public ChangeShowElapsedTimeEvent(boolean showElapsedTime) { + this.showElapsedTime = showElapsedTime; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSpoilerBlurEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSpoilerBlurEvent.java new file mode 100644 index 00000000..92219f58 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSpoilerBlurEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeSpoilerBlurEvent { + public boolean needBlurSpoiler; + + public ChangeSpoilerBlurEvent(boolean needBlurSpoiler) { + this.needBlurSpoiler = needBlurSpoiler; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeStartAutoplayVisibleAreaOffsetEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeStartAutoplayVisibleAreaOffsetEvent.java new file mode 100644 index 00000000..1f4feb1c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeStartAutoplayVisibleAreaOffsetEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeStartAutoplayVisibleAreaOffsetEvent { + public double startAutoplayVisibleAreaOffset; + + public ChangeStartAutoplayVisibleAreaOffsetEvent(double startAutoplayVisibleAreaOffset) { + this.startAutoplayVisibleAreaOffset = startAutoplayVisibleAreaOffset; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionEvent.java new file mode 100644 index 00000000..fe3f8ef3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionEvent.java @@ -0,0 +1,11 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeSwipeActionEvent { + public int swipeLeftAction; + public int swipeRightAction; + + public ChangeSwipeActionEvent(int swipeLeftAction, int swipeRightAction) { + this.swipeLeftAction = swipeLeftAction; + this.swipeRightAction = swipeRightAction; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionThresholdEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionThresholdEvent.java new file mode 100644 index 00000000..355edc59 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeSwipeActionThresholdEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeSwipeActionThresholdEvent { + public float swipeActionThreshold; + + public ChangeSwipeActionThresholdEvent(float swipeActionThreshold) { + this.swipeActionThreshold = swipeActionThreshold; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeTimeFormatEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeTimeFormatEvent.java new file mode 100644 index 00000000..84a35326 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeTimeFormatEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeTimeFormatEvent { + public String timeFormat; + + public ChangeTimeFormatEvent(String timeFormat) { + this.timeFormat = timeFormat; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVibrateWhenActionTriggeredEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVibrateWhenActionTriggeredEvent.java new file mode 100644 index 00000000..5c1f9823 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVibrateWhenActionTriggeredEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeVibrateWhenActionTriggeredEvent { + public boolean vibrateWhenActionTriggered; + + public ChangeVibrateWhenActionTriggeredEvent(boolean vibrateWhenActionTriggered) { + this.vibrateWhenActionTriggered = vibrateWhenActionTriggered; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVideoAutoplayEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVideoAutoplayEvent.java new file mode 100644 index 00000000..aed729c6 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVideoAutoplayEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeVideoAutoplayEvent { + public String autoplay; + + public ChangeVideoAutoplayEvent(String autoplay) { + this.autoplay = autoplay; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVoteButtonsPositionEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVoteButtonsPositionEvent.java new file mode 100644 index 00000000..22bb9e9f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ChangeVoteButtonsPositionEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ChangeVoteButtonsPositionEvent { + public boolean voteButtonsOnTheRight; + + public ChangeVoteButtonsPositionEvent(boolean voteButtonsOnTheRight) { + this.voteButtonsOnTheRight = voteButtonsOnTheRight; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadMediaEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadMediaEvent.java new file mode 100644 index 00000000..6398cf5e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadMediaEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class DownloadMediaEvent { + public boolean isSuccessful; + + public DownloadMediaEvent(boolean isSuccessful) { + this.isSuccessful = isSuccessful; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadRedditVideoEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadRedditVideoEvent.java new file mode 100644 index 00000000..e6b1a9ca --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/DownloadRedditVideoEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class DownloadRedditVideoEvent { + public boolean isSuccessful; + + public DownloadRedditVideoEvent(boolean isSuccessful) { + this.isSuccessful = isSuccessful; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/GoBackToMainPageEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/GoBackToMainPageEvent.java new file mode 100644 index 00000000..cff195b3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/GoBackToMainPageEvent.java @@ -0,0 +1,4 @@ +package ml.docilealligator.infinityforreddit.events; + +public class GoBackToMainPageEvent { +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToDetailActivity.java new file mode 100644 index 00000000..e629ea2b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToDetailActivity.java @@ -0,0 +1,11 @@ +package ml.docilealligator.infinityforreddit.events; + +import ml.docilealligator.infinityforreddit.post.Post; + +public class PostUpdateEventToDetailActivity { + public final Post post; + + public PostUpdateEventToDetailActivity(Post post) { + this.post = post; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToPostList.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToPostList.java new file mode 100644 index 00000000..96f5e62f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/PostUpdateEventToPostList.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.events; + +import ml.docilealligator.infinityforreddit.post.Post; + +public class PostUpdateEventToPostList { + public final Post post; + public final int positionInList; + + public PostUpdateEventToPostList(Post post, int positionInList) { + this.post = post; + this.positionInList = positionInList; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/RecreateActivityEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/RecreateActivityEvent.java new file mode 100644 index 00000000..b7f5c087 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/RecreateActivityEvent.java @@ -0,0 +1,4 @@ +package ml.docilealligator.infinityforreddit.events; + +public class RecreateActivityEvent { +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/RefreshMultiRedditsEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/RefreshMultiRedditsEvent.java new file mode 100644 index 00000000..60d4295b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/RefreshMultiRedditsEvent.java @@ -0,0 +1,4 @@ +package ml.docilealligator.infinityforreddit.events; + +public class RefreshMultiRedditsEvent { +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/RepliedToPrivateMessageEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/RepliedToPrivateMessageEvent.java new file mode 100644 index 00000000..fc84880c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/RepliedToPrivateMessageEvent.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.events; + +import ml.docilealligator.infinityforreddit.message.Message; + +public class RepliedToPrivateMessageEvent { + public Message newReply; + public int messagePosition; + + public RepliedToPrivateMessageEvent(Message newReply, int messagePosition) { + this.newReply = newReply; + this.messagePosition = messagePosition; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowDividerInCompactLayoutPreferenceEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowDividerInCompactLayoutPreferenceEvent.java new file mode 100644 index 00000000..84fba13e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowDividerInCompactLayoutPreferenceEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ShowDividerInCompactLayoutPreferenceEvent { + public boolean showDividerInCompactLayout; + + public ShowDividerInCompactLayoutPreferenceEvent(boolean showDividerInCompactLayout) { + this.showDividerInCompactLayout = showDividerInCompactLayout; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowThumbnailOnTheRightInCompactLayoutEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowThumbnailOnTheRightInCompactLayoutEvent.java new file mode 100644 index 00000000..0f5edd86 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ShowThumbnailOnTheRightInCompactLayoutEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.events; + +public class ShowThumbnailOnTheRightInCompactLayoutEvent { + public boolean showThumbnailOnTheRightInCompactLayout; + + public ShowThumbnailOnTheRightInCompactLayoutEvent(boolean showThumbnailOnTheRightInCompactLayout) { + this.showThumbnailOnTheRightInCompactLayout = showThumbnailOnTheRightInCompactLayout; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitCrosspostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitCrosspostEvent.java new file mode 100644 index 00000000..5c675bcb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitCrosspostEvent.java @@ -0,0 +1,15 @@ +package ml.docilealligator.infinityforreddit.events; + +import ml.docilealligator.infinityforreddit.post.Post; + +public class SubmitCrosspostEvent { + public boolean postSuccess; + public Post post; + public String errorMessage; + + public SubmitCrosspostEvent(boolean postSuccess, Post post, String errorMessage) { + this.postSuccess = postSuccess; + this.post = post; + this.errorMessage = errorMessage; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitImagePostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitImagePostEvent.java new file mode 100644 index 00000000..f98c7744 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitImagePostEvent.java @@ -0,0 +1,11 @@ +package ml.docilealligator.infinityforreddit.events; + +public class SubmitImagePostEvent { + public boolean postSuccess; + public String errorMessage; + + public SubmitImagePostEvent(boolean postSuccess, String errorMessage) { + this.postSuccess = postSuccess; + this.errorMessage = errorMessage; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitTextOrLinkPostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitTextOrLinkPostEvent.java new file mode 100644 index 00000000..c0613568 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitTextOrLinkPostEvent.java @@ -0,0 +1,15 @@ +package ml.docilealligator.infinityforreddit.events; + +import ml.docilealligator.infinityforreddit.post.Post; + +public class SubmitTextOrLinkPostEvent { + public boolean postSuccess; + public Post post; + public String errorMessage; + + public SubmitTextOrLinkPostEvent(boolean postSuccess, Post post, String errorMessage) { + this.postSuccess = postSuccess; + this.post = post; + this.errorMessage = errorMessage; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitVideoOrGifPostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitVideoOrGifPostEvent.java new file mode 100644 index 00000000..2a5aa0a7 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitVideoOrGifPostEvent.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.events; + +public class SubmitVideoOrGifPostEvent { + public boolean postSuccess; + public boolean errorProcessingVideoOrGif; + public String errorMessage; + + public SubmitVideoOrGifPostEvent(boolean postSuccess, boolean errorProcessingVideoOrGif, String errorMessage) { + this.postSuccess = postSuccess; + this.errorProcessingVideoOrGif = errorProcessingVideoOrGif; + this.errorMessage = errorMessage; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/SwitchAccountEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SwitchAccountEvent.java new file mode 100644 index 00000000..bd907147 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SwitchAccountEvent.java @@ -0,0 +1,12 @@ +package ml.docilealligator.infinityforreddit.events; + +public class SwitchAccountEvent { + public String excludeActivityClassName; + + public SwitchAccountEvent() { + } + + public SwitchAccountEvent(String excludeActivityClassName) { + this.excludeActivityClassName = excludeActivityClassName; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java new file mode 100644 index 00000000..1445c503 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontFamily.java @@ -0,0 +1,36 @@ +package ml.docilealligator.infinityforreddit.font; + +import ml.docilealligator.infinityforreddit.R; + +public enum ContentFontFamily { + Default(R.style.ContentFontFamily, "Default"), + BalsamiqSans(R.style.ContentFontFamily_BalsamiqSans, "BalsamiqSansBold"), + BalsamiqSansBold(R.style.ContentFontFamily_BalsamiqSansBold, "BalsamiqSansBold"), + NotoSans(R.style.ContentFontFamily_NotoSans, "NotoSans"), + NotoSansBold(R.style.ContentFontFamily_NotoSansBold, "NotoSansBold"), + RobotoCondensed(R.style.ContentFontFamily_RobotoCondensed, "RobotoCondensed"), + RobotoCondensedBold(R.style.ContentFontFamily_RobotoCondensedBold, "RobotoCondensedBold"), + HarmoniaSans(R.style.ContentFontFamily_HarmoniaSans, "HarmoniaSans"), + HarmoniaSansBold(R.style.ContentFontFamily_HarmoniaSansBold, "HarmoniaSansBold"), + Inter(R.style.ContentFontFamily_Inter, "Inter"), + InterBold(R.style.ContentFontFamily_InterBold, "InterBold"), + Manrope(R.style.ContentFontFamily_Manrope, "Manrope"), + ManropeBold(R.style.ContentFontFamily_ManropeBold, "ManropeBold"), + Sriracha(R.style.ContentFontFamily_Sriracha, "Sriracha"); + + private int resId; + private String title; + + ContentFontFamily(int resId, String title) { + this.resId = resId; + this.title = title; + } + + public int getResId() { + return resId; + } + + public String getTitle() { + return title; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontStyle.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontStyle.java new file mode 100644 index 00000000..5a448852 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/ContentFontStyle.java @@ -0,0 +1,27 @@ +package ml.docilealligator.infinityforreddit.font; + +import ml.docilealligator.infinityforreddit.R; + +public enum ContentFontStyle { + Small(R.style.ContentFontStyle_Small, "Small"), + Normal(R.style.ContentFontStyle_Normal, "Normal"), + Large(R.style.ContentFontStyle_Large, "Large"), + XLarge(R.style.ContentFontStyle_XLarge, "XLarge"), + XXLarge(R.style.ContentFontStyle_XXLarge, "XXLarge"); + + private int resId; + private String title; + + ContentFontStyle(int resId, String title) { + this.resId = resId; + this.title = title; + } + + public int getResId() { + return resId; + } + + public String getTitle() { + return title; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java new file mode 100644 index 00000000..c04111e5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontFamily.java @@ -0,0 +1,36 @@ +package ml.docilealligator.infinityforreddit.font; + +import ml.docilealligator.infinityforreddit.R; + +public enum FontFamily { + Default(R.style.FontFamily, "Default"), + BalsamiqSans(R.style.FontFamily_BalsamiqSans, "BalsamiqSans"), + BalsamiqSansBold(R.style.FontFamily_BalsamiqSansBold, "BalsamiqSansBold"), + NotoSans(R.style.FontFamily_NotoSans, "NotoSans"), + NotoSansBold(R.style.FontFamily_NotoSansBold, "NotoSansBold"), + RobotoCondensed(R.style.FontFamily_RobotoCondensed, "RobotoCondensed"), + RobotoCondensedBold(R.style.FontFamily_RobotoCondensedBold, "RobotoCondensedBold"), + HarmoniaSans(R.style.FontFamily_HarmoniaSans, "HarmoniaSans"), + HarmoniaSansBold(R.style.FontFamily_HarmoniaSansBold, "HarmoniaSansBold"), + Inter(R.style.FontFamily_Inter, "Inter"), + InterBold(R.style.FontFamily_InterBold, "InterBold"), + Manrope(R.style.FontFamily_Manrope, "Manrope"), + ManropeBold(R.style.FontFamily_ManropeBold, "ManropeBold"), + Sriracha(R.style.FontFamily_Sriracha, "Sriracha"); + + private int resId; + private String title; + + FontFamily(int resId, String title) { + this.resId = resId; + this.title = title; + } + + public int getResId() { + return resId; + } + + public String getTitle() { + return title; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontStyle.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontStyle.java new file mode 100644 index 00000000..a7e3d7fa --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/FontStyle.java @@ -0,0 +1,26 @@ +package ml.docilealligator.infinityforreddit.font; + +import ml.docilealligator.infinityforreddit.R; + +public enum FontStyle { + Small(R.style.FontStyle_Small, "Small"), + Normal(R.style.FontStyle_Normal, "Normal"), + Large(R.style.FontStyle_Large, "Large"), + XLarge(R.style.FontStyle_XLarge, "XLarge"); + + private int resId; + private String title; + + FontStyle(int resId, String title) { + this.resId = resId; + this.title = title; + } + + public int getResId() { + return resId; + } + + public String getTitle() { + return title; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java new file mode 100644 index 00000000..60855f54 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontFamily.java @@ -0,0 +1,36 @@ +package ml.docilealligator.infinityforreddit.font; + +import ml.docilealligator.infinityforreddit.R; + +public enum TitleFontFamily { + Default(R.style.TitleFontFamily, "Default"), + BalsamiqSans(R.style.TitleFontFamily_BalsamiqSans, "BalsamiqSans"), + BalsamiqSansBold(R.style.TitleFontFamily_BalsamiqSansBold, "BalsamiqSansBold"), + NotoSans(R.style.TitleFontFamily_NotoSans, "NotoSans"), + NotoSansBold(R.style.TitleFontFamily_NotoSansBold, "NotoSansBold"), + RobotoCondensed(R.style.TitleFontFamily_RobotoCondensed, "RobotoCondensed"), + RobotoCondensedBold(R.style.TitleFontFamily_RobotoCondensedBold, "RobotoCondensedBold"), + HarmoniaSans(R.style.TitleFontFamily_HarmoniaSans, "HarmoniaSans"), + HarmoniaSansBold(R.style.TitleFontFamily_HarmoniaSansBold, "HarmoniaSansBold"), + Inter(R.style.TitleFontFamily_Inter, "Inter"), + InterBold(R.style.TitleFontFamily_InterBold, "InterBold"), + Manrope(R.style.TitleFontFamily_Manrope, "Manrope"), + ManropeBold(R.style.TitleFontFamily_ManropeBold, "ManropeBold"), + Sriracha(R.style.TitleFontFamily_Sriracha, "Sriracha"); + + private int resId; + private String title; + + TitleFontFamily(int resId, String title) { + this.resId = resId; + this.title = title; + } + + public int getResId() { + return resId; + } + + public String getTitle() { + return title; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontStyle.java b/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontStyle.java new file mode 100644 index 00000000..0c2a7d53 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/font/TitleFontStyle.java @@ -0,0 +1,26 @@ +package ml.docilealligator.infinityforreddit.font; + +import ml.docilealligator.infinityforreddit.R; + +public enum TitleFontStyle { + Small(R.style.TitleFontStyle_Small, "Small"), + Normal(R.style.TitleFontStyle_Normal, "Normal"), + Large(R.style.TitleFontStyle_Large, "Large"), + XLarge(R.style.TitleFontStyle_XLarge, "XLarge"); + + private int resId; + private String title; + + TitleFontStyle(int resId, String title) { + this.resId = resId; + this.title = title; + } + + public int getResId() { + return resId; + } + + public String getTitle() { + return title; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ChangePullToRefreshEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ChangePullToRefreshEvent.java new file mode 100644 index 00000000..c9aa91b9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ChangePullToRefreshEvent.java @@ -0,0 +1,9 @@ +package ml.docilealligator.infinityforreddit.fragments; + +public class ChangePullToRefreshEvent { + public boolean pullToRefresh; + + public ChangePullToRefreshEvent(boolean pullToRefresh) { + this.pullToRefresh = pullToRefresh; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java new file mode 100644 index 00000000..75ed77db --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/CommentsListingFragment.java @@ -0,0 +1,416 @@ +package ml.docilealligator.infinityforreddit.fragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.os.Bundle; +import android.view.HapticFeedbackConstants; +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.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.res.ResourcesCompat; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.adapters.CommentsListingRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.asynctasks.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.comment.CommentViewModel; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + + +/** + * A simple {@link Fragment} subclass. + */ +public class CommentsListingFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_USERNAME = "EN"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + public static final String EXTRA_ARE_SAVED_COMMENTS = "EISC"; + + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + + @BindView(R.id.coordinator_layout_comments_listing_fragment) + CoordinatorLayout mCoordinatorLayout; + @BindView(R.id.swipe_refresh_layout_view_comments_listing_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_comments_listing_fragment) + RecyclerView mCommentRecyclerView; + @BindView(R.id.fetch_comments_info_linear_layout_comments_listing_fragment) + LinearLayout mFetchCommentInfoLinearLayout; + @BindView(R.id.fetch_comments_info_image_view_comments_listing_fragment) + ImageView mFetchCommentInfoImageView; + @BindView(R.id.fetch_comments_info_text_view_comments_listing_fragment) + TextView mFetchCommentInfoTextView; + CommentViewModel mCommentViewModel; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + CustomThemeWrapper customThemeWrapper; + private boolean mNullAccessToken = false; + private String mAccessToken; + private RequestManager mGlide; + private Activity mActivity; + private LinearLayoutManager mLinearLayoutManager; + private CommentsListingRecyclerViewAdapter mAdapter; + private SortType sortType; + private ColorDrawable backgroundSwipeRight; + private ColorDrawable backgroundSwipeLeft; + private Drawable drawableSwipeRight; + private Drawable drawableSwipeLeft; + private int swipeLeftAction; + private int swipeRightAction; + private float swipeActionThreshold; + private ItemTouchHelper touchHelper; + + public CommentsListingFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_comments_listing, container, false); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + applyTheme(); + + mGlide = Glide.with(mActivity); + + Resources resources = getResources(); + + if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { + mCommentRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { + mCommentRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); + } + } + + boolean enableSwipeAction = mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false); + boolean 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 CommentsListingRecyclerViewAdapter.CommentViewHolder)) { + return makeMovementFlags(0, 0); + } + int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; + return makeMovementFlags(0, swipeFlags); + } + + @Override + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { + return false; + } + + @Override + public boolean isItemViewSwipeEnabled() { + return true; + } + + @Override + public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { + if (touchHelper != null) { + touchHelper.attachToRecyclerView(null); + touchHelper.attachToRecyclerView(mCommentRecyclerView); + if (mAdapter != null) { + mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); + } + } + } + + @Override + public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + + View itemView = viewHolder.itemView; + int horizontalOffset = (int) Utils.convertDpToPixel(16, mActivity); + if (dX > 0) { + if (dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeRight.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeRight.setBounds(0, 0, 0, 0); + } + + drawableSwipeRight.setBounds(itemView.getLeft() + ((int) dX) - horizontalOffset - drawableSwipeRight.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() - drawableSwipeRight.getIntrinsicHeight()) / 2, + itemView.getLeft() + ((int) dX) - horizontalOffset, + (itemView.getBottom() + itemView.getTop() + drawableSwipeRight.getIntrinsicHeight()) / 2); + backgroundSwipeRight.draw(c); + drawableSwipeRight.draw(c); + } else if (dX < 0) { + if (-dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeLeft.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeLeft.setBounds(0, 0, 0, 0); + } + drawableSwipeLeft.setBounds(itemView.getRight() + ((int) dX) + horizontalOffset, + (itemView.getBottom() + itemView.getTop() - drawableSwipeLeft.getIntrinsicHeight()) / 2, + itemView.getRight() + ((int) dX) + horizontalOffset + drawableSwipeLeft.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() + drawableSwipeLeft.getIntrinsicHeight()) / 2); + backgroundSwipeLeft.draw(c); + drawableSwipeLeft.draw(c); + } + } + + @Override + public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { + return swipeActionThreshold; + } + }); + + if (enableSwipeAction) { + touchHelper.attachToRecyclerView(mCommentRecyclerView); + } + + if (savedInstanceState == null) { + getCurrentAccountAndBindView(resources); + } else { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(resources); + } else { + bindView(resources); + } + } + + return rootView; + } + + private void getCurrentAccountAndBindView(Resources resources) { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + } + bindView(resources); + }).execute(); + } + + private void bindView(Resources resources) { + mLinearLayoutManager = new LinearLayoutManager(mActivity); + mCommentRecyclerView.setLayoutManager(mLinearLayoutManager); + + mAdapter = new CommentsListingRecyclerViewAdapter(mActivity, mOauthRetrofit, customThemeWrapper, + getResources().getConfiguration().locale, mSharedPreferences, + getArguments().getString(EXTRA_ACCESS_TOKEN), getArguments().getString(EXTRA_ACCOUNT_NAME), + () -> mCommentViewModel.retryLoadingMore()); + + String username = getArguments().getString(EXTRA_USERNAME); + String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_USER_COMMENT, SortType.Type.NEW.name()); + if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { + String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_USER_COMMENT, SortType.Time.ALL.name()); + sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase()), SortType.Time.valueOf(sortTime.toUpperCase())); + } else { + sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase())); + } + + mCommentRecyclerView.setAdapter(mAdapter); + + CommentViewModel.Factory factory; + + if (mAccessToken == null) { + factory = new CommentViewModel.Factory(mRetrofit, + resources.getConfiguration().locale, null, username, sortType, + getArguments().getBoolean(EXTRA_ARE_SAVED_COMMENTS)); + } else { + factory = new CommentViewModel.Factory(mOauthRetrofit, + resources.getConfiguration().locale, mAccessToken, username, sortType, + getArguments().getBoolean(EXTRA_ARE_SAVED_COMMENTS)); + } + + mCommentViewModel = new ViewModelProvider(this, factory).get(CommentViewModel.class); + mCommentViewModel.getComments().observe(getViewLifecycleOwner(), comments -> mAdapter.submitList(comments)); + + mCommentViewModel.hasComment().observe(getViewLifecycleOwner(), hasComment -> { + mSwipeRefreshLayout.setRefreshing(false); + if (hasComment) { + mFetchCommentInfoLinearLayout.setVisibility(View.GONE); + } else { + mFetchCommentInfoLinearLayout.setOnClickListener(view -> { + //Do nothing + }); + showErrorView(R.string.no_comments); + } + }); + + mCommentViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { + if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { + mSwipeRefreshLayout.setRefreshing(false); + } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchCommentInfoLinearLayout.setOnClickListener(view -> refresh()); + showErrorView(R.string.load_comments_failed); + } else { + mSwipeRefreshLayout.setRefreshing(true); + } + }); + + mCommentViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> mAdapter.setNetworkState(networkState)); + + mSwipeRefreshLayout.setOnRefreshListener(() -> mCommentViewModel.refresh()); + } + + public void changeSortType(SortType sortType) { + mCommentViewModel.changeSortType(sortType); + this.sortType = sortType; + } + + private void initializeSwipeActionDrawable() { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getDownvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } else { + backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getUpvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } + + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getUpvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } else { + backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getDownvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(mActivity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.mActivity = (Activity) context; + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + } + + @Override + public void refresh() { + mFetchCommentInfoLinearLayout.setVisibility(View.GONE); + mCommentViewModel.refresh(); + mAdapter.setNetworkState(null); + } + + @Override + public void applyTheme() { + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); + mFetchCommentInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); + } + + private void showErrorView(int stringResId) { + if (mActivity != null && isAdded()) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchCommentInfoLinearLayout.setVisibility(View.VISIBLE); + mFetchCommentInfoTextView.setText(stringResId); + mGlide.load(R.drawable.error_image).into(mFetchCommentInfoImageView); + } + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } + + public SortType getSortType() { + return sortType; + } + + public void giveAward(String awardsHTML, int position) { + if (mAdapter != null) { + mAdapter.giveAward(awardsHTML, position); + } + } + + public void editComment(String commentMarkdown, int position) { + if (mAdapter != null) { + mAdapter.editComment(commentMarkdown, position); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java new file mode 100644 index 00000000..a740116c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/FollowedUsersListingFragment.java @@ -0,0 +1,175 @@ +package ml.docilealligator.infinityforreddit.fragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Build; +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 androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import me.zhanghai.android.fastscroll.FastScrollerBuilder; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.activities.SubscribedThingListingActivity; +import ml.docilealligator.infinityforreddit.adapters.FollowedUsersRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserViewModel; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + + +/** + * A simple {@link Fragment} subclass. + */ +public class FollowedUsersListingFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + + @BindView(R.id.swipe_refresh_layout_followed_users_listing_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_followed_users_listing_fragment) + RecyclerView mRecyclerView; + @BindView(R.id.no_subscriptions_linear_layout_followed_users_listing_fragment) + LinearLayout mLinearLayout; + @BindView(R.id.no_subscriptions_image_view_followed_users_listing_fragment) + ImageView mImageView; + @BindView(R.id.error_text_view_followed_users_listing_fragment) + TextView mErrorTextView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + SubscribedUserViewModel mSubscribedUserViewModel; + private Activity mActivity; + private RequestManager mGlide; + private LinearLayoutManager mLinearLayoutManager; + + public FollowedUsersListingFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_followed_users_listing, container, false); + + ButterKnife.bind(this, rootView); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + applyTheme(); + + Resources resources = getResources(); + + if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { + mRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { + mRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); + } + } + + mGlide = Glide.with(this); + + mLinearLayoutManager = new LinearLayoutManager(mActivity); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + FollowedUsersRecyclerViewAdapter adapter = new FollowedUsersRecyclerViewAdapter(mActivity, + mOauthRetrofit, mRedditDataRoomDatabase, customThemeWrapper, + getArguments().getString(EXTRA_ACCESS_TOKEN)); + mRecyclerView.setAdapter(adapter); + new FastScrollerBuilder(mRecyclerView).build(); + + mSubscribedUserViewModel = new ViewModelProvider(this, + new SubscribedUserViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, getArguments().getString(EXTRA_ACCOUNT_NAME))) + .get(SubscribedUserViewModel.class); + + mSubscribedUserViewModel.getAllSubscribedUsers().observe(this, subscribedUserData -> { + mSwipeRefreshLayout.setRefreshing(false); + if (subscribedUserData == null || subscribedUserData.size() == 0) { + mRecyclerView.setVisibility(View.GONE); + mLinearLayout.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.error_image).into(mImageView); + } else { + mLinearLayout.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + mGlide.clear(mImageView); + } + adapter.setSubscribedUsers(subscribedUserData); + }); + + mSubscribedUserViewModel.getAllFavoriteSubscribedUsers().observe(this, favoriteSubscribedUserData -> { + mSwipeRefreshLayout.setRefreshing(false); + if (favoriteSubscribedUserData != null && favoriteSubscribedUserData.size() > 0) { + mLinearLayout.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + mGlide.clear(mImageView); + } + adapter.setFavoriteSubscribedUsers(favoriteSubscribedUserData); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (Activity) context; + } + + @Override + public void stopRefreshProgressbar() { + mSwipeRefreshLayout.setRefreshing(false); + } + + @Override + public void applyTheme() { + if (mActivity instanceof SubscribedThingListingActivity) { + mSwipeRefreshLayout.setOnRefreshListener(() -> ((SubscribedThingListingActivity) mActivity).loadSubscriptions(true)); + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); + } else { + mSwipeRefreshLayout.setEnabled(false); + } + mErrorTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java new file mode 100644 index 00000000..f23b6597 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/InboxFragment.java @@ -0,0 +1,197 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.content.Context; +import android.content.SharedPreferences; +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 androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.DividerItemDecoration; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.adapters.MessageRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RepliedToPrivateMessageEvent; +import ml.docilealligator.infinityforreddit.message.FetchMessage; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.message.MessageViewModel; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import retrofit2.Retrofit; + +public class InboxFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_MESSAGE_WHERE = "EMT"; + @BindView(R.id.swipe_refresh_layout_inbox_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_inbox_fragment) + RecyclerView mRecyclerView; + @BindView(R.id.fetch_messages_info_linear_layout_inbox_fragment) + LinearLayout mFetchMessageInfoLinearLayout; + @BindView(R.id.fetch_messages_info_image_view_inbox_fragment) + ImageView mFetchMessageInfoImageView; + @BindView(R.id.fetch_messages_info_text_view_inbox_fragment) + TextView mFetchMessageInfoTextView; + MessageViewModel mMessageViewModel; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String mAccessToken; + private String mWhere; + private MessageRecyclerViewAdapter mAdapter; + private RequestManager mGlide; + private LinearLayoutManager mLinearLayoutManager; + private BaseActivity mActivity; + + public InboxFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_inbox, container, false); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + EventBus.getDefault().register(this); + + applyTheme(); + + Bundle arguments = getArguments(); + if (arguments == null) { + return rootView; + } + mAccessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + mGlide = Glide.with(this); + + if (mActivity.isImmersiveInterface()) { + mRecyclerView.setPadding(0, 0, 0, mActivity.getNavBarHeight()); + } + + mWhere = arguments.getString(EXTRA_MESSAGE_WHERE, FetchMessage.WHERE_INBOX); + mAdapter = new MessageRecyclerViewAdapter(mActivity, mOauthRetrofit, mCustomThemeWrapper, + mAccessToken, mWhere, () -> mMessageViewModel.retryLoadingMore()); + mLinearLayoutManager = new LinearLayoutManager(mActivity); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + mRecyclerView.setAdapter(mAdapter); + DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(mActivity, mLinearLayoutManager.getOrientation()); + mRecyclerView.addItemDecoration(dividerItemDecoration); + + MessageViewModel.Factory factory = new MessageViewModel.Factory(mOauthRetrofit, + getResources().getConfiguration().locale, mAccessToken, mWhere); + mMessageViewModel = new ViewModelProvider(this, factory).get(MessageViewModel.class); + mMessageViewModel.getMessages().observe(getViewLifecycleOwner(), messages -> mAdapter.submitList(messages)); + + mMessageViewModel.hasMessage().observe(getViewLifecycleOwner(), hasMessage -> { + mSwipeRefreshLayout.setRefreshing(false); + if (hasMessage) { + mFetchMessageInfoLinearLayout.setVisibility(View.GONE); + } else { + mFetchMessageInfoLinearLayout.setOnClickListener(null); + showErrorView(R.string.no_messages); + } + }); + + mMessageViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { + if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { + mSwipeRefreshLayout.setRefreshing(false); + } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchMessageInfoLinearLayout.setOnClickListener(view -> { + mFetchMessageInfoLinearLayout.setVisibility(View.GONE); + mMessageViewModel.refresh(); + mAdapter.setNetworkState(null); + }); + showErrorView(R.string.load_messages_failed); + } else { + mSwipeRefreshLayout.setRefreshing(true); + } + }); + + mMessageViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> { + mAdapter.setNetworkState(networkState); + }); + + mSwipeRefreshLayout.setOnRefreshListener(this::onRefresh); + + return rootView; + } + + private void showErrorView(int stringResId) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchMessageInfoLinearLayout.setVisibility(View.VISIBLE); + mFetchMessageInfoTextView.setText(stringResId); + mGlide.load(R.drawable.error_image).into(mFetchMessageInfoImageView); + } + + @Override + public void applyTheme() { + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); + mFetchMessageInfoTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } + + private void onRefresh() { + mMessageViewModel.refresh(); + mAdapter.setNetworkState(null); + } + + @Override + public void onDestroy() { + super.onDestroy(); + EventBus.getDefault().unregister(this); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (BaseActivity) context; + } + + @Subscribe + public void onRepliedToPrivateMessageEvent(RepliedToPrivateMessageEvent repliedToPrivateMessageEvent) { + if (mAdapter != null && mWhere.equals(FetchMessage.WHERE_MESSAGES)) { + mAdapter.updateMessageReply(repliedToPrivateMessageEvent.newReply, repliedToPrivateMessageEvent.messagePosition); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java new file mode 100644 index 00000000..b9ae3f7b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/MultiRedditListingFragment.java @@ -0,0 +1,181 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Build; +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 androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import me.zhanghai.android.fastscroll.FastScrollerBuilder; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.activities.SubscribedThingListingActivity; +import ml.docilealligator.infinityforreddit.adapters.MultiRedditListingRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.multireddit.MultiRedditViewModel; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class MultiRedditListingFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + + @BindView(R.id.swipe_refresh_layout_multi_reddit_listing_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_multi_reddit_listing_fragment) + RecyclerView mRecyclerView; + @BindView(R.id.fetch_multi_reddit_listing_info_linear_layout_multi_reddit_listing_fragment) + LinearLayout mErrorLinearLayout; + @BindView(R.id.fetch_multi_reddit_listing_info_image_view_multi_reddit_listing_fragment) + ImageView mErrorImageView; + @BindView(R.id.fetch_multi_reddit_listing_info_text_view_multi_reddit_listing_fragment) + TextView mErrorTextView; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + + public MultiRedditViewModel mMultiRedditViewModel; + private SubscribedThingListingActivity mActivity; + private RequestManager mGlide; + private LinearLayoutManager mLinearLayoutManager; + + public MultiRedditListingFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_multi_reddit_listing, container, false); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + applyTheme(); + + if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { + mRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).getNavBarHeight()); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true)) { + Resources resources = getResources(); + int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); + if (navBarResourceId > 0) { + mRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); + } + } + + String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + + mGlide = Glide.with(this); + + mLinearLayoutManager = new LinearLayoutManager(mActivity); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + MultiRedditListingRecyclerViewAdapter adapter = new MultiRedditListingRecyclerViewAdapter(mActivity, + mOauthRetrofit, mRedditDataRoomDatabase, mCustomThemeWrapper, accessToken, accountName); + mRecyclerView.setAdapter(adapter); + mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); + if (dy > 0) { + mActivity.fab.hide(); + } else { + mActivity.fab.show(); + } + } + }); + new FastScrollerBuilder(mRecyclerView).build(); + + mMultiRedditViewModel = new ViewModelProvider(this, + new MultiRedditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName)) + .get(MultiRedditViewModel.class); + + mMultiRedditViewModel.getAllMultiReddits().observe(getViewLifecycleOwner(), subscribedUserData -> { + if (subscribedUserData == null || subscribedUserData.size() == 0) { + mRecyclerView.setVisibility(View.GONE); + mErrorLinearLayout.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.error_image).into(mErrorImageView); + } else { + mErrorLinearLayout.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + mGlide.clear(mErrorImageView); + } + adapter.setMultiReddits(subscribedUserData); + }); + + mMultiRedditViewModel.getAllFavoriteMultiReddits().observe(getViewLifecycleOwner(), favoriteSubscribedUserData -> { + if (favoriteSubscribedUserData != null && favoriteSubscribedUserData.size() > 0) { + mErrorLinearLayout.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + mGlide.clear(mErrorImageView); + } + adapter.setFavoriteMultiReddits(favoriteSubscribedUserData); + }); + + return rootView; + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (SubscribedThingListingActivity) context; + } + + @Override + public void applyTheme() { + if (mActivity instanceof SubscribedThingListingActivity) { + mSwipeRefreshLayout.setOnRefreshListener(() -> ((SubscribedThingListingActivity) mActivity).loadSubscriptions(true)); + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); + } else { + mSwipeRefreshLayout.setEnabled(false); + } + + mErrorTextView.setTextColor(mCustomThemeWrapper.getSecondaryTextColor()); + } + + @Override + public void stopRefreshProgressbar() { + mSwipeRefreshLayout.setRefreshing(false); + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java new file mode 100644 index 00000000..8ab11086 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java @@ -0,0 +1,1457 @@ +package ml.docilealligator.infinityforreddit.fragments; + + +import android.content.Context; +import android.content.Intent; +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.util.DisplayMetrics; +import android.view.HapticFeedbackConstants; +import android.view.KeyEvent; +import android.view.LayoutInflater; +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.appcompat.app.AppCompatActivity; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.res.ResourcesCompat; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.PagedList; +import androidx.recyclerview.widget.ItemTouchHelper; +import androidx.recyclerview.widget.LinearLayoutManager; +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.Locale; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import im.ene.toro.exoplayer.ExoCreator; +import im.ene.toro.media.PlaybackInfo; +import im.ene.toro.media.VolumeInfo; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.activities.FilteredThingActivity; +import ml.docilealligator.infinityforreddit.activities.MainActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.adapters.PostRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.customviews.CustomToroContainer; +import ml.docilealligator.infinityforreddit.events.ChangeAutoplayNsfwVideosEvent; +import ml.docilealligator.infinityforreddit.events.ChangeCompactLayoutToolbarHiddenByDefaultEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDataSavingModeEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDefaultPostLayoutEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDisableImagePreviewEvent; +import ml.docilealligator.infinityforreddit.events.ChangeEnableSwipeActionSwitchEvent; +import ml.docilealligator.infinityforreddit.events.ChangeLongPressToHideToolbarInCompactLayoutEvent; +import ml.docilealligator.infinityforreddit.events.ChangeMuteAutoplayingVideosEvent; +import ml.docilealligator.infinityforreddit.events.ChangeMuteNSFWVideoEvent; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWBlurEvent; +import ml.docilealligator.infinityforreddit.events.ChangeNetworkStatusEvent; +import ml.docilealligator.infinityforreddit.events.ChangePostLayoutEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSavePostFeedScrolledPositionEvent; +import ml.docilealligator.infinityforreddit.events.ChangeShowAbsoluteNumberOfVotesEvent; +import ml.docilealligator.infinityforreddit.events.ChangeShowElapsedTimeEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSpoilerBlurEvent; +import ml.docilealligator.infinityforreddit.events.ChangeStartAutoplayVisibleAreaOffsetEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSwipeActionEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSwipeActionThresholdEvent; +import ml.docilealligator.infinityforreddit.events.ChangeTimeFormatEvent; +import ml.docilealligator.infinityforreddit.events.ChangeVibrateWhenActionTriggeredEvent; +import ml.docilealligator.infinityforreddit.events.ChangeVideoAutoplayEvent; +import ml.docilealligator.infinityforreddit.events.ChangeVoteButtonsPositionEvent; +import ml.docilealligator.infinityforreddit.events.PostUpdateEventToPostList; +import ml.docilealligator.infinityforreddit.events.ShowDividerInCompactLayoutPreferenceEvent; +import ml.docilealligator.infinityforreddit.events.ShowThumbnailOnTheRightInCompactLayoutEvent; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.post.PostDataSource; +import ml.docilealligator.infinityforreddit.post.PostViewModel; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.subredditfilter.FetchSubredditFilters; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Retrofit; + +import static im.ene.toro.media.PlaybackInfo.INDEX_UNSET; +import static im.ene.toro.media.PlaybackInfo.TIME_UNSET; + + +/** + * A simple {@link Fragment} subclass. + */ +public class PostFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_NAME = "EN"; + public static final String EXTRA_USER_NAME = "EUN"; + public static final String EXTRA_USER_WHERE = "EUW"; + public static final String EXTRA_QUERY = "EQ"; + public static final String EXTRA_POST_TYPE = "EPT"; + public static final String EXTRA_FILTER = "EF"; + public static final int EXTRA_NO_FILTER = -2; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + + private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; + private static final String RECYCLER_VIEW_POSITION_STATE = "RVPS"; + private static final String SUBREDDIT_FILTER_LIST_STATE = "SFLS"; + + @BindView(R.id.swipe_refresh_layout_post_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_post_fragment) + CustomToroContainer mPostRecyclerView; + @BindView(R.id.fetch_post_info_linear_layout_post_fragment) + LinearLayout mFetchPostInfoLinearLayout; + @BindView(R.id.fetch_post_info_image_view_post_fragment) + ImageView mFetchPostInfoImageView; + @BindView(R.id.fetch_post_info_text_view_post_fragment) + TextView mFetchPostInfoTextView; + PostViewModel mPostViewModel; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("gfycat") + Retrofit mGfycatRetrofit; + @Inject + @Named("redgifs") + Retrofit mRedgifsRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + CustomThemeWrapper customThemeWrapper; + @Inject + ExoCreator exoCreator; + @Inject + @Named("post_feed_scrolled_position_cache") + SharedPreferences postFeedScrolledPositionSharedPreferences; + private RequestManager mGlide; + private AppCompatActivity activity; + private LinearLayoutManager mLinearLayoutManager; + private StaggeredGridLayoutManager mStaggeredGridLayoutManager; + private int postType; + private boolean isInLazyMode = false; + private boolean isLazyModePaused = false; + private boolean hasPost = false; + private boolean isShown = false; + private boolean savePostFeedScrolledPosition; + private PostRecyclerViewAdapter mAdapter; + private RecyclerView.SmoothScroller smoothScroller; + private Window window; + private Handler lazyModeHandler; + private LazyModeRunnable lazyModeRunnable; + private CountDownTimer resumeLazyModeCountDownTimer; + private float lazyModeInterval; + private String accountName; + private String subredditName; + private String username; + private String multiRedditPath; + private int maxPosition = -1; + private int postLayout; + private SortType sortType; + 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 subredditFilterList; + + public PostFragment() { + // Required empty public constructor + } + + @Override + public void onResume() { + super.onResume(); + isShown = true; + if (mPostRecyclerView.getAdapter() != null) { + ((PostRecyclerViewAdapter) mPostRecyclerView.getAdapter()).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; + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_post, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + EventBus.getDefault().register(this); + + applyTheme(); + + 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 instanceof BaseActivity && ((BaseActivity) 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)); + } + } + + DisplayMetrics displayMetrics = new DisplayMetrics(); + activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics); + int windowWidth = displayMetrics.widthPixels; + + int nColumns; + if (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + nColumns = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT, "1")); + } else { + nColumns = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE, "2")); + } + + if (nColumns == 1) { + mLinearLayoutManager = new LinearLayoutManager(activity); + mPostRecyclerView.setLayoutManager(mLinearLayoutManager); + } else { + mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL); + mPostRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); + StaggeredGridLayoutManagerItemOffsetDecoration itemDecoration = + new StaggeredGridLayoutManagerItemOffsetDecoration(activity, R.dimen.staggeredLayoutManagerItemOffset); + mPostRecyclerView.addItemDecoration(itemDecoration); + windowWidth /= 2; + } + + mGlide = Glide.with(activity); + + lazyModeRunnable = new LazyModeRunnable() { + + @Override + public void run() { + if (isInLazyMode && !isLazyModePaused) { + 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); + + if (savedInstanceState != null) { + int recyclerViewPosition = savedInstanceState.getInt(RECYCLER_VIEW_POSITION_STATE); + if (recyclerViewPosition > 0) { + mPostRecyclerView.scrollToPosition(recyclerViewPosition); + } + + isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); + subredditFilterList = savedInstanceState.getParcelableArrayList(SUBREDDIT_FILTER_LIST_STATE); + } + + mPostRecyclerView.setOnTouchListener((view, motionEvent) -> { + if (isInLazyMode) { + pauseLazyMode(true); + } + return false; + }); + + if (activity instanceof MainActivity) { + mPostRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + ((MainActivity) activity).postScrollDown(); + } else if (dy < 0) { + ((MainActivity) activity).postScrollUp(); + } + + } + }); + } else if (activity instanceof ViewSubredditDetailActivity) { + mPostRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + ((ViewSubredditDetailActivity) activity).contentScrollDown(); + } else if (dy < 0) { + ((ViewSubredditDetailActivity) activity).contentScrollUp(); + } + + } + }); + } + + postType = getArguments().getInt(EXTRA_POST_TYPE); + + int filter = getArguments().getInt(EXTRA_FILTER); + String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); + int defaultPostLayout = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.DEFAULT_POST_LAYOUT_KEY, "0")); + savePostFeedScrolledPosition = mSharedPreferences.getBoolean(SharedPreferencesUtils.SAVE_FRONT_PAGE_SCROLLED_POSITION, false); + Locale locale = getResources().getConfiguration().locale; + + if (postType == PostDataSource.TYPE_SEARCH) { + subredditName = getArguments().getString(EXTRA_NAME); + String query = getArguments().getString(EXTRA_QUERY); + + String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SEARCH_POST, SortType.Type.RELEVANCE.name()); + String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_SEARCH_POST, SortType.Time.ALL.name()); + sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); + postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST, defaultPostLayout); + + mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, + windowWidth, accessToken, accountName, postType, postLayout, true, + mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, subredditName); + intent.putExtra(FilteredThingActivity.EXTRA_QUERY, query); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + + @Override + public void currentlyBindItem(int position) { + if (maxPosition < position) { + maxPosition = position; + } + } + + @Override + public void delayTransition() { + TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); + } + }); + + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw)).get(PostViewModel.class); + } else if (postType == PostDataSource.TYPE_SUBREDDIT) { + subredditName = getArguments().getString(EXTRA_NAME); + String sort; + String sortTime = null; + + sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SUBREDDIT_POST_BASE + subredditName, SortType.Type.HOT.name()); + if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { + sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_SUBREDDIT_POST_BASE + subredditName, SortType.Time.ALL.name()); + } + boolean displaySubredditName = subredditName != null && (subredditName.equals("popular") || subredditName.equals("all")); + postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + subredditName, defaultPostLayout); + + if(sortTime != null) { + sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); + } else { + sortType = new SortType(SortType.Type.valueOf(sort)); + } + + mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, + windowWidth, accessToken, accountName, postType, postLayout, displaySubredditName, + mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, subredditName); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + + @Override + public void currentlyBindItem(int position) { + if (maxPosition < position) { + maxPosition = position; + } + } + + @Override + public void delayTransition() { + TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); + } + }); + + if (subredditName.equals("all") || subredditName.equals("popular")) { + if (subredditFilterList != null) { + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList)).get(PostViewModel.class); + } else { + FetchSubredditFilters.fetchSubredditFilters(mRedditDataRoomDatabase, subredditFilters -> { + if (activity != null) { + subredditFilterList = subredditFilters; + mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilters)).get(PostViewModel.class); + + bindPostViewModel(); + } + }); + } + } else { + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw)).get(PostViewModel.class); + } + } else if(postType == PostDataSource.TYPE_MULTI_REDDIT) { + multiRedditPath = getArguments().getString(EXTRA_NAME); + String sort; + String sortTime = null; + + sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_MULTI_REDDIT_POST_BASE + multiRedditPath, + SortType.Type.HOT.name()); + if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { + sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_MULTI_REDDIT_POST_BASE + multiRedditPath, + SortType.Time.ALL.name()); + } + postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + multiRedditPath, + defaultPostLayout); + + if(sortTime != null) { + sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); + } else { + sortType = new SortType(SortType.Type.valueOf(sort)); + } + + mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, + windowWidth, accessToken, accountName, postType, postLayout, true, + mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, multiRedditPath); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + + @Override + public void currentlyBindItem(int position) { + if (maxPosition < position) { + maxPosition = position; + } + } + + @Override + public void delayTransition() { + TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); + } + }); + + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, multiRedditPath, postType, sortType, filter, nsfw)).get(PostViewModel.class); + } else if (postType == PostDataSource.TYPE_USER) { + username = getArguments().getString(EXTRA_USER_NAME); + String where = getArguments().getString(EXTRA_USER_WHERE); + if (where != null && where.equals(PostDataSource.USER_WHERE_SUBMITTED)) { + CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) mFetchPostInfoLinearLayout.getLayoutParams(); + params.height = ViewGroup.LayoutParams.WRAP_CONTENT; + mFetchPostInfoLinearLayout.setLayoutParams(params); + } + + String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_USER_POST_BASE + username, SortType.Type.NEW.name()); + if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { + String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_USER_POST_BASE + username, SortType.Time.ALL.name()); + sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); + } else { + sortType = new SortType(SortType.Type.valueOf(sort)); + } + postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + username, defaultPostLayout); + + mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, + windowWidth, accessToken, accountName, postType, postLayout, true, + mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, username); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredThingActivity.EXTRA_USER_WHERE, where); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + + @Override + public void currentlyBindItem(int position) { + if (maxPosition < position) { + maxPosition = position; + } + } + + @Override + public void delayTransition() { + TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); + } + }); + + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(accessToken == null ? mRetrofit : mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, + postFeedScrolledPositionSharedPreferences, username, postType, sortType, where, filter, nsfw)).get(PostViewModel.class); + } else { + String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_BEST_POST, SortType.Type.BEST.name()); + if(sort.equals(SortType.Type.CONTROVERSIAL.name()) || sort.equals(SortType.Type.TOP.name())) { + String sortTime = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TIME_BEST_POST, SortType.Time.ALL.name()); + sortType = new SortType(SortType.Type.valueOf(sort), SortType.Time.valueOf(sortTime)); + } else { + sortType = new SortType(SortType.Type.valueOf(sort)); + } + postLayout = mPostLayoutSharedPreferences.getInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, defaultPostLayout); + + mAdapter = new PostRecyclerViewAdapter(activity, mOauthRetrofit, mRetrofit, mGfycatRetrofit, + mRedgifsRetrofit, mRedditDataRoomDatabase, customThemeWrapper, locale, + windowWidth, accessToken, accountName, postType, postLayout, true, + mSharedPreferences, mNsfwAndSpoilerSharedPreferences, exoCreator, new PostRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mPostViewModel.retryLoadingMore(); + } + + @Override + public void typeChipClicked(int filter) { + Intent intent = new Intent(activity, FilteredThingActivity.class); + intent.putExtra(FilteredThingActivity.EXTRA_NAME, activity.getString(R.string.best)); + intent.putExtra(FilteredThingActivity.EXTRA_POST_TYPE, postType); + intent.putExtra(FilteredThingActivity.EXTRA_FILTER, filter); + startActivity(intent); + } + + @Override + public void currentlyBindItem(int position) { + if (maxPosition < position) { + maxPosition = position; + } + } + + @Override + public void delayTransition() { + TransitionManager.beginDelayedTransition(mPostRecyclerView, new AutoTransition()); + } + }); + + mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(mOauthRetrofit, accessToken, + accountName, getResources().getConfiguration().locale, mSharedPreferences, postFeedScrolledPositionSharedPreferences, + postType, sortType, filter, nsfw)).get(PostViewModel.class); + } + + if (activity instanceof ActivityToolbarInterface) { + ((ActivityToolbarInterface) activity).displaySortType(); + } + + vibrateWhenActionTriggered = mSharedPreferences.getBoolean(SharedPreferencesUtils.VIBRATE_WHEN_ACTION_TRIGGERED, true); + swipeActionThreshold = Float.parseFloat(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_ACTION_THRESHOLD, "0.3")); + swipeRightAction = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_RIGHT_ACTION, "1")); + swipeLeftAction = Integer.parseInt(mSharedPreferences.getString(SharedPreferencesUtils.SWIPE_LEFT_ACTION, "0")); + initializeSwipeActionDrawable(); + + touchHelper = new ItemTouchHelper(new ItemTouchHelper.Callback() { + boolean exceedThreshold = false; + + @Override + public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) { + if (!(viewHolder instanceof PostRecyclerViewAdapter.PostBaseViewHolder) && + !(viewHolder instanceof PostRecyclerViewAdapter.PostCompactBaseViewHolder)) { + return makeMovementFlags(0, 0); + } + int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; + return makeMovementFlags(0, swipeFlags); + } + + @Override + public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) { + return false; + } + + @Override + public boolean isItemViewSwipeEnabled() { + return true; + } + + @Override + public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) { + if (touchHelper != null) { + touchHelper.attachToRecyclerView(null); + touchHelper.attachToRecyclerView(mPostRecyclerView); + if (mAdapter != null) { + mAdapter.onItemSwipe(viewHolder, direction, swipeLeftAction, swipeRightAction); + } + } + } + + @Override + public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { + super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); + + View itemView = viewHolder.itemView; + int horizontalOffset = (int) Utils.convertDpToPixel(16, activity); + if (dX > 0) { + if (dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeRight.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeRight.setBounds(0, 0, 0, 0); + } + + drawableSwipeRight.setBounds(itemView.getLeft() + ((int) dX) - horizontalOffset - drawableSwipeRight.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() - drawableSwipeRight.getIntrinsicHeight()) / 2, + itemView.getLeft() + ((int) dX) - horizontalOffset, + (itemView.getBottom() + itemView.getTop() + drawableSwipeRight.getIntrinsicHeight()) / 2); + backgroundSwipeRight.draw(c); + drawableSwipeRight.draw(c); + } else if (dX < 0) { + if (-dX > (itemView.getRight() - itemView.getLeft()) * swipeActionThreshold) { + if (!exceedThreshold) { + exceedThreshold = true; + if (vibrateWhenActionTriggered) { + viewHolder.itemView.setHapticFeedbackEnabled(true); + viewHolder.itemView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING); + } + } + backgroundSwipeLeft.setBounds(0, itemView.getTop(), itemView.getRight(), itemView.getBottom()); + } else { + exceedThreshold = false; + backgroundSwipeLeft.setBounds(0, 0, 0, 0); + } + drawableSwipeLeft.setBounds(itemView.getRight() + ((int) dX) + horizontalOffset, + (itemView.getBottom() + itemView.getTop() - drawableSwipeLeft.getIntrinsicHeight()) / 2, + itemView.getRight() + ((int) dX) + horizontalOffset + drawableSwipeLeft.getIntrinsicWidth(), + (itemView.getBottom() + itemView.getTop() + drawableSwipeLeft.getIntrinsicHeight()) / 2); + backgroundSwipeLeft.draw(c); + drawableSwipeLeft.draw(c); + } + } + + @Override + public float getSwipeThreshold(@NonNull RecyclerView.ViewHolder viewHolder) { + return swipeActionThreshold; + } + }); + + if (nColumns == 1 && mSharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_SWIPE_ACTION, false)) { + touchHelper.attachToRecyclerView(mPostRecyclerView); + } + mPostRecyclerView.setAdapter(mAdapter); + mPostRecyclerView.setCacheManager(mAdapter); + mPostRecyclerView.setPlayerInitializer(order -> { + VolumeInfo volumeInfo = new VolumeInfo(true, 0f); + return new PlaybackInfo(INDEX_UNSET, TIME_UNSET, volumeInfo); + }); + + if (mPostViewModel != null) { + bindPostViewModel(); + } + + return rootView; + } + + private void bindPostViewModel() { + mPostViewModel.getPosts().observe(getViewLifecycleOwner(), posts -> mAdapter.submitList(posts)); + + mPostViewModel.hasPost().observe(getViewLifecycleOwner(), hasPost -> { + this.hasPost = hasPost; + mSwipeRefreshLayout.setRefreshing(false); + if (hasPost) { + mFetchPostInfoLinearLayout.setVisibility(View.GONE); + } else { + if (isInLazyMode) { + stopLazyMode(); + } + + mFetchPostInfoLinearLayout.setOnClickListener(view -> { + }); + showErrorView(R.string.no_posts); + } + }); + + mPostViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { + if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { + mSwipeRefreshLayout.setRefreshing(false); + } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchPostInfoLinearLayout.setOnClickListener(view -> refresh()); + showErrorView(R.string.load_posts_error); + } else { + mSwipeRefreshLayout.setRefreshing(true); + } + }); + + mPostViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> mAdapter.setNetworkState(networkState)); + } + + public void changeSortType(SortType sortType) { + switch (postType) { + case PostDataSource.TYPE_FRONT_PAGE: + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_BEST_POST, sortType.getType().name()).apply(); + if (sortType.getTime() != null) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_BEST_POST, sortType.getTime().name()).apply(); + } + break; + case PostDataSource.TYPE_SUBREDDIT: + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SUBREDDIT_POST_BASE + subredditName, sortType.getType().name()).apply(); + if (sortType.getTime() != null) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_SUBREDDIT_POST_BASE + subredditName, sortType.getTime().name()).apply(); + } + break; + case PostDataSource.TYPE_USER: + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_USER_POST_BASE + username, sortType.getType().name()).apply(); + if(sortType.getTime() != null) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_USER_POST_BASE + username, sortType.getTime().name()).apply(); + } + break; + case PostDataSource.TYPE_SEARCH: + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SEARCH_POST, sortType.getType().name()).apply(); + if(sortType.getTime() != null) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_SEARCH_POST, sortType.getTime().name()).apply(); + } + break; + case PostDataSource.TYPE_MULTI_REDDIT: + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_MULTI_REDDIT_POST_BASE + multiRedditPath, + sortType.getType().name()).apply(); + if (sortType.getTime() != null) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TIME_MULTI_REDDIT_POST_BASE + multiRedditPath, + sortType.getTime().name()).apply(); + } + break; + } + if (mFetchPostInfoLinearLayout.getVisibility() != View.GONE) { + mFetchPostInfoLinearLayout.setVisibility(View.GONE); + mGlide.clear(mFetchPostInfoImageView); + } + mAdapter.removeFooter(); + hasPost = false; + if (isInLazyMode) { + stopLazyMode(); + } + this.sortType = sortType; + mPostViewModel.changeSortType(sortType); + } + + private void initializeSwipeActionDrawable() { + if (swipeRightAction == SharedPreferencesUtils.SWIPE_ACITON_DOWNVOTE) { + backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getDownvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } else { + backgroundSwipeRight = new ColorDrawable(customThemeWrapper.getUpvoted()); + drawableSwipeRight = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } + + if (swipeLeftAction == SharedPreferencesUtils.SWIPE_ACITON_UPVOTE) { + backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getUpvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_upward_black_24dp, null); + } else { + backgroundSwipeLeft = new ColorDrawable(customThemeWrapper.getDownvoted()); + drawableSwipeLeft = ResourcesCompat.getDrawable(activity.getResources(), R.drawable.ic_arrow_downward_black_24dp, null); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (AppCompatActivity) context; + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); + outState.putParcelableArrayList(SUBREDDIT_FILTER_LIST_STATE, subredditFilterList); + if (mLinearLayoutManager != null) { + outState.putInt(RECYCLER_VIEW_POSITION_STATE, mLinearLayoutManager.findFirstVisibleItemPosition()); + } else if (mStaggeredGridLayoutManager != null) { + int[] into = new int[2]; + outState.putInt(RECYCLER_VIEW_POSITION_STATE, + mStaggeredGridLayoutManager.findFirstVisibleItemPositions(into)[0]); + } + } + + @Override + public void onStop() { + super.onStop(); + saveCache(); + } + + private void saveCache() { + if (savePostFeedScrolledPosition && postType == PostDataSource.TYPE_FRONT_PAGE && sortType != null && sortType.getType() == SortType.Type.BEST && mAdapter != null) { + Post currentPost = mAdapter.getItemByPosition(maxPosition); + if (currentPost != null) { + String accountNameForCache = accountName == null ? SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_ANONYMOUS : accountName; + String key = accountNameForCache + SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_FRONT_PAGE_BASE; + String value = currentPost.getFullName(); + postFeedScrolledPositionSharedPreferences.edit().putString(key, value).apply(); + } + } + } + + @Override + public void refresh() { + mAdapter.removeFooter(); + mFetchPostInfoLinearLayout.setVisibility(View.GONE); + hasPost = false; + if (isInLazyMode) { + stopLazyMode(); + } + saveCache(); + mPostViewModel.refresh(); + } + + 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 void changeNSFW(boolean nsfw) { + mPostViewModel.changeNSFW(nsfw); + } + + @Override + public boolean startLazyMode() { + if (!hasPost) { + Toast.makeText(activity, R.string.no_posts_no_lazy_mode, Toast.LENGTH_SHORT).show(); + return false; + } + + 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() { + 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) { + switch (postType) { + case PostDataSource.TYPE_FRONT_PAGE: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST, postLayout).apply(); + break; + case PostDataSource.TYPE_SUBREDDIT: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + subredditName, postLayout).apply(); + break; + case PostDataSource.TYPE_USER: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + username, postLayout).apply(); + break; + case PostDataSource.TYPE_SEARCH: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST, postLayout).apply(); + break; + case PostDataSource.TYPE_MULTI_REDDIT: + mPostLayoutSharedPreferences.edit().putInt(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + multiRedditPath, postLayout).apply(); + break; + } + + if (mAdapter != null) { + mAdapter.setPostLayout(postLayout); + refreshAdapter(); + } + } + + @Override + public void applyTheme() { + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); + mFetchPostInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); + } + + @Subscribe + public void onPostUpdateEvent(PostUpdateEventToPostList event) { + PagedList posts = mAdapter.getCurrentList(); + if (posts != null && 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.setScore(event.post.getScore()); + post.setNSFW(event.post.isNSFW()); + post.setHidden(event.post.isHidden()); + post.setSpoiler(event.post.isSpoiler()); + post.setFlair(event.post.getFlair()); + post.setSaved(event.post.isSaved()); + 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.setBlurNSFW(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 PostDataSource.TYPE_SUBREDDIT: + if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_SUBREDDIT_POST_BASE + bundle.getString(EXTRA_NAME))) { + changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); + } + break; + case PostDataSource.TYPE_USER: + if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_USER_POST_BASE + bundle.getString(EXTRA_USER_NAME))) { + changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); + } + break; + case PostDataSource.TYPE_MULTI_REDDIT: + if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_MULTI_REDDIT_POST_BASE + bundle.getString(EXTRA_NAME))) { + changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); + } + break; + case PostDataSource.TYPE_SEARCH: + if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_SEARCH_POST)) { + changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); + } + break; + case PostDataSource.TYPE_FRONT_PAGE: + if (!mPostLayoutSharedPreferences.contains(SharedPreferencesUtils.POST_LAYOUT_FRONT_PAGE_POST)) { + changePostLayout(changeDefaultPostLayoutEvent.defaultPostLayout); + } + break; + } + } + } + + @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 onChangeSavePostFeedScrolledPositionEvent(ChangeSavePostFeedScrolledPositionEvent changeSavePostFeedScrolledPositionEvent) { + savePostFeedScrolledPosition = changeSavePostFeedScrolledPositionEvent.savePostFeedScrolledPosition; + } + + @Subscribe + public void onChangeVibrateWhenActionTriggeredEvent(ChangeVibrateWhenActionTriggeredEvent changeVibrateWhenActionTriggeredEvent) { + vibrateWhenActionTriggered = changeVibrateWhenActionTriggeredEvent.vibrateWhenActionTriggered; + } + + @Subscribe + public void onChangeEnableSwipeActionSwitchEvent(ChangeEnableSwipeActionSwitchEvent changeEnableSwipeActionSwitchEvent) { + if (touchHelper != null) { + 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 onChangeSwipeActionEvent(ChangeSwipeActionEvent changeSwipeActionEvent) { + swipeRightAction = changeSwipeActionEvent.swipeRightAction == -1 ? swipeRightAction : changeSwipeActionEvent.swipeRightAction; + swipeLeftAction = changeSwipeActionEvent.swipeLeftAction == -1 ? swipeLeftAction : changeSwipeActionEvent.swipeLeftAction; + initializeSwipeActionDrawable(); + } + + private void refreshAdapter() { + int previousPosition = -1; + if (mLinearLayoutManager != null) { + previousPosition = mLinearLayoutManager.findFirstVisibleItemPosition(); + } else if (mStaggeredGridLayoutManager != null) { + int[] into = new int[2]; + 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(); + } + } + } + + public SortType getSortType() { + return sortType; + } + + public int getPostType() { + return postType; + } + + @Override + public void onPause() { + super.onPause(); + if (isInLazyMode) { + pauseLazyMode(false); + } + if (mAdapter != null && mPostRecyclerView != null) { + mPostRecyclerView.onWindowVisibilityChanged(View.GONE); + } + } + + @Override + public void onDestroy() { + EventBus.getDefault().unregister(this); + super.onDestroy(); + } + + 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; + + StaggeredGridLayoutManagerItemOffsetDecoration(int itemOffset) { + mItemOffset = itemOffset; + } + + StaggeredGridLayoutManagerItemOffsetDecoration(@NonNull Context context, @DimenRes int itemOffsetId) { + this(context.getResources().getDimensionPixelSize(itemOffsetId)); + } + + @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 (spanIndex == 0) { + outRect.set(0, 0, halfOffset, 0); + } else { + outRect.set(halfOffset, 0, 0, 0); + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java new file mode 100644 index 00000000..50a7a912 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SidebarFragment.java @@ -0,0 +1,201 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.text.Spanned; +import android.text.style.SuperscriptSpan; +import android.text.util.Linkify; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import org.commonmark.ext.gfm.tables.TableBlock; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import io.noties.markwon.AbstractMarkwonPlugin; +import io.noties.markwon.Markwon; +import io.noties.markwon.MarkwonConfiguration; +import io.noties.markwon.core.MarkwonTheme; +import io.noties.markwon.ext.strikethrough.StrikethroughPlugin; +import io.noties.markwon.linkify.LinkifyPlugin; +import io.noties.markwon.recycler.MarkwonAdapter; +import io.noties.markwon.recycler.table.TableEntry; +import io.noties.markwon.recycler.table.TableEntryPlugin; +import io.noties.markwon.simple.ext.SimpleExtPlugin; +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.asynctasks.InsertSubredditDataAsyncTask; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subreddit.FetchSubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditData; +import ml.docilealligator.infinityforreddit.subreddit.SubredditViewModel; +import retrofit2.Retrofit; + +public class SidebarFragment extends Fragment { + + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + @BindView(R.id.swipe_refresh_layout_sidebar_fragment) + SwipeRefreshLayout swipeRefreshLayout; + @BindView(R.id.markdown_recycler_view_sidebar_fragment) + RecyclerView recyclerView; + private Activity activity; + private String subredditName; + public SubredditViewModel mSubredditViewModel; + private LinearLayoutManager linearLayoutManager; + private int markdownColor; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + + public SidebarFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_sidebar, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); + if (subredditName == null) { + Toast.makeText(activity, R.string.error_getting_subreddit_name, Toast.LENGTH_SHORT).show(); + return rootView; + } + + swipeRefreshLayout.setProgressBackgroundColorSchemeColor(mCustomThemeWrapper.getCircularProgressBarBackground()); + swipeRefreshLayout.setColorSchemeColors(mCustomThemeWrapper.getColorAccent()); + markdownColor = mCustomThemeWrapper.getSecondaryTextColor(); + + Markwon markwon = Markwon.builder(activity) + .usePlugin(new AbstractMarkwonPlugin() { + @Override + public void beforeSetText(@NonNull TextView textView, @NonNull Spanned markdown) { + textView.setTextColor(markdownColor); + } + + @Override + public void configureTheme(@NonNull MarkwonTheme.Builder builder) { + builder.linkColor(mCustomThemeWrapper.getLinkColor()); + } + + @Override + public void configureConfiguration(@NonNull MarkwonConfiguration.Builder builder) { + builder.linkResolver((view, link) -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + Uri uri = Uri.parse(link); + if (uri.getScheme() == null && uri.getHost() == null) { + intent.setData(LinkResolverActivity.getRedditUriByPath(link)); + } else { + intent.setData(uri); + } + startActivity(intent); + }); + } + }) + .usePlugin(StrikethroughPlugin.create()) + .usePlugin(LinkifyPlugin.create(Linkify.WEB_URLS)) + .usePlugin(SimpleExtPlugin.create(plugin -> + plugin.addExtension(1, '^', (configuration, props) -> { + return new SuperscriptSpan(); + }) + ) + ) + .usePlugin(TableEntryPlugin.create(activity)) + .build(); + MarkwonAdapter markwonAdapter = MarkwonAdapter.builder(R.layout.adapter_default_entry, R.id.text) + .include(TableBlock.class, TableEntry.create(builder -> builder + .tableLayout(R.layout.adapter_table_block, R.id.table_layout) + .textLayoutIsRoot(R.layout.view_table_entry_cell))) + .build(); + + linearLayoutManager = new LinearLayoutManager(activity); + recyclerView.setLayoutManager(linearLayoutManager); + recyclerView.setAdapter(markwonAdapter); + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { + if (dy > 0) { + ((ViewSubredditDetailActivity) activity).contentScrollDown(); + } else if (dy < 0) { + ((ViewSubredditDetailActivity) activity).contentScrollUp(); + } + + } + }); + + mSubredditViewModel = new ViewModelProvider(this, + new SubredditViewModel.Factory(activity.getApplication(), mRedditDataRoomDatabase, subredditName)) + .get(SubredditViewModel.class); + mSubredditViewModel.getSubredditLiveData().observe(getViewLifecycleOwner(), subredditData -> { + if (subredditData != null) { + if (subredditData.getSidebarDescription() != null && !subredditData.getSidebarDescription().equals("")) { + markwonAdapter.setMarkdown(markwon, subredditData.getSidebarDescription()); + markwonAdapter.notifyDataSetChanged(); + } + } else { + fetchSubredditData(); + } + }); + + swipeRefreshLayout.setOnRefreshListener(this::fetchSubredditData); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } + + public void fetchSubredditData() { + swipeRefreshLayout.setRefreshing(true); + FetchSubredditData.fetchSubredditData(mRetrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { + @Override + public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { + swipeRefreshLayout.setRefreshing(false); + new InsertSubredditDataAsyncTask(mRedditDataRoomDatabase, subredditData, () -> swipeRefreshLayout.setRefreshing(false)).execute(); + } + + @Override + public void onFetchSubredditDataFail() { + swipeRefreshLayout.setRefreshing(false); + Toast.makeText(activity, R.string.cannot_fetch_sidebar, Toast.LENGTH_SHORT).show(); + } + }); + } + + public void goBackToTop() { + if (linearLayoutManager != null) { + linearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java new file mode 100644 index 00000000..14bfbf0a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubredditListingFragment.java @@ -0,0 +1,239 @@ +package ml.docilealligator.infinityforreddit.fragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Build; +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.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.activities.SearchSubredditsResultActivity; +import ml.docilealligator.infinityforreddit.activities.ViewSubredditDetailActivity; +import ml.docilealligator.infinityforreddit.adapters.SubredditListingRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.subreddit.SubredditListingViewModel; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + + +/** + * A simple {@link Fragment} subclass. + */ +public class SubredditListingFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_QUERY = "EQ"; + public static final String EXTRA_IS_POSTING = "EIP"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + + @BindView(R.id.coordinator_layout_subreddit_listing_fragment) + CoordinatorLayout mCoordinatorLayout; + @BindView(R.id.recycler_view_subreddit_listing_fragment) + RecyclerView mSubredditListingRecyclerView; + @BindView(R.id.swipe_refresh_layout_subreddit_listing_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.fetch_subreddit_listing_info_linear_layout_subreddit_listing_fragment) + LinearLayout mFetchSubredditListingInfoLinearLayout; + @BindView(R.id.fetch_subreddit_listing_info_image_view_subreddit_listing_fragment) + ImageView mFetchSubredditListingInfoImageView; + @BindView(R.id.fetch_subreddit_listing_info_text_view_subreddit_listing_fragment) + TextView mFetchSubredditListingInfoTextView; + SubredditListingViewModel mSubredditListingViewModel; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + CustomThemeWrapper customThemeWrapper; + private LinearLayoutManager mLinearLayoutManager; + private SubredditListingRecyclerViewAdapter mAdapter; + private Activity mActivity; + private SortType sortType; + + public SubredditListingFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_subreddit_listing, container, false); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + applyTheme(); + + Resources resources = getResources(); + + if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { + mSubredditListingRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { + mSubredditListingRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); + } + } + + mLinearLayoutManager = new LinearLayoutManager(getActivity()); + mSubredditListingRecyclerView.setLayoutManager(mLinearLayoutManager); + + String query = getArguments().getString(EXTRA_QUERY); + boolean isPosting = getArguments().getBoolean(EXTRA_IS_POSTING); + String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + + String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SEARCH_SUBREDDIT, SortType.Type.RELEVANCE.value); + sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase())); + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); + + mAdapter = new SubredditListingRecyclerViewAdapter(mActivity, mOauthRetrofit, mRetrofit, + customThemeWrapper, accessToken, accountName, mRedditDataRoomDatabase, + new SubredditListingRecyclerViewAdapter.Callback() { + @Override + public void retryLoadingMore() { + mSubredditListingViewModel.retryLoadingMore(); + } + + @Override + public void subredditSelected(String subredditName, String iconUrl) { + if (isPosting) { + ((SearchSubredditsResultActivity) mActivity).getSelectedSubreddit(subredditName, iconUrl); + } else { + Intent intent = new Intent(mActivity, ViewSubredditDetailActivity.class); + intent.putExtra(ViewSubredditDetailActivity.EXTRA_SUBREDDIT_NAME_KEY, subredditName); + mActivity.startActivity(intent); + } + } + }); + + mSubredditListingRecyclerView.setAdapter(mAdapter); + + SubredditListingViewModel.Factory factory = new SubredditListingViewModel.Factory( + accessToken == null ? mRetrofit : mOauthRetrofit, query, sortType, accessToken, nsfw); + mSubredditListingViewModel = new ViewModelProvider(this, factory).get(SubredditListingViewModel.class); + mSubredditListingViewModel.getSubreddits().observe(getViewLifecycleOwner(), subredditData -> mAdapter.submitList(subredditData)); + + mSubredditListingViewModel.hasSubredditLiveData().observe(getViewLifecycleOwner(), hasSubreddit -> { + mSwipeRefreshLayout.setRefreshing(false); + if (hasSubreddit) { + mFetchSubredditListingInfoLinearLayout.setVisibility(View.GONE); + } else { + mFetchSubredditListingInfoLinearLayout.setOnClickListener(null); + showErrorView(R.string.no_subreddits); + } + }); + + mSubredditListingViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { + if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { + mSwipeRefreshLayout.setRefreshing(false); + } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchSubredditListingInfoLinearLayout.setOnClickListener(view -> refresh()); + showErrorView(R.string.search_subreddits_error); + } else { + mSwipeRefreshLayout.setRefreshing(true); + } + }); + + mSubredditListingViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> { + mAdapter.setNetworkState(networkState); + }); + + mSwipeRefreshLayout.setOnRefreshListener(() -> mSubredditListingViewModel.refresh()); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (Activity) context; + } + + private void showErrorView(int stringResId) { + if (getActivity() != null && isAdded()) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchSubredditListingInfoLinearLayout.setVisibility(View.VISIBLE); + mFetchSubredditListingInfoTextView.setText(stringResId); + Glide.with(this).load(R.drawable.error_image).into(mFetchSubredditListingInfoImageView); + } + } + + public void changeSortType(SortType sortType) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SEARCH_SUBREDDIT, sortType.getType().name()).apply(); + mSubredditListingViewModel.changeSortType(sortType); + this.sortType = sortType; + } + + @Override + public void refresh() { + mFetchSubredditListingInfoLinearLayout.setVisibility(View.GONE); + mSubredditListingViewModel.refresh(); + mAdapter.setNetworkState(null); + } + + @Override + public void applyTheme() { + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); + mFetchSubredditListingInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } + + public SortType getSortType() { + return sortType; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java new file mode 100644 index 00000000..6279bae5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/SubscribedSubredditsListingFragment.java @@ -0,0 +1,191 @@ +package ml.docilealligator.infinityforreddit.fragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Build; +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 androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import me.zhanghai.android.fastscroll.FastScrollerBuilder; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.activities.SubredditSelectionActivity; +import ml.docilealligator.infinityforreddit.activities.SubscribedThingListingActivity; +import ml.docilealligator.infinityforreddit.adapters.SubscribedSubredditsRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditViewModel; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + + +/** + * A simple {@link Fragment} subclass. + */ +public class SubscribedSubredditsListingFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_ACCOUNT_PROFILE_IMAGE_URL = "EAPIU"; + public static final String EXTRA_IS_SUBREDDIT_SELECTION = "EISS"; + public static final String EXTRA_EXTRA_CLEAR_SELECTION = "EECS"; + + @BindView(R.id.swipe_refresh_layout_subscribed_subreddits_listing_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.recycler_view_subscribed_subreddits_listing_fragment) + RecyclerView mRecyclerView; + @BindView(R.id.no_subscriptions_linear_layout_subreddits_listing_fragment) + LinearLayout mLinearLayout; + @BindView(R.id.no_subscriptions_image_view_subreddits_listing_fragment) + ImageView mImageView; + @BindView(R.id.error_text_view_subscribed_subreddits_listing_fragment) + TextView mErrorTextView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + public SubscribedSubredditViewModel mSubscribedSubredditViewModel; + private Activity mActivity; + private RequestManager mGlide; + private LinearLayoutManager mLinearLayoutManager; + + public SubscribedSubredditsListingFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_subscribed_subreddits_listing, container, false); + + ButterKnife.bind(this, rootView); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + applyTheme(); + + if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { + mRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).getNavBarHeight()); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && mSharedPreferences.getBoolean(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY, true)) { + Resources resources = getResources(); + int navBarResourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android"); + if (navBarResourceId > 0) { + mRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); + } + } + + String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + + mGlide = Glide.with(this); + + mLinearLayoutManager = new LinearLayoutManager(mActivity); + mRecyclerView.setLayoutManager(mLinearLayoutManager); + + SubscribedSubredditsRecyclerViewAdapter adapter; + if (getArguments().getBoolean(EXTRA_IS_SUBREDDIT_SELECTION)) { + adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity, mOauthRetrofit, mRedditDataRoomDatabase, + customThemeWrapper, accessToken, getArguments().getBoolean(EXTRA_EXTRA_CLEAR_SELECTION), + (name, iconUrl, subredditIsUser) -> ((SubredditSelectionActivity) mActivity).getSelectedSubreddit(name, iconUrl, subredditIsUser)); + } else { + adapter = new SubscribedSubredditsRecyclerViewAdapter(mActivity, mOauthRetrofit, mRedditDataRoomDatabase, + customThemeWrapper, accessToken); + } + + mRecyclerView.setAdapter(adapter); + new FastScrollerBuilder(mRecyclerView).build(); + + mSubscribedSubredditViewModel = new ViewModelProvider(this, + new SubscribedSubredditViewModel.Factory(mActivity.getApplication(), mRedditDataRoomDatabase, accountName)) + .get(SubscribedSubredditViewModel.class); + mSubscribedSubredditViewModel.getAllSubscribedSubreddits().observe(this, subscribedSubredditData -> { + mSwipeRefreshLayout.setRefreshing(false); + if (subscribedSubredditData == null || subscribedSubredditData.size() == 0) { + mRecyclerView.setVisibility(View.GONE); + mLinearLayout.setVisibility(View.VISIBLE); + mGlide.load(R.drawable.error_image).into(mImageView); + } else { + mLinearLayout.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + mGlide.clear(mImageView); + } + + adapter.addUser(accountName, getArguments().getString(EXTRA_ACCOUNT_PROFILE_IMAGE_URL)); + adapter.setSubscribedSubreddits(subscribedSubredditData); + }); + + mSubscribedSubredditViewModel.getAllFavoriteSubscribedSubreddits().observe(this, favoriteSubscribedSubredditData -> { + mSwipeRefreshLayout.setRefreshing(false); + if (favoriteSubscribedSubredditData != null && favoriteSubscribedSubredditData.size() > 0) { + mLinearLayout.setVisibility(View.GONE); + mRecyclerView.setVisibility(View.VISIBLE); + mGlide.clear(mImageView); + } + + adapter.setFavoriteSubscribedSubreddits(favoriteSubscribedSubredditData); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (Activity) context; + } + + @Override + public void stopRefreshProgressbar() { + mSwipeRefreshLayout.setRefreshing(false); + } + + @Override + public void applyTheme() { + if (mActivity instanceof SubscribedThingListingActivity) { + mSwipeRefreshLayout.setOnRefreshListener(() -> ((SubscribedThingListingActivity) mActivity).loadSubscriptions(true)); + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); + } else { + mSwipeRefreshLayout.setEnabled(false); + } + mErrorTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewCommentsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewCommentsFragment.java new file mode 100644 index 00000000..9b5dad16 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewCommentsFragment.java @@ -0,0 +1,154 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.content.Context; +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 ml.docilealligator.infinityforreddit.activities.CustomThemePreviewActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.R; + +/** + * 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 CustomThemePreviewActivity activity; + + public ThemePreviewCommentsFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_theme_preview_comments, container, false); + ButterKnife.bind(this, rootView); + + 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); + + linearLayoutFullyCollapsed.setBackgroundColor(customTheme.fullyCollapsedCommentBackgroundColor); + authorTextViewFullyCollapsed.setTextColor(customTheme.username); + scoreTextViewFullyCollapsed.setTextColor(customTheme.secondaryTextColor); + timeTextViewFullyCollapsed.setTextColor(customTheme.secondaryTextColor); + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (CustomThemePreviewActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewPostsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewPostsFragment.java new file mode 100644 index 00000000..1f56b086 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ThemePreviewPostsFragment.java @@ -0,0 +1,153 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.content.Context; +import android.content.res.ColorStateList; +import android.graphics.PorterDuff; +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.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.cardview.widget.CardView; +import androidx.core.graphics.drawable.DrawableCompat; +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 ml.docilealligator.infinityforreddit.activities.CustomThemePreviewActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; +import ml.docilealligator.infinityforreddit.customviews.AspectRatioGifImageView; +import ml.docilealligator.infinityforreddit.R; + +/** + * 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 CustomThemePreviewActivity activity; + + public ThemePreviewPostsFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_theme_preview_posts, container, false); + ButterKnife.bind(this, rootView); + + CustomTheme customTheme = activity.getCustomTheme(); + + cardView.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); + Drawable commentIcon = activity.getDrawable(R.drawable.ic_comment_grey_24dp); + if (commentIcon != null) { + DrawableCompat.setTint(commentIcon, 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); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (CustomThemePreviewActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java new file mode 100644 index 00000000..6d833f4e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/UserListingFragment.java @@ -0,0 +1,220 @@ +package ml.docilealligator.infinityforreddit.fragments; + + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Build; +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.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; + +import com.bumptech.glide.Glide; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.BaseActivity; +import ml.docilealligator.infinityforreddit.adapters.UserListingRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FragmentCommunicator; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.user.UserListingViewModel; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + + +/** + * A simple {@link Fragment} subclass. + */ +public class UserListingFragment extends Fragment implements FragmentCommunicator { + + public static final String EXTRA_QUERY = "EQ"; + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + + @BindView(R.id.coordinator_layout_user_listing_fragment) + CoordinatorLayout mCoordinatorLayout; + @BindView(R.id.recycler_view_user_listing_fragment) + RecyclerView mUserListingRecyclerView; + @BindView(R.id.swipe_refresh_layout_user_listing_fragment) + SwipeRefreshLayout mSwipeRefreshLayout; + @BindView(R.id.fetch_user_listing_info_linear_layout_user_listing_fragment) + LinearLayout mFetchUserListingInfoLinearLayout; + @BindView(R.id.fetch_user_listing_info_image_view_user_listing_fragment) + ImageView mFetchUserListingInfoImageView; + @BindView(R.id.fetch_user_listing_info_text_view_user_listing_fragment) + TextView mFetchUserListingInfoTextView; + UserListingViewModel mUserListingViewModel; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject + CustomThemeWrapper customThemeWrapper; + private LinearLayoutManager mLinearLayoutManager; + private String mQuery; + private UserListingRecyclerViewAdapter mAdapter; + private Activity mActivity; + private SortType sortType; + + public UserListingFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_user_listing, container, false); + + ((Infinity) mActivity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + applyTheme(); + + Resources resources = getResources(); + + if ((mActivity instanceof BaseActivity && ((BaseActivity) mActivity).isImmersiveInterface())) { + mUserListingRecyclerView.setPadding(0, 0, 0, ((BaseActivity) mActivity).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) { + mUserListingRecyclerView.setPadding(0, 0, 0, resources.getDimensionPixelSize(navBarResourceId)); + } + } + + mLinearLayoutManager = new LinearLayoutManager(getActivity()); + mUserListingRecyclerView.setLayoutManager(mLinearLayoutManager); + + mQuery = getArguments().getString(EXTRA_QUERY); + String accessToken = getArguments().getString(EXTRA_ACCESS_TOKEN); + String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + String sort = mSortTypeSharedPreferences.getString(SharedPreferencesUtils.SORT_TYPE_SEARCH_USER, SortType.Type.RELEVANCE.value); + sortType = new SortType(SortType.Type.valueOf(sort.toUpperCase())); + boolean nsfw = mNsfwAndSpoilerSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); + + mAdapter = new UserListingRecyclerViewAdapter(getActivity(), mOauthRetrofit, mRetrofit, + customThemeWrapper, accessToken, accountName, mRedditDataRoomDatabase.subscribedUserDao(), + () -> mUserListingViewModel.retryLoadingMore()); + + mUserListingRecyclerView.setAdapter(mAdapter); + + UserListingViewModel.Factory factory = new UserListingViewModel.Factory(mRetrofit, mQuery, + sortType, nsfw); + mUserListingViewModel = new ViewModelProvider(this, factory).get(UserListingViewModel.class); + mUserListingViewModel.getUsers().observe(getViewLifecycleOwner(), UserData -> mAdapter.submitList(UserData)); + + mUserListingViewModel.hasUser().observe(getViewLifecycleOwner(), hasUser -> { + mSwipeRefreshLayout.setRefreshing(false); + if (hasUser) { + mFetchUserListingInfoLinearLayout.setVisibility(View.GONE); + } else { + mFetchUserListingInfoLinearLayout.setOnClickListener(view -> { + //Do nothing + }); + showErrorView(R.string.no_users); + } + }); + + mUserListingViewModel.getInitialLoadingState().observe(getViewLifecycleOwner(), networkState -> { + if (networkState.getStatus().equals(NetworkState.Status.SUCCESS)) { + mSwipeRefreshLayout.setRefreshing(false); + } else if (networkState.getStatus().equals(NetworkState.Status.FAILED)) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchUserListingInfoLinearLayout.setOnClickListener(view -> refresh()); + showErrorView(R.string.search_users_error); + } else { + mSwipeRefreshLayout.setRefreshing(true); + } + }); + + mUserListingViewModel.getPaginationNetworkState().observe(getViewLifecycleOwner(), networkState -> { + mAdapter.setNetworkState(networkState); + }); + + mSwipeRefreshLayout.setOnRefreshListener(() -> mUserListingViewModel.refresh()); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + mActivity = (Activity) context; + } + + private void showErrorView(int stringResId) { + if (getActivity() != null && isAdded()) { + mSwipeRefreshLayout.setRefreshing(false); + mFetchUserListingInfoLinearLayout.setVisibility(View.VISIBLE); + mFetchUserListingInfoTextView.setText(stringResId); + Glide.with(this).load(R.drawable.error_image).into(mFetchUserListingInfoImageView); + } + } + + public void changeSortType(SortType sortType) { + mSortTypeSharedPreferences.edit().putString(SharedPreferencesUtils.SORT_TYPE_SEARCH_USER, sortType.getType().name()).apply(); + mUserListingViewModel.changeSortType(sortType); + this.sortType = sortType; + } + + @Override + public void refresh() { + mFetchUserListingInfoLinearLayout.setVisibility(View.GONE); + mUserListingViewModel.refresh(); + mAdapter.setNetworkState(null); + } + + @Override + public void applyTheme() { + mSwipeRefreshLayout.setProgressBackgroundColorSchemeColor(customThemeWrapper.getCircularProgressBarBackground()); + mSwipeRefreshLayout.setColorSchemeColors(customThemeWrapper.getColorAccent()); + mFetchUserListingInfoTextView.setTextColor(customThemeWrapper.getSecondaryTextColor()); + } + + public void goBackToTop() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } + + public SortType getSortType() { + return sortType; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java new file mode 100644 index 00000000..66d63fa8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurImageFragment.java @@ -0,0 +1,264 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.fragment.app.Fragment; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; +import com.davemorrissey.labs.subscaleview.ImageSource; +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; + +import java.io.File; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.ViewImgurMediaActivity; +import ml.docilealligator.infinityforreddit.asynctasks.SaveBitmapImageToFileAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SetAsWallpaperBottomSheetFragment; +import ml.docilealligator.infinityforreddit.BuildConfig; +import ml.docilealligator.infinityforreddit.ImgurMedia; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.services.DownloadMediaService; +import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; + +public class ViewImgurImageFragment extends Fragment { + + public static final String EXTRA_IMGUR_IMAGES = "EII"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; + + @BindView(R.id.progress_bar_view_imgur_image_fragment) + ProgressBar progressBar; + @BindView(R.id.image_view_view_imgur_image_fragment) + SubsamplingScaleImageView imageView; + @BindView(R.id.load_image_error_linear_layout_view_imgur_image_fragment) + LinearLayout errorLinearLayout; + + private ViewImgurMediaActivity activity; + private RequestManager glide; + private ImgurMedia imgurMedia; + private boolean isDownloading = false; + private boolean isActionBarHidden = false; + + public ViewImgurImageFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_view_imgur_images, container, false); + + ButterKnife.bind(this, rootView); + + setHasOptionsMenu(true); + + imgurMedia = getArguments().getParcelable(EXTRA_IMGUR_IMAGES); + glide = Glide.with(activity); + loadImage(); + + imageView.setOnClickListener(view -> { + if (isActionBarHidden) { + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + isActionBarHidden = false; + } else { + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE); + isActionBarHidden = true; + } + }); + + errorLinearLayout.setOnClickListener(view -> { + progressBar.setVisibility(View.VISIBLE); + errorLinearLayout.setVisibility(View.GONE); + loadImage(); + }); + + return rootView; + } + + private void loadImage() { + glide.asBitmap().load(imgurMedia.getLink()).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + return false; + } + + @Override + public boolean onResourceReady(Bitmap resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + progressBar.setVisibility(View.GONE); + return false; + } + }).into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + imageView.setImage(ImageSource.bitmap(resource)); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.view_imgur_image_fragment, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.action_download_view_imgur_image_fragment: + if (isDownloading) { + return false; + } + + isDownloading = true; + + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + + return true; + case R.id.action_share_view_imgur_image_fragment: + glide.asBitmap().load(imgurMedia.getLink()).into(new CustomTarget() { + + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + if (activity.getExternalCacheDir() != null) { + Toast.makeText(activity, R.string.save_image_first, Toast.LENGTH_SHORT).show(); + new SaveBitmapImageToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), + imgurMedia.getFileName(), + new SaveBitmapImageToFileAsyncTask.SaveBitmapImageToFileAsyncTaskListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(activity, + BuildConfig.APPLICATION_ID + ".provider", imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(activity, + R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); + } + }).execute(); + } else { + Toast.makeText(activity, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + return true; + case R.id.action_set_wallpaper_view_imgur_image_fragment: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); + setAsWallpaperBottomSheetFragment.setArguments(bundle); + setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); + } else { + ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); + } + return true; + } + + return false; + } + + private void download() { + isDownloading = false; + + Intent intent = new Intent(activity, DownloadMediaService.class); + intent.putExtra(DownloadMediaService.EXTRA_URL, imgurMedia.getLink()); + intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_IMAGE); + intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, imgurMedia.getFileName()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + activity.startForegroundService(intent); + } else { + activity.startService(intent); + } + Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + isDownloading = false; + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (ViewImgurMediaActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java new file mode 100644 index 00000000..e95306bb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewImgurVideoFragment.java @@ -0,0 +1,289 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.Manifest; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; + +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.source.ProgressiveMediaSource; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelection; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.trackselection.TrackSelector; +import com.google.android.exoplayer2.ui.PlayerView; +import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.util.Util; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ImgurMedia; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.services.DownloadMediaService; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class ViewImgurVideoFragment extends Fragment { + + public static final String EXTRA_IMGUR_VIDEO = "EIV"; + private static final String IS_MUTE_STATE = "IMS"; + private static final String POSITION_STATE = "PS"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; + @BindView(R.id.player_view_view_imgur_video_fragment) + PlayerView videoPlayerView; + @BindView(R.id.mute_exo_playback_control_view) + ImageButton muteButton; + private Activity activity; + private ImgurMedia imgurMedia; + private SimpleExoPlayer player; + private DataSource.Factory dataSourceFactory; + private boolean wasPlaying = false; + private boolean isMute = false; + private boolean isDownloading = false; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + + public ViewImgurVideoFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_view_imgur_video, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + setHasOptionsMenu(true); + + activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); + + imgurMedia = getArguments().getParcelable(EXTRA_IMGUR_VIDEO); + + if (!mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_IGNORE_NAV_BAR, false)) { + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { + //Set player controller bottom margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); + params.bottomMargin = getResources().getDimensionPixelSize(resourceId); + } else { + //Set player controller right margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); + params.rightMargin = getResources().getDimensionPixelSize(resourceId); + } + } + + videoPlayerView.setControllerVisibilityListener(visibility -> { + switch (visibility) { + case View.GONE: + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE); + break; + case View.VISIBLE: + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } + }); + + TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); + TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); + player = ExoPlayerFactory.newSimpleInstance(activity, trackSelector); + videoPlayerView.setPlayer(player); + dataSourceFactory = new DefaultDataSourceFactory(activity, + Util.getUserAgent(activity, "Infinity")); + player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(imgurMedia.getLink()))); + preparePlayer(savedInstanceState); + + return rootView; + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.view_imgur_video_fragment, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_download_view_imgur_video_fragment) { + isDownloading = true; + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + return true; + } + return false; + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + isDownloading = false; + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + } + } + + private void download() { + isDownloading = false; + + Intent intent = new Intent(activity, DownloadMediaService.class); + intent.putExtra(DownloadMediaService.EXTRA_URL, imgurMedia.getLink()); + intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_VIDEO); + intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, imgurMedia.getFileName()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + activity.startForegroundService(intent); + } else { + activity.startService(intent); + } + Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + private void preparePlayer(Bundle savedInstanceState) { + player.setRepeatMode(Player.REPEAT_MODE_ALL); + wasPlaying = true; + + boolean muteVideo = mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_VIDEO, false); + + if (savedInstanceState != null) { + long position = savedInstanceState.getLong(POSITION_STATE); + if (position > 0) { + player.seekTo(position); + } + isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); + if (isMute) { + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + } else if (muteVideo) { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + + player.addListener(new Player.EventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + muteButton.setVisibility(View.VISIBLE); + muteButton.setOnClickListener(view -> { + if (isMute) { + isMute = false; + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } else { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } + }); + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + }); + } + + @Override + public void onResume() { + super.onResume(); + if (wasPlaying) { + player.setPlayWhenReady(true); + } + } + + @Override + public void onPause() { + super.onPause(); + wasPlaying = player.getPlayWhenReady(); + player.setPlayWhenReady(false); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_MUTE_STATE, isMute); + outState.putLong(POSITION_STATE, player.getCurrentPosition()); + } + + @Override + public void onDestroy() { + super.onDestroy(); + player.release(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java new file mode 100644 index 00000000..7c03154e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryImageOrGifFragment.java @@ -0,0 +1,381 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; +import androidx.core.content.FileProvider; +import androidx.fragment.app.Fragment; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.engine.GlideException; +import com.bumptech.glide.load.resource.gif.GifDrawable; +import com.bumptech.glide.request.RequestListener; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; +import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView; +import com.github.piasy.biv.BigImageViewer; +import com.github.piasy.biv.loader.ImageLoader; +import com.github.piasy.biv.loader.glide.GlideImageLoader; +import com.github.piasy.biv.view.BigImageView; +import com.github.piasy.biv.view.GlideImageViewFactory; + +import java.io.File; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.activities.ViewRedditGalleryActivity; +import ml.docilealligator.infinityforreddit.asynctasks.SaveBitmapImageToFileAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.SaveGIFToFileAsyncTask; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.SetAsWallpaperBottomSheetFragment; +import ml.docilealligator.infinityforreddit.BuildConfig; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.services.DownloadMediaService; +import ml.docilealligator.infinityforreddit.SetAsWallpaperCallback; + +public class ViewRedditGalleryImageOrGifFragment extends Fragment { + + public static final String EXTRA_REDDIT_GALLERY_MEDIA = "ERGM"; + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; + + @BindView(R.id.progress_bar_view_reddit_gallery_image_or_gif_fragment) + ProgressBar progressBar; + @BindView(R.id.image_view_view_reddit_gallery_image_or_gif_fragment) + BigImageView imageView; + @BindView(R.id.load_image_error_linear_layout_view_reddit_gallery_image_or_gif_fragment) + LinearLayout errorLinearLayout; + + private ViewRedditGalleryActivity activity; + private RequestManager glide; + private Post.Gallery media; + private String subredditName; + private boolean isDownloading = false; + private boolean isActionBarHidden = false; + + public ViewRedditGalleryImageOrGifFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + BigImageViewer.initialize(GlideImageLoader.with(activity)); + + View rootView = inflater.inflate(R.layout.fragment_view_reddit_gallery_image_or_gif, container, false); + + ButterKnife.bind(this, rootView); + + setHasOptionsMenu(true); + + media = getArguments().getParcelable(EXTRA_REDDIT_GALLERY_MEDIA); + subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); + glide = Glide.with(activity); + + imageView.setImageViewFactory(new GlideImageViewFactory()); + + imageView.setImageLoaderCallback(new ImageLoader.Callback() { + @Override + public void onCacheHit(int imageType, File image) { + + } + + @Override + public void onCacheMiss(int imageType, File image) { + + } + + @Override + public void onStart() { + + } + + @Override + public void onProgress(int progress) { + + } + + @Override + public void onFinish() { + + } + + @Override + public void onSuccess(File image) { + progressBar.setVisibility(View.GONE); + + final SubsamplingScaleImageView view = imageView.getSSIV(); + + if (view != null) { + view.setMinimumDpi(80); + + view.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() { + @Override + public void onReady() { + + } + + @Override + public void onImageLoaded() { + view.setDoubleTapZoomDpi(70); + view.setDoubleTapZoomStyle(SubsamplingScaleImageView.ZOOM_FOCUS_FIXED); + view.setQuickScaleEnabled(true); + } + + @Override + public void onPreviewLoadError(Exception e) { + + } + + @Override + public void onImageLoadError(Exception e) { + + } + + @Override + public void onTileLoadError(Exception e) { + + } + + @Override + public void onPreviewReleased() { + + } + }); + } + } + + @Override + public void onFail(Exception error) { + progressBar.setVisibility(View.GONE); + errorLinearLayout.setVisibility(View.VISIBLE); + } + }); + + loadImage(); + + imageView.setOnClickListener(view -> { + if (isActionBarHidden) { + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + isActionBarHidden = false; + } else { + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE); + isActionBarHidden = true; + } + }); + + errorLinearLayout.setOnClickListener(view -> { + progressBar.setVisibility(View.VISIBLE); + errorLinearLayout.setVisibility(View.GONE); + loadImage(); + }); + + return rootView; + } + + private void loadImage() { + imageView.showImage(Uri.parse(media.url)); + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.view_reddit_gallery_image_or_gif_fragment, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.action_download_view_reddit_gallery_image_or_gif_fragment: + if (isDownloading) { + return false; + } + + isDownloading = true; + + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + + return true; + case R.id.action_share_view_reddit_gallery_image_or_gif_fragment: + if (media.mediaType == Post.Gallery.TYPE_GIF) { + shareGif(); + } else { + shareImage(); + } + return true; + case R.id.action_set_wallpaper_view_reddit_gallery_image_or_gif_fragment: + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + SetAsWallpaperBottomSheetFragment setAsWallpaperBottomSheetFragment = new SetAsWallpaperBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putInt(SetAsWallpaperBottomSheetFragment.EXTRA_VIEW_PAGER_POSITION, activity.getCurrentPagePosition()); + setAsWallpaperBottomSheetFragment.setArguments(bundle); + setAsWallpaperBottomSheetFragment.show(activity.getSupportFragmentManager(), setAsWallpaperBottomSheetFragment.getTag()); + } else { + ((SetAsWallpaperCallback) activity).setToBoth(activity.getCurrentPagePosition()); + } + return true; + } + + return false; + } + + private void download() { + isDownloading = false; + + Intent intent = new Intent(activity, DownloadMediaService.class); + intent.putExtra(DownloadMediaService.EXTRA_URL, media.url); + intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, media.mediaType == Post.Gallery.TYPE_GIF ? DownloadMediaService.EXTRA_MEDIA_TYPE_GIF: DownloadMediaService.EXTRA_MEDIA_TYPE_IMAGE); + intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, media.fileName); + intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, subredditName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + activity.startForegroundService(intent); + } else { + activity.startService(intent); + } + Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + private void shareImage() { + glide.asBitmap().load(media.url).into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + if (activity.getExternalCacheDir() != null) { + Toast.makeText(activity, R.string.save_image_first, Toast.LENGTH_SHORT).show(); + new SaveBitmapImageToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), + media.fileName, + new SaveBitmapImageToFileAsyncTask.SaveBitmapImageToFileAsyncTaskListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(activity, + BuildConfig.APPLICATION_ID + ".provider", imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(activity, + R.string.cannot_save_image, Toast.LENGTH_SHORT).show(); + } + }).execute(); + } else { + Toast.makeText(activity, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + } + + private void shareGif() { + Toast.makeText(activity, R.string.save_gif_first, Toast.LENGTH_SHORT).show(); + glide.asGif().load(media.url).listener(new RequestListener() { + @Override + public boolean onLoadFailed(@Nullable GlideException e, Object model, Target target, boolean isFirstResource) { + return false; + } + + @Override + public boolean onResourceReady(GifDrawable resource, Object model, Target target, DataSource dataSource, boolean isFirstResource) { + if (activity.getExternalCacheDir() != null) { + new SaveGIFToFileAsyncTask(resource, activity.getExternalCacheDir().getPath(), media.fileName, + new SaveGIFToFileAsyncTask.SaveGIFToFileAsyncTaskListener() { + @Override + public void saveSuccess(File imageFile) { + Uri uri = FileProvider.getUriForFile(activity, + BuildConfig.APPLICATION_ID + ".provider", imageFile); + Intent shareIntent = new Intent(); + shareIntent.setAction(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_STREAM, uri); + shareIntent.setType("image/*"); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))); + } + + @Override + public void saveFailed() { + Toast.makeText(activity, + R.string.cannot_save_gif, Toast.LENGTH_SHORT).show(); + } + }).execute(); + } else { + Toast.makeText(activity, + R.string.cannot_get_storage, Toast.LENGTH_SHORT).show(); + } + return false; + } + }).submit(); + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + isDownloading = false; + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (ViewRedditGalleryActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java new file mode 100644 index 00000000..e2d16f22 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewRedditGalleryVideoFragment.java @@ -0,0 +1,293 @@ +package ml.docilealligator.infinityforreddit.fragments; + +import android.Manifest; +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageButton; +import android.widget.LinearLayout; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; +import androidx.fragment.app.Fragment; + +import com.google.android.exoplayer2.ExoPlayerFactory; +import com.google.android.exoplayer2.Player; +import com.google.android.exoplayer2.SimpleExoPlayer; +import com.google.android.exoplayer2.source.ProgressiveMediaSource; +import com.google.android.exoplayer2.source.TrackGroupArray; +import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection; +import com.google.android.exoplayer2.trackselection.DefaultTrackSelector; +import com.google.android.exoplayer2.trackselection.TrackSelection; +import com.google.android.exoplayer2.trackselection.TrackSelectionArray; +import com.google.android.exoplayer2.trackselection.TrackSelector; +import com.google.android.exoplayer2.ui.PlayerView; +import com.google.android.exoplayer2.upstream.DataSource; +import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory; +import com.google.android.exoplayer2.util.Util; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.services.DownloadMediaService; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class ViewRedditGalleryVideoFragment extends Fragment { + + public static final String EXTRA_REDDIT_GALLERY_VIDEO = "EIV"; + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + private static final String IS_MUTE_STATE = "IMS"; + private static final String POSITION_STATE = "PS"; + private static final int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 0; + @BindView(R.id.player_view_view_reddit_gallery_video_fragment) + PlayerView videoPlayerView; + @BindView(R.id.mute_exo_playback_control_view) + ImageButton muteButton; + private Activity activity; + private Post.Gallery galleryVideo; + private String subredditName; + private SimpleExoPlayer player; + private DataSource.Factory dataSourceFactory; + private boolean wasPlaying = false; + private boolean isMute = false; + private boolean isDownloading = false; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + + public ViewRedditGalleryVideoFragment() { + // Required empty public constructor + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_view_reddit_gallery_video, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + setHasOptionsMenu(true); + + activity.setVolumeControlStream(AudioManager.STREAM_MUSIC); + + galleryVideo = getArguments().getParcelable(EXTRA_REDDIT_GALLERY_VIDEO); + subredditName = getArguments().getString(EXTRA_SUBREDDIT_NAME); + + if (!mSharedPreferences.getBoolean(SharedPreferencesUtils.VIDEO_PLAYER_IGNORE_NAV_BAR, false)) { + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT || getResources().getBoolean(R.bool.isTablet)) { + //Set player controller bottom margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); + params.bottomMargin = getResources().getDimensionPixelSize(resourceId); + } else { + //Set player controller right margin in order to display it above the navbar + int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android"); + LinearLayout controllerLinearLayout = rootView.findViewById(R.id.linear_layout_exo_playback_control_view); + ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) controllerLinearLayout.getLayoutParams(); + params.rightMargin = getResources().getDimensionPixelSize(resourceId); + } + } + + videoPlayerView.setControllerVisibilityListener(visibility -> { + switch (visibility) { + case View.GONE: + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_IMMERSIVE); + break; + case View.VISIBLE: + activity.getWindow().getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + } + }); + + TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(); + TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); + player = ExoPlayerFactory.newSimpleInstance(activity, trackSelector); + videoPlayerView.setPlayer(player); + dataSourceFactory = new DefaultDataSourceFactory(activity, + Util.getUserAgent(activity, "Infinity")); + player.prepare(new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(Uri.parse(galleryVideo.url))); + preparePlayer(savedInstanceState); + + return rootView; + } + + @Override + public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) { + inflater.inflate(R.menu.view_reddit_gallery_video_fragment, menu); + super.onCreateOptionsMenu(menu, inflater); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == R.id.action_download_view_reddit_gallery_video_fragment) { + isDownloading = true; + if (Build.VERSION.SDK_INT >= 23) { + if (ContextCompat.checkSelfPermission(activity, + Manifest.permission.WRITE_EXTERNAL_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + + // Permission is not granted + // No explanation needed; request the permission + requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, + PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE); + } else { + // Permission has already been granted + download(); + } + } else { + download(); + } + return true; + } + return false; + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE && grantResults.length > 0) { + if (grantResults[0] == PackageManager.PERMISSION_DENIED) { + Toast.makeText(activity, R.string.no_storage_permission, Toast.LENGTH_SHORT).show(); + isDownloading = false; + } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED && isDownloading) { + download(); + } + } + } + + private void download() { + isDownloading = false; + + Intent intent = new Intent(activity, DownloadMediaService.class); + intent.putExtra(DownloadMediaService.EXTRA_URL, galleryVideo.url); + intent.putExtra(DownloadMediaService.EXTRA_MEDIA_TYPE, DownloadMediaService.EXTRA_MEDIA_TYPE_VIDEO); + intent.putExtra(DownloadMediaService.EXTRA_FILE_NAME, galleryVideo.fileName); + intent.putExtra(DownloadMediaService.EXTRA_SUBREDDIT_NAME, subredditName); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + activity.startForegroundService(intent); + } else { + activity.startService(intent); + } + Toast.makeText(activity, R.string.download_started, Toast.LENGTH_SHORT).show(); + } + + private void preparePlayer(Bundle savedInstanceState) { + player.setRepeatMode(Player.REPEAT_MODE_ALL); + wasPlaying = true; + + boolean muteVideo = mSharedPreferences.getBoolean(SharedPreferencesUtils.MUTE_VIDEO, false); + + if (savedInstanceState != null) { + long position = savedInstanceState.getLong(POSITION_STATE); + if (position > 0) { + player.seekTo(position); + } + isMute = savedInstanceState.getBoolean(IS_MUTE_STATE); + if (isMute) { + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + } else if (muteVideo) { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } else { + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } + + player.addListener(new Player.EventListener() { + @Override + public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { + if (!trackGroups.isEmpty()) { + for (int i = 0; i < trackGroups.length; i++) { + String mimeType = trackGroups.get(i).getFormat(0).sampleMimeType; + if (mimeType != null && mimeType.contains("audio")) { + muteButton.setVisibility(View.VISIBLE); + muteButton.setOnClickListener(view -> { + if (isMute) { + isMute = false; + player.setVolume(1f); + muteButton.setImageResource(R.drawable.ic_unmute_24dp); + } else { + isMute = true; + player.setVolume(0f); + muteButton.setImageResource(R.drawable.ic_mute_24dp); + } + }); + break; + } + } + } else { + muteButton.setVisibility(View.GONE); + } + } + }); + } + + @Override + public void onResume() { + super.onResume(); + if (wasPlaying) { + player.setPlayWhenReady(true); + } + } + + @Override + public void onPause() { + super.onPause(); + wasPlaying = player.getPlayWhenReady(); + player.setPlayWhenReady(false); + } + + @Override + public void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(IS_MUTE_STATE, isMute); + outState.putLong(POSITION_STATE, player.getCurrentPosition()); + } + + @Override + public void onDestroy() { + super.onDestroy(); + player.release(); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/ComposeMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ComposeMessage.java new file mode 100644 index 00000000..5411d96e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ComposeMessage.java @@ -0,0 +1,58 @@ +package ml.docilealligator.infinityforreddit.message; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class ComposeMessage { + public static void composeMessage(Retrofit oauthRetrofit, String accessToken, Locale locale, String username, + String subject, String message, ComposeMessageListener composeMessageListener) { + Map headers = APIUtils.getOAuthHeader(accessToken); + Map params = new HashMap<>(); + params.put(APIUtils.API_TYPE_KEY, "json"); + params.put(APIUtils.RETURN_RTJSON_KEY, "true"); + params.put(APIUtils.SUBJECT_KEY, subject); + params.put(APIUtils.TEXT_KEY, message); + params.put(APIUtils.TO_KEY, username); + + oauthRetrofit.create(RedditAPI.class).composePrivateMessage(headers, params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseMessage.parseComposedMessageError(response.body(), new ParseMessage.ParseComposedMessageErrorListener() { + @Override + public void noError() { + composeMessageListener.composeMessageSuccess(); + } + + @Override + public void error(String errorMessage) { + composeMessageListener.composeMessageFailed(errorMessage); + } + }); + } else { + composeMessageListener.composeMessageFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + composeMessageListener.composeMessageFailed(t.getMessage()); + } + }); + } + + public interface ComposeMessageListener { + void composeMessageSuccess(); + void composeMessageFailed(String errorMessage); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/FetchMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/FetchMessage.java new file mode 100644 index 00000000..78689fd6 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/FetchMessage.java @@ -0,0 +1,53 @@ +package ml.docilealligator.infinityforreddit.message; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchMessage { + + public static final String WHERE_INBOX = "inbox"; + public static final String WHERE_UNREAD = "unread"; + public static final String WHERE_SENT = "sent"; + public static final String WHERE_COMMENTS = "comments"; + public static final String WHERE_MESSAGES = "messages"; + public static final String WHERE_MESSAGES_DETAIL = "messages_detail"; + public static final int MESSAGE_TYPE_INBOX = 0; + public static final int MESSAGE_TYPE_PRIVATE_MESSAGE = 1; + public static final int MESSAGE_TYPE_NOTIFICATION = 2; + + static void fetchInbox(Retrofit oauthRetrofit, Locale locale, String accessToken, String where, + String after, int messageType, FetchMessagesListener fetchMessagesListener) { + oauthRetrofit.create(RedditAPI.class).getMessages(APIUtils.getOAuthHeader(accessToken), where, after) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseMessage.parseMessage(response.body(), locale, messageType, fetchMessagesListener::fetchSuccess); + } else { + fetchMessagesListener.fetchFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchMessagesListener.fetchFailed(); + } + }); + } + + interface FetchMessagesListener { + void fetchSuccess(ArrayList messages, @Nullable String after); + + void fetchFailed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/Message.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/Message.java new file mode 100644 index 00000000..eb3524c9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/Message.java @@ -0,0 +1,221 @@ +package ml.docilealligator.infinityforreddit.message; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; + +public class Message implements Parcelable { + public static final String TYPE_COMMENT = "t1"; + public static final String TYPE_ACCOUNT = "t2"; + public static final String TYPE_LINK = "t3"; + public static final String TYPE_MESSAGE = "t4"; + public static final String TYPE_SUBREDDIT = "t5"; + static final String TYPE_AWARD = "t6"; + + private String kind; + private String subredditName; + private String subredditNamePrefixed; + private String id; + private String fullname; + private String subject; + private String author; + private String destination; + private String parentFullName; + private String title; + private String body; + private String context; + private String distinguished; + private String formattedTime; + private boolean wasComment; + private boolean isNew; + private int score; + private int nComments; + private long timeUTC; + private ArrayList replies; + + Message(String kind, String subredditName, String subredditNamePrefixed, String id, String fullname, + String subject, String author, String destination, String parentFullName, String title, String body, + String context, String distinguished, String formattedTime, boolean wasComment, boolean isNew, + int score, int nComments, long timeUTC) { + this.kind = kind; + this.subredditName = subredditName; + this.subredditNamePrefixed = subredditNamePrefixed; + this.id = id; + this.fullname = fullname; + this.subject = subject; + this.author = author; + this.destination = destination; + this.parentFullName = parentFullName; + this.title = title; + this.body = body; + this.context = context; + this.distinguished = distinguished; + this.formattedTime = formattedTime; + this.wasComment = wasComment; + this.isNew = isNew; + this.score = score; + this.nComments = nComments; + this.timeUTC = timeUTC; + } + + + protected Message(Parcel in) { + kind = in.readString(); + subredditName = in.readString(); + subredditNamePrefixed = in.readString(); + id = in.readString(); + fullname = in.readString(); + subject = in.readString(); + author = in.readString(); + destination = in.readString(); + parentFullName = in.readString(); + title = in.readString(); + body = in.readString(); + context = in.readString(); + distinguished = in.readString(); + formattedTime = in.readString(); + wasComment = in.readByte() != 0; + isNew = in.readByte() != 0; + score = in.readInt(); + nComments = in.readInt(); + timeUTC = in.readLong(); + replies = in.createTypedArrayList(Message.CREATOR); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Message createFromParcel(Parcel in) { + return new Message(in); + } + + @Override + public Message[] newArray(int size) { + return new Message[size]; + } + }; + + public String getKind() { + return kind; + } + + public String getSubredditName() { + return subredditName; + } + + public String getSubredditNamePrefixed() { + return subredditNamePrefixed; + } + + public String getId() { + return id; + } + + public String getFullname() { + return fullname; + } + + public String getSubject() { + return subject; + } + + public String getAuthor() { + return author; + } + + public String getDestination() { + return destination; + } + + public String getParentFullName() { + return parentFullName; + } + + public String getTitle() { + return title; + } + + public String getBody() { + return body; + } + + public String getContext() { + return context; + } + + public String getDistinguished() { + return distinguished; + } + + public String getFormattedTime() { + return formattedTime; + } + + public boolean wasComment() { + return wasComment; + } + + public boolean isNew() { + return isNew; + } + + public void setNew(boolean isNew) { + this.isNew = isNew; + } + + public int getScore() { + return score; + } + + public int getnComments() { + return nComments; + } + + public long getTimeUTC() { + return timeUTC; + } + + public ArrayList getReplies() { + return replies; + } + + public void setReplies(ArrayList replies) { + this.replies = replies; + } + + public void addReply(Message reply) { + if (replies == null) { + replies = new ArrayList<>(); + } + replies.add(reply); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(kind); + parcel.writeString(subredditName); + parcel.writeString(subredditNamePrefixed); + parcel.writeString(id); + parcel.writeString(fullname); + parcel.writeString(subject); + parcel.writeString(author); + parcel.writeString(destination); + parcel.writeString(parentFullName); + parcel.writeString(title); + parcel.writeString(body); + parcel.writeString(context); + parcel.writeString(distinguished); + parcel.writeString(formattedTime); + parcel.writeByte((byte) (wasComment ? 1 : 0)); + parcel.writeByte((byte) (isNew ? 1 : 0)); + parcel.writeInt(score); + parcel.writeInt(nComments); + parcel.writeLong(timeUTC); + parcel.writeTypedList(replies); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSource.java new file mode 100644 index 00000000..37a55509 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSource.java @@ -0,0 +1,119 @@ +package ml.docilealligator.infinityforreddit.message; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.PageKeyedDataSource; + +import java.util.ArrayList; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.NetworkState; +import retrofit2.Retrofit; + +class MessageDataSource extends PageKeyedDataSource { + private Retrofit oauthRetrofit; + private Locale locale; + private String accessToken; + private String where; + private int messageType; + + private MutableLiveData paginationNetworkStateLiveData; + private MutableLiveData initialLoadStateLiveData; + private MutableLiveData hasPostLiveData; + + private LoadParams params; + private LoadCallback callback; + + MessageDataSource(Retrofit oauthRetrofit, Locale locale, String accessToken, String where) { + this.oauthRetrofit = oauthRetrofit; + this.locale = locale; + this.accessToken = accessToken; + this.where = where; + if (where.equals(FetchMessage.WHERE_MESSAGES)) { + messageType = FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE; + } else { + messageType = FetchMessage.MESSAGE_TYPE_INBOX; + } + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasPostLiveData = new MutableLiveData<>(); + } + + MutableLiveData getPaginationNetworkStateLiveData() { + return paginationNetworkStateLiveData; + } + + MutableLiveData getInitialLoadStateLiveData() { + return initialLoadStateLiveData; + } + + MutableLiveData hasPostLiveData() { + return hasPostLiveData; + } + + void retryLoadingMore() { + loadAfter(params, callback); + } + + @Override + public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { + initialLoadStateLiveData.postValue(NetworkState.LOADING); + + FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, null, messageType, + new FetchMessage.FetchMessagesListener() { + @Override + public void fetchSuccess(ArrayList messages, @Nullable String after) { + if (messages.size() == 0) { + hasPostLiveData.postValue(false); + } else { + hasPostLiveData.postValue(true); + } + + if (after == null || after.equals("") || after.equals("null")) { + callback.onResult(messages, null, null); + } else { + callback.onResult(messages, null, after); + } + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void fetchFailed() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetch messages")); + } + }); + } + + @Override + public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { + + } + + @Override + public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { + this.params = params; + this.callback = callback; + + paginationNetworkStateLiveData.postValue(NetworkState.LOADING); + + FetchMessage.fetchInbox(oauthRetrofit, locale, accessToken, where, params.key, messageType, + new FetchMessage.FetchMessagesListener() { + @Override + public void fetchSuccess(ArrayList messages, @Nullable String after) { + if (after == null || after.equals("") || after.equals("null")) { + callback.onResult(messages, null); + } else { + callback.onResult(messages, after); + } + + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void fetchFailed() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error fetching data")); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSourceFactory.java new file mode 100644 index 00000000..f7baf668 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageDataSourceFactory.java @@ -0,0 +1,47 @@ +package ml.docilealligator.infinityforreddit.message; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.DataSource; + +import java.util.Locale; + +import retrofit2.Retrofit; + +class MessageDataSourceFactory extends DataSource.Factory { + private Retrofit oauthRetrofit; + private Locale locale; + private String accessToken; + private String where; + + private MessageDataSource messageDataSource; + private MutableLiveData messageDataSourceLiveData; + + MessageDataSourceFactory(Retrofit oauthRetrofit, Locale locale, String accessToken, String where) { + this.oauthRetrofit = oauthRetrofit; + this.locale = locale; + this.accessToken = accessToken; + this.where = where; + messageDataSourceLiveData = new MutableLiveData<>(); + } + + @NonNull + @Override + public DataSource create() { + messageDataSource = new MessageDataSource(oauthRetrofit, locale, accessToken, where); + messageDataSourceLiveData.postValue(messageDataSource); + return messageDataSource; + } + + public MutableLiveData getMessageDataSourceLiveData() { + return messageDataSourceLiveData; + } + + MessageDataSource getMessageDataSource() { + return messageDataSource; + } + + void changeWhere(String where) { + this.where = where; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageViewModel.java new file mode 100644 index 00000000..27833e82 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/MessageViewModel.java @@ -0,0 +1,97 @@ +package ml.docilealligator.infinityforreddit.message; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Transformations; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.LivePagedListBuilder; +import androidx.paging.PagedList; + +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.NetworkState; +import retrofit2.Retrofit; + +public class MessageViewModel extends ViewModel { + private MessageDataSourceFactory messageDataSourceFactory; + private LiveData paginationNetworkState; + private LiveData initialLoadingState; + private LiveData hasMessageLiveData; + private LiveData> messages; + private MutableLiveData whereLiveData; + + public MessageViewModel(Retrofit retrofit, Locale locale, String accessToken, String where) { + messageDataSourceFactory = new MessageDataSourceFactory(retrofit, locale, accessToken, where); + + initialLoadingState = Transformations.switchMap(messageDataSourceFactory.getMessageDataSourceLiveData(), + MessageDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(messageDataSourceFactory.getMessageDataSourceLiveData(), + MessageDataSource::getPaginationNetworkStateLiveData); + hasMessageLiveData = Transformations.switchMap(messageDataSourceFactory.getMessageDataSourceLiveData(), + MessageDataSource::hasPostLiveData); + + whereLiveData = new MutableLiveData<>(); + whereLiveData.postValue(where); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + messages = Transformations.switchMap(whereLiveData, newWhere -> { + messageDataSourceFactory.changeWhere(whereLiveData.getValue()); + return (new LivePagedListBuilder(messageDataSourceFactory, pagedListConfig)).build(); + }); + } + + public LiveData> getMessages() { + return messages; + } + + public LiveData getPaginationNetworkState() { + return paginationNetworkState; + } + + public LiveData getInitialLoadingState() { + return initialLoadingState; + } + + public LiveData hasMessage() { + return hasMessageLiveData; + } + + public void refresh() { + messageDataSourceFactory.getMessageDataSource().invalidate(); + } + + public void retryLoadingMore() { + messageDataSourceFactory.getMessageDataSource().retryLoadingMore(); + } + + void changeWhere(String where) { + whereLiveData.postValue(where); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Retrofit retrofit; + private Locale locale; + private String accessToken; + private String where; + + public Factory(Retrofit retrofit, Locale locale, String accessToken, String where) { + this.retrofit = retrofit; + this.locale = locale; + this.accessToken = accessToken; + this.where = where; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new MessageViewModel(retrofit, locale, accessToken, where); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/ParseMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ParseMessage.java new file mode 100644 index 00000000..5ffe40a8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ParseMessage.java @@ -0,0 +1,242 @@ +package ml.docilealligator.infinityforreddit.message; + +import android.os.AsyncTask; + +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; + +public class ParseMessage { + public static void parseMessage(String response, Locale locale, int messageType, + ParseMessageAsyncTaskListener parseMessageAsnycTaskListener) { + new ParseMessageAsnycTask(response, locale, messageType, parseMessageAsnycTaskListener).execute(); + } + + public static ArrayList parseMessages(JSONArray messageArray, Locale locale, int messageType) { + ArrayList messages = new ArrayList<>(); + for (int i = 0; i < messageArray.length(); i++) { + try { + Message message = parseSingleMessage(messageArray.getJSONObject(i), locale, messageType); + if (message != null) { + messages.add(message); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + return messages; + } + + public static void parseRepliedMessage(String response, Locale locale, ParseSentMessageAsyncTaskListener parseSentMessageAsyncTaskListener) { + new ParseSentMessageAsnycTask(response, locale, parseSentMessageAsyncTaskListener).execute(); + } + + public static void parseComposedMessageError(String response, ParseComposedMessageErrorListener parseComposedMessageErrorListener) { + new ParseComposedMessageErrorAsncTask(response, parseComposedMessageErrorListener).execute(); + } + + @Nullable + private static Message parseSingleMessage(JSONObject messageJSON, Locale locale, int messageType) throws JSONException { + String kind = messageJSON.getString(JSONUtils.KIND_KEY); + if ((messageType == FetchMessage.MESSAGE_TYPE_INBOX && kind.equals("t4")) || + (messageType == FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE && !kind.equals("t4"))) { + return null; + } + + JSONObject rawMessageJSON = messageJSON.getJSONObject(JSONUtils.DATA_KEY); + String subredditName = rawMessageJSON.getString(JSONUtils.SUBREDDIT_KEY); + String subredditNamePrefixed = rawMessageJSON.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); + String id = rawMessageJSON.getString(JSONUtils.ID_KEY); + String fullname = rawMessageJSON.getString(JSONUtils.NAME_KEY); + String subject = rawMessageJSON.getString(JSONUtils.SUBJECT_KEY); + String author = rawMessageJSON.getString(JSONUtils.AUTHOR_KEY); + String destination = rawMessageJSON.getString(JSONUtils.DEST_KEY); + String parentFullname = rawMessageJSON.getString(JSONUtils.PARENT_ID_KEY); + String title = rawMessageJSON.has(JSONUtils.LINK_TITLE_KEY) ? rawMessageJSON.getString(JSONUtils.LINK_TITLE_KEY) : null; + String body = Utils.modifyMarkdown(rawMessageJSON.getString(JSONUtils.BODY_KEY)); + String context = rawMessageJSON.getString(JSONUtils.CONTEXT_KEY); + String distinguished = rawMessageJSON.getString(JSONUtils.DISTINGUISHED_KEY); + boolean wasComment = rawMessageJSON.getBoolean(JSONUtils.WAS_COMMENT_KEY); + boolean isNew = rawMessageJSON.getBoolean(JSONUtils.NEW_KEY); + int score = rawMessageJSON.getInt(JSONUtils.SCORE_KEY); + int nComments = rawMessageJSON.isNull(JSONUtils.NUM_COMMENTS_KEY) ? -1 : rawMessageJSON.getInt(JSONUtils.NUM_COMMENTS_KEY); + long timeUTC = rawMessageJSON.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; + + Calendar submitTimeCalendar = Calendar.getInstance(); + submitTimeCalendar.setTimeInMillis(timeUTC); + String formattedTime = new SimpleDateFormat("MMM d, yyyy, HH:mm", + locale).format(submitTimeCalendar.getTime()); + + ArrayList replies = null; + if (!rawMessageJSON.isNull(JSONUtils.REPLIES_KEY) && rawMessageJSON.get(JSONUtils.REPLIES_KEY) instanceof JSONObject) { + JSONArray repliesArray = rawMessageJSON.getJSONObject(JSONUtils.REPLIES_KEY).getJSONObject(JSONUtils.DATA_KEY) + .getJSONArray(JSONUtils.CHILDREN_KEY); + replies = parseMessages(repliesArray, locale, messageType); + } + + Message message = new Message(kind, subredditName, subredditNamePrefixed, id, fullname, subject, + author, destination, parentFullname, title, body, context, distinguished, formattedTime, + wasComment, isNew, score, nComments, timeUTC); + if (replies != null) { + message.setReplies(replies); + } + + return message; + } + + private static class ParseMessageAsnycTask extends AsyncTask { + + private String response; + private Locale locale; + private ArrayList messages; + private String after; + private int messageType; + private ParseMessageAsyncTaskListener parseMessageAsyncTaskListener; + ParseMessageAsnycTask(String response, Locale locale, int messageType, + ParseMessageAsyncTaskListener parseMessageAsnycTaskListener) { + this.response = response; + this.locale = locale; + this.messageType = messageType; + messages = new ArrayList<>(); + this.parseMessageAsyncTaskListener = parseMessageAsnycTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONArray messageArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + messages = parseMessages(messageArray, locale, messageType); + after = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + parseMessageAsyncTaskListener.parseSuccess(messages, after); + } + } + + private static class ParseSentMessageAsnycTask extends AsyncTask { + + private String response; + private Locale locale; + private Message message; + private String errorMessage; + private boolean parseFailed = false; + private ParseSentMessageAsyncTaskListener parseSentMessageAsyncTaskListener; + + ParseSentMessageAsnycTask(String response, Locale locale, ParseSentMessageAsyncTaskListener parseSentMessageAsyncTaskListener) { + this.response = response; + this.locale = locale; + this.parseSentMessageAsyncTaskListener = parseSentMessageAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject messageJSON = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY) + .getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.THINGS_KEY).getJSONObject(0); + message = parseSingleMessage(messageJSON, locale, FetchMessage.MESSAGE_TYPE_PRIVATE_MESSAGE); + } catch (JSONException e) { + e.printStackTrace(); + errorMessage = parseRepliedMessageErrorMessage(response); + parseFailed = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (parseFailed) { + parseSentMessageAsyncTaskListener.parseFailed(errorMessage); + } else { + parseSentMessageAsyncTaskListener.parseSuccess(message); + } + } + } + + private static class ParseComposedMessageErrorAsncTask extends AsyncTask { + private String response; + private ParseComposedMessageErrorListener parseComposedMessageErrorListener; + private String errorMessage; + + ParseComposedMessageErrorAsncTask(String response, ParseComposedMessageErrorListener parseComposedMessageErrorListener) { + this.response = response; + this.parseComposedMessageErrorListener = parseComposedMessageErrorListener; + } + + @Override + protected Void doInBackground(Void... voids) { + errorMessage = parseRepliedMessageErrorMessage(response); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (errorMessage == null) { + parseComposedMessageErrorListener.noError(); + } else { + parseComposedMessageErrorListener.error(errorMessage); + } + } + } + + @Nullable + private static String parseRepliedMessageErrorMessage(String response) { + try { + JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); + + if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) + .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); + if (error.length() != 0) { + String errorString; + if (error.length() >= 2) { + errorString = error.getString(1); + } else { + errorString = error.getString(0); + } + return errorString.substring(0, 1).toUpperCase() + errorString.substring(1); + } else { + return null; + } + } else { + return null; + } + } catch (JSONException e) { + e.printStackTrace(); + } + + return null; + } + + public interface ParseMessageAsyncTaskListener { + void parseSuccess(ArrayList messages, @Nullable String after); + } + + public interface ParseSentMessageAsyncTaskListener { + void parseSuccess(Message message); + void parseFailed(String errorMessage); + } + + public interface ParseComposedMessageErrorListener { + void noError(); + void error(String errorMessage); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/ReadMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ReadMessage.java new file mode 100644 index 00000000..1473a729 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ReadMessage.java @@ -0,0 +1,43 @@ +package ml.docilealligator.infinityforreddit.message; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class ReadMessage { + public static void readMessage(Retrofit oauthRetrofit, String accessToken, String commaSeparatedFullnames, + ReadMessageListener readMessageListener) { + Map params = new HashMap<>(); + params.put(APIUtils.ID_KEY, commaSeparatedFullnames); + oauthRetrofit.create(RedditAPI.class).readMessage(APIUtils.getOAuthHeader(accessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + readMessageListener.readSuccess(); + } else { + readMessageListener.readFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + readMessageListener.readFailed(); + } + }); + } + + public interface ReadMessageListener { + void readSuccess(); + + void readFailed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/message/ReplyMessage.java b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ReplyMessage.java new file mode 100644 index 00000000..acdfbfca --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/message/ReplyMessage.java @@ -0,0 +1,58 @@ +package ml.docilealligator.infinityforreddit.message; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class ReplyMessage { + public static void replyMessage(String messageMarkdown, String thingFullname, + Locale locale, Retrofit oauthRetrofit, String accessToken, + ReplyMessageListener replyMessageListener) { + Map headers = APIUtils.getOAuthHeader(accessToken); + Map params = new HashMap<>(); + params.put(APIUtils.API_TYPE_KEY, "json"); + params.put(APIUtils.RETURN_RTJSON_KEY, "true"); + params.put(APIUtils.TEXT_KEY, messageMarkdown); + params.put(APIUtils.THING_ID_KEY, thingFullname); + + oauthRetrofit.create(RedditAPI.class).sendCommentOrReplyToMessage(headers, params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseMessage.parseRepliedMessage(response.body(), locale, new ParseMessage.ParseSentMessageAsyncTaskListener() { + @Override + public void parseSuccess(Message message) { + replyMessageListener.replyMessageSuccess(message); + } + + @Override + public void parseFailed(String errorMessage) { + replyMessageListener.replyMessageFailed(errorMessage); + } + }); + } else { + replyMessageListener.replyMessageFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + replyMessageListener.replyMessageFailed(t.getMessage()); + } + }); + } + + public interface ReplyMessageListener { + void replyMessageSuccess(Message message); + void replyMessageFailed(String errorMessage); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/CreateMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/CreateMultiReddit.java new file mode 100644 index 00000000..186d8574 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/CreateMultiReddit.java @@ -0,0 +1,56 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class CreateMultiReddit { + public interface CreateMultiRedditListener { + void success(); + void failed(int errorType); + } + + public static void createMultiReddit(Retrofit oauthRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, + String accessToken, String multipath, String model, + CreateMultiRedditListener createMultiRedditListener) { + Map params = new HashMap<>(); + params.put(APIUtils.MULTIPATH_KEY, multipath); + params.put(APIUtils.MODEL_KEY, model); + oauthRetrofit.create(RedditAPI.class).createMultiReddit(APIUtils.getOAuthHeader(accessToken), + params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseMultiReddit.parseAndSaveMultiReddit(response.body(), redditDataRoomDatabase, + new ParseMultiReddit.ParseMultiRedditListener() { + @Override + public void success() { + createMultiRedditListener.success(); + } + + @Override + public void failed() { + createMultiRedditListener.failed(1); + } + }); + } else { + createMultiRedditListener.failed(response.code()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + createMultiRedditListener.failed(0); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/DeleteMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/DeleteMultiReddit.java new file mode 100644 index 00000000..0d6567a1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/DeleteMultiReddit.java @@ -0,0 +1,41 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import androidx.annotation.NonNull; + +import ml.docilealligator.infinityforreddit.asynctasks.DeleteMultiredditInDatabaseAsyncTask; +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class DeleteMultiReddit { + public interface DeleteMultiRedditListener { + void success(); + void failed(); + } + + public static void deleteMultiReddit(Retrofit oauthRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, + String accessToken, String accountName, String multipath, + DeleteMultiRedditListener deleteMultiRedditListener) { + oauthRetrofit.create(RedditAPI.class).deleteMultiReddit(APIUtils.getOAuthHeader(accessToken), + multipath).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new DeleteMultiredditInDatabaseAsyncTask(redditDataRoomDatabase, accountName, multipath, + deleteMultiRedditListener::success).execute(); + } else { + deleteMultiRedditListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + deleteMultiRedditListener.failed(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/EditMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/EditMultiReddit.java new file mode 100644 index 00000000..36303b90 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/EditMultiReddit.java @@ -0,0 +1,43 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class EditMultiReddit { + public interface EditMultiRedditListener { + void success(); + void failed(); + } + + public static void editMultiReddit(Retrofit oauthRetrofit, String accessToken, String multipath, String model, + EditMultiRedditListener editMultiRedditListener) { + Map params = new HashMap<>(); + params.put(APIUtils.MULTIPATH_KEY, multipath); + params.put(APIUtils.MODEL_KEY, model); + oauthRetrofit.create(RedditAPI.class).updateMultiReddit(APIUtils.getOAuthHeader(accessToken), + params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + editMultiRedditListener.success(); + } else { + editMultiRedditListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + editMultiRedditListener.failed(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FavoriteMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FavoriteMultiReddit.java new file mode 100644 index 00000000..5d6c7573 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FavoriteMultiReddit.java @@ -0,0 +1,49 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.asynctasks.InsertMultiRedditAsyncTask; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FavoriteMultiReddit { + public interface FavoriteMultiRedditListener { + void success(); + void failed(); + } + + public static void favoriteMultiReddit(Retrofit oauthRetrofit, RedditDataRoomDatabase redditDataRoomDatabase, + String accessToken, boolean makeFavorite, + MultiReddit multiReddit, FavoriteMultiRedditListener favoriteMultiRedditListener) { + Map params = new HashMap<>(); + params.put(APIUtils.MULTIPATH_KEY, multiReddit.getPath()); + params.put(APIUtils.MAKE_FAVORITE_KEY, String.valueOf(makeFavorite)); + params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); + oauthRetrofit.create(RedditAPI.class).favoriteMultiReddit(APIUtils.getOAuthHeader(accessToken), + params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + multiReddit.setFavorite(makeFavorite); + new InsertMultiRedditAsyncTask(redditDataRoomDatabase, multiReddit, + favoriteMultiRedditListener::success).execute(); + } else { + favoriteMultiRedditListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + favoriteMultiRedditListener.failed(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMultiRedditInfo.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMultiRedditInfo.java new file mode 100644 index 00000000..97d2a2d1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMultiRedditInfo.java @@ -0,0 +1,101 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import android.os.AsyncTask; + +import androidx.annotation.NonNull; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchMultiRedditInfo { + + public interface FetchMultiRedditInfoListener { + void success(MultiReddit multiReddit); + void failed(); + } + + public static void fetchMultiRedditInfo(Retrofit retrofit, String accessToken, String multipath, + FetchMultiRedditInfoListener fetchMultiRedditInfoListener) { + retrofit.create(RedditAPI.class).getMultiRedditInfo(APIUtils.getOAuthHeader(accessToken), multipath).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseMultiRedditInfoAsyncTask(response.body(), fetchMultiRedditInfoListener).execute(); + } else { + fetchMultiRedditInfoListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchMultiRedditInfoListener.failed(); + } + }); + } + + private static class ParseMultiRedditInfoAsyncTask extends AsyncTask { + + private String response; + private FetchMultiRedditInfoListener fetchMultiRedditInfoListener; + private MultiReddit multiReddit; + private boolean parseFailed = false; + + public ParseMultiRedditInfoAsyncTask(String response, FetchMultiRedditInfoListener fetchMultiRedditInfoListener) { + this.response = response; + this.fetchMultiRedditInfoListener = fetchMultiRedditInfoListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject object = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY); + String path = object.getString(JSONUtils.PATH_KEY); + String displayName = object.getString(JSONUtils.DISPLAY_NAME_KEY); + String name = object.getString(JSONUtils.NAME_KEY); + String description = object.getString(JSONUtils.DESCRIPTION_MD_KEY); + String copiedFrom = object.getString(JSONUtils.COPIED_FROM_KEY); + String iconUrl = object.getString(JSONUtils.ICON_URL_KEY); + String visibility = object.getString(JSONUtils.VISIBILITY_KEY); + String owner = object.getString(JSONUtils.OWNER_KEY); + int nSubscribers = object.getInt(JSONUtils.NUM_SUBSCRIBERS_KEY); + long createdUTC = object.getLong(JSONUtils.CREATED_UTC_KEY); + boolean over18 = object.getBoolean(JSONUtils.OVER_18_KEY); + boolean isSubscriber = object.getBoolean(JSONUtils.IS_SUBSCRIBER_KEY); + boolean isFavorite = object.getBoolean(JSONUtils.IS_FAVORITED_KEY); + ArrayList subreddits = new ArrayList<>(); + JSONArray subredditsArray = object.getJSONArray(JSONUtils.SUBREDDITS_KEY); + for (int i = 0; i < subredditsArray.length(); i++) { + subreddits.add(subredditsArray.getJSONObject(i).getString(JSONUtils.NAME_KEY)); + } + + multiReddit = new MultiReddit(path, displayName, name, description, copiedFrom, iconUrl, + visibility, owner, nSubscribers, createdUTC, over18, isSubscriber, isFavorite, + subreddits); + } catch (JSONException e) { + parseFailed = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (parseFailed) { + fetchMultiRedditInfoListener.failed(); + } else { + fetchMultiRedditInfoListener.success(multiReddit); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMyMultiReddits.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMyMultiReddits.java new file mode 100644 index 00000000..7954d0e2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/FetchMyMultiReddits.java @@ -0,0 +1,48 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchMyMultiReddits { + public interface FetchMyMultiRedditsListener { + void success(ArrayList multiReddits); + void failed(); + } + + public static void fetchMyMultiReddits(Retrofit oauthRetrofit, String accessToken, FetchMyMultiRedditsListener fetchMyMultiRedditsListener) { + oauthRetrofit.create(RedditAPI.class) + .getMyMultiReddits(APIUtils.getOAuthHeader(accessToken)).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseMultiReddit.parseMultiRedditsList(response.body(), new ParseMultiReddit.ParseMultiRedditsListListener() { + @Override + public void success(ArrayList multiReddits) { + fetchMyMultiRedditsListener.success(multiReddits); + } + + @Override + public void failed() { + fetchMyMultiRedditsListener.failed(); + } + }); + } else { + fetchMyMultiRedditsListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchMyMultiRedditsListener.failed(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiReddit.java new file mode 100644 index 00000000..b010f9d2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiReddit.java @@ -0,0 +1,258 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.ForeignKey; +import androidx.room.Ignore; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.account.Account; + +@Entity(tableName = "multi_reddits", primaryKeys = {"path", "username"}, + foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", + childColumns = "username", onDelete = ForeignKey.CASCADE)) +public class MultiReddit implements Parcelable { + @NonNull + @ColumnInfo(name = "path") + private String path; + @NonNull + @ColumnInfo(name = "display_name") + private String displayName; + @NonNull + @ColumnInfo(name = "name") + private String name; + @ColumnInfo(name = "description") + private String description; + @ColumnInfo(name = "copied_from") + private String copiedFrom; + @ColumnInfo(name = "icon_url") + private String iconUrl; + @ColumnInfo(name = "visibility") + private String visibility; + @NonNull + @ColumnInfo(name = "username") + private String owner; + @ColumnInfo(name = "n_subscribers") + private int nSubscribers; + @ColumnInfo(name = "created_UTC") + private long createdUTC; + @ColumnInfo(name = "over_18") + private boolean over18; + @ColumnInfo(name = "is_subscriber") + private boolean isSubscriber; + @ColumnInfo(name = "is_favorite") + private boolean isFavorite; + @Ignore + private ArrayList subreddits; + + public MultiReddit(@NonNull String path, @NonNull String displayName, @NonNull String name, + String description, String copiedFrom, String iconUrl, String visibility, + @NonNull String owner, int nSubscribers, long createdUTC, boolean over18, + boolean isSubscriber, boolean isFavorite) { + this.displayName = displayName; + this.name = name; + this.description = description; + this.copiedFrom = copiedFrom; + this.iconUrl = iconUrl; + this.visibility = visibility; + this.path = path; + this.owner = owner; + this.nSubscribers = nSubscribers; + this.createdUTC = createdUTC; + this.over18 = over18; + this.isSubscriber = isSubscriber; + this.isFavorite = isFavorite; + } + + public MultiReddit(@NonNull String path, @NonNull String displayName, @NonNull String name, + String description, String copiedFrom, String iconUrl, String visibility, + @NonNull String owner, int nSubscribers, long createdUTC, boolean over18, + boolean isSubscriber, boolean isFavorite, ArrayList subreddits) { + this.displayName = displayName; + this.name = name; + this.description = description; + this.copiedFrom = copiedFrom; + this.iconUrl = iconUrl; + this.visibility = visibility; + this.path = path; + this.owner = owner; + this.nSubscribers = nSubscribers; + this.createdUTC = createdUTC; + this.over18 = over18; + this.isSubscriber = isSubscriber; + this.isFavorite = isFavorite; + this.subreddits = subreddits; + } + + protected MultiReddit(Parcel in) { + path = in.readString(); + displayName = in.readString(); + name = in.readString(); + description = in.readString(); + copiedFrom = in.readString(); + iconUrl = in.readString(); + visibility = in.readString(); + owner = in.readString(); + nSubscribers = in.readInt(); + createdUTC = in.readLong(); + over18 = in.readByte() != 0; + isSubscriber = in.readByte() != 0; + isFavorite = in.readByte() != 0; + subreddits = in.readArrayList(MultiReddit.class.getClassLoader()); + } + + public static final Creator CREATOR = new Creator() { + @Override + public MultiReddit createFromParcel(Parcel in) { + return new MultiReddit(in); + } + + @Override + public MultiReddit[] newArray(int size) { + return new MultiReddit[size]; + } + }; + + @NonNull + public String getPath() { + return path; + } + + public void setPath(@NonNull String path) { + this.path = path; + } + + @NonNull + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(@NonNull String displayName) { + this.displayName = displayName; + } + + @NonNull + public String getName() { + return name; + } + + public void setName(@NonNull String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getCopiedFrom() { + return copiedFrom; + } + + public void setCopiedFrom(String copiedFrom) { + this.copiedFrom = copiedFrom; + } + + public String getIconUrl() { + return iconUrl; + } + + public void setIconUrl(String iconUrl) { + this.iconUrl = iconUrl; + } + + public String getVisibility() { + return visibility; + } + + public void setVisibility(String visibility) { + this.visibility = visibility; + } + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public int getNSubscribers() { + return nSubscribers; + } + + public void setNSubscribers(int nSubscribers) { + this.nSubscribers = nSubscribers; + } + + public long getCreatedUTC() { + return createdUTC; + } + + public void setCreatedUTC(long createdUTC) { + this.createdUTC = createdUTC; + } + + public boolean isOver18() { + return over18; + } + + public void setOver18(boolean over18) { + this.over18 = over18; + } + + public boolean isSubscriber() { + return isSubscriber; + } + + public void setSubscriber(boolean subscriber) { + isSubscriber = subscriber; + } + + public boolean isFavorite() { + return isFavorite; + } + + public void setFavorite(boolean favorite) { + isFavorite = favorite; + } + + public ArrayList getSubreddits() { + return subreddits; + } + + public void setSubreddits(ArrayList subreddits) { + this.subreddits = subreddits; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(path); + parcel.writeString(displayName); + parcel.writeString(name); + parcel.writeString(description); + parcel.writeString(copiedFrom); + parcel.writeString(iconUrl); + parcel.writeString(visibility); + parcel.writeString(owner); + parcel.writeInt(nSubscribers); + parcel.writeLong(createdUTC); + parcel.writeByte((byte) (over18 ? 1 : 0)); + parcel.writeByte((byte) (isSubscriber ? 1 : 0)); + parcel.writeByte((byte) (isFavorite ? 1 : 0)); + parcel.writeStringList(subreddits); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditDao.java new file mode 100644 index 00000000..cb50cba6 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditDao.java @@ -0,0 +1,33 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface MultiRedditDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(MultiReddit MultiReddit); + + @Query("SELECT * FROM multi_reddits WHERE username = :username ORDER BY name COLLATE NOCASE ASC") + LiveData> getAllMultiReddits(String username); + + @Query("SELECT * FROM multi_reddits WHERE username = :username ORDER BY name COLLATE NOCASE ASC") + List getAllMultiRedditsList(String username); + + @Query("SELECT * FROM multi_reddits WHERE username = :username AND is_favorite ORDER BY name COLLATE NOCASE ASC") + LiveData> getAllFavoriteMultiReddits(String username); + + @Query("SELECT * FROM multi_reddits WHERE name = :name AND username = :username COLLATE NOCASE LIMIT 1") + MultiReddit getMultiReddit(String name, String username); + + @Query("DELETE FROM multi_reddits WHERE name = :name AND username = :username") + void deleteMultiReddit(String name, String username); + + @Query("DELETE FROM multi_reddits WHERE username = :username") + void deleteAllUserMultiReddits(String username); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditJSONModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditJSONModel.java new file mode 100644 index 00000000..60f405ef --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditJSONModel.java @@ -0,0 +1,38 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import com.google.gson.Gson; + +import java.util.ArrayList; + +public class MultiRedditJSONModel { + private String display_name; + private String description_md; + private String visibility; + private SubredditInMultiReddit[] subreddits; + + public MultiRedditJSONModel() {} + + public MultiRedditJSONModel(String display_name, String description_md, boolean isPrivate, + ArrayList subreddits) { + this.display_name = display_name; + this.description_md = description_md; + if (isPrivate) { + visibility = "private"; + } else { + visibility = "public"; + } + + if (subreddits != null) { + this.subreddits = new SubredditInMultiReddit[subreddits.size()]; + for (int i = 0; i < subreddits.size(); i++) { + SubredditInMultiReddit subredditInMultiReddit = new SubredditInMultiReddit(subreddits.get(i)); + this.subreddits[i] = subredditInMultiReddit; + } + } + } + + public String createJSONModel() { + Gson gson = new Gson(); + return gson.toJson(this); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditRepository.java new file mode 100644 index 00000000..8b8156ae --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditRepository.java @@ -0,0 +1,26 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import androidx.lifecycle.LiveData; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class MultiRedditRepository { + private LiveData> mAllMultiReddits; + private LiveData> mAllFavoriteMultiReddits; + + MultiRedditRepository(RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + MultiRedditDao multiRedditDao = redditDataRoomDatabase.multiRedditDao(); + mAllMultiReddits = multiRedditDao.getAllMultiReddits(accountName); + mAllFavoriteMultiReddits = multiRedditDao.getAllFavoriteMultiReddits(accountName); + } + + LiveData> getAllMultiReddits() { + return mAllMultiReddits; + } + + LiveData> getAllFavoriteMultiReddits() { + return mAllFavoriteMultiReddits; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditViewModel.java new file mode 100644 index 00000000..989b4853 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/MultiRedditViewModel.java @@ -0,0 +1,52 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class MultiRedditViewModel extends AndroidViewModel { + private MultiRedditRepository mMultiRedditRepository; + private LiveData> mAllMultiReddits; + private LiveData> mAllFavoriteMultiReddits; + + public MultiRedditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + super(application); + mMultiRedditRepository = new MultiRedditRepository(redditDataRoomDatabase, accountName); + mAllMultiReddits = mMultiRedditRepository.getAllMultiReddits(); + mAllFavoriteMultiReddits = mMultiRedditRepository.getAllFavoriteMultiReddits(); + } + + public LiveData> getAllMultiReddits() { + return mAllMultiReddits; + } + + public LiveData> getAllFavoriteMultiReddits() { + return mAllFavoriteMultiReddits; + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Application mApplication; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private String mAccountName; + + public Factory(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + mApplication = application; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mAccountName = accountName; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new MultiRedditViewModel(mApplication, mRedditDataRoomDatabase, mAccountName); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/ParseMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/ParseMultiReddit.java new file mode 100644 index 00000000..d3d23445 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/ParseMultiReddit.java @@ -0,0 +1,138 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +import android.os.AsyncTask; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; + +public class ParseMultiReddit { + interface ParseMultiRedditsListListener { + void success(ArrayList multiReddits); + void failed(); + } + + interface ParseMultiRedditListener { + void success(); + void failed(); + } + + public static void parseMultiRedditsList(String response, ParseMultiRedditsListListener parseMultiRedditsListListener) { + new ParseMultiRedditsListAsyncTask(response, parseMultiRedditsListListener).execute(); + } + + public static void parseAndSaveMultiReddit(String response, RedditDataRoomDatabase redditDataRoomDatabase, + ParseMultiRedditListener parseMultiRedditListener) { + new ParseAndSaveMultiRedditAsyncTask(response, redditDataRoomDatabase, parseMultiRedditListener).execute(); + } + + private static MultiReddit parseMultiReddit(JSONObject singleMultiRedditJSON) throws JSONException { + String displayName = singleMultiRedditJSON.getString(JSONUtils.DISPLAY_NAME_KEY); + String name = singleMultiRedditJSON.getString(JSONUtils.NAME_KEY); + String description = singleMultiRedditJSON.getString(JSONUtils.DESCRIPTION_MD_KEY); + int nSubscribers = singleMultiRedditJSON.getInt(JSONUtils.NUM_SUBSCRIBERS_KEY); + String copiedFrom = singleMultiRedditJSON.getString(JSONUtils.COPIED_FROM_KEY); + String iconUrl = singleMultiRedditJSON.getString(JSONUtils.ICON_URL_KEY); + long createdUTC = singleMultiRedditJSON.getLong(JSONUtils.CREATED_UTC_KEY); + String visibility = singleMultiRedditJSON.getString(JSONUtils.VISIBILITY_KEY); + boolean over18 = singleMultiRedditJSON.getBoolean(JSONUtils.OVER_18_KEY); + String path = singleMultiRedditJSON.getString(JSONUtils.PATH_KEY); + String owner = singleMultiRedditJSON.getString(JSONUtils.OWNER_KEY); + boolean isSubscriber = singleMultiRedditJSON.getBoolean(JSONUtils.IS_SUBSCRIBER_KEY); + boolean isFavorited = singleMultiRedditJSON.getBoolean(JSONUtils.IS_FAVORITED_KEY); + + JSONArray subredditsArray = singleMultiRedditJSON.getJSONArray(JSONUtils.SUBREDDITS_KEY); + ArrayList subreddits = new ArrayList<>(); + for (int j = 0; j < subredditsArray.length(); j++) { + subreddits.add(subredditsArray.getJSONObject(j).getString(JSONUtils.NAME_KEY)); + } + + return new MultiReddit(path, displayName, name, description, copiedFrom, + iconUrl, visibility, owner, nSubscribers, createdUTC, over18, isSubscriber, + isFavorited, subreddits); + } + + private static class ParseMultiRedditsListAsyncTask extends AsyncTask { + private JSONArray arrayResponse; + private boolean parseFailed; + private ArrayList multiReddits; + private ParseMultiRedditsListListener parseMultiRedditsListListener; + + ParseMultiRedditsListAsyncTask(String response, + ParseMultiRedditsListListener parseMultiRedditsListListener) { + this.parseMultiRedditsListListener = parseMultiRedditsListListener; + try { + arrayResponse = new JSONArray(response); + multiReddits = new ArrayList<>(); + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + @Override + protected Void doInBackground(Void... voids) { + if (!parseFailed) { + for (int i = 0; i < arrayResponse.length(); i++) { + try { + multiReddits.add(parseMultiReddit(arrayResponse.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY))); + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (!parseFailed) { + parseMultiRedditsListListener.success(multiReddits); + } else { + parseMultiRedditsListListener.failed(); + } + } + } + + private static class ParseAndSaveMultiRedditAsyncTask extends AsyncTask { + private String response; + private RedditDataRoomDatabase redditDataRoomDatabase; + private MultiReddit multiReddit; + private ParseMultiRedditListener parseMultiRedditListener; + + ParseAndSaveMultiRedditAsyncTask(String response, RedditDataRoomDatabase redditDataRoomDatabase, + ParseMultiRedditListener parseMultiRedditListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.parseMultiRedditListener = parseMultiRedditListener; + this.response = response; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + multiReddit = parseMultiReddit(new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY)); + redditDataRoomDatabase.multiRedditDao().insert(multiReddit); + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (multiReddit != null) { + parseMultiRedditListener.success(); + } else { + parseMultiRedditListener.failed(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/SubredditInMultiReddit.java b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/SubredditInMultiReddit.java new file mode 100644 index 00000000..21f734bb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/multireddit/SubredditInMultiReddit.java @@ -0,0 +1,11 @@ +package ml.docilealligator.infinityforreddit.multireddit; + +public class SubredditInMultiReddit { + String name; + + SubredditInMultiReddit() {} + + SubredditInMultiReddit(String subredditName) { + name = subredditName; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java new file mode 100644 index 00000000..bdb3b17e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchPost.java @@ -0,0 +1,95 @@ +package ml.docilealligator.infinityforreddit.post; + +import androidx.annotation.NonNull; + +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchPost { + public static void fetchPost(Retrofit retrofit, String id, String accessToken, Locale locale, FetchPostListener fetchPostListener) { + Call postCall; + if (accessToken == null) { + postCall = retrofit.create(RedditAPI.class).getPost(id); + } else { + postCall = retrofit.create(RedditAPI.class).getPostOauth(id, APIUtils.getOAuthHeader(accessToken)); + } + postCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(Post post) { + fetchPostListener.fetchPostSuccess(post); + } + + @Override + public void onParsePostFail() { + fetchPostListener.fetchPostFailed(); + } + }); + } else { + fetchPostListener.fetchPostFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchPostListener.fetchPostFailed(); + } + }); + } + + public static void fetchRandomPost(Retrofit retrofit, boolean isNSFW, FetchRandomPostListener fetchRandomPostListener) { + Call call; + if (isNSFW) { + call = retrofit.create(RedditAPI.class).getRandomNSFWPost(); + } else { + call = retrofit.create(RedditAPI.class).getRandomPost(); + } + + call.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParsePost.ParseRandomPostAsyncTask(response.body(), isNSFW, new ParsePost.ParseRandomPostListener() { + + @Override + public void onParseRandomPostSuccess(String postId, String subredditName) { + fetchRandomPostListener.fetchRandomPostSuccess(postId, subredditName); + } + + @Override + public void onParseRandomPostFailed() { + fetchRandomPostListener.fetchRandomPostFailed(); + } + }).execute(); + } else { + fetchRandomPostListener.fetchRandomPostFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchRandomPostListener.fetchRandomPostFailed(); + } + }); + } + + public interface FetchPostListener { + void fetchPostSuccess(Post post); + + void fetchPostFailed(); + } + + public interface FetchRandomPostListener { + void fetchRandomPostSuccess(String postId, String subredditName); + void fetchRandomPostFailed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchRemovedPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchRemovedPost.java new file mode 100644 index 00000000..8ae15029 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/FetchRemovedPost.java @@ -0,0 +1,159 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.net.Uri; +import android.os.AsyncTask; +import android.text.Html; + +import androidx.annotation.NonNull; + +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.apis.PushshiftAPI; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchRemovedPost { + + public static void fetchRemovedPost(Retrofit retrofit, Post post, FetchRemovedPostListener listener) { + retrofit.create(PushshiftAPI.class).getRemovedPost(post.getId()) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParsePostAsyncTask(response.body(), post, listener).execute(); + } else { + listener.fetchFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + t.printStackTrace(); + listener.fetchFailed(); + } + }); + } + + private static Post parseRemovedPost(JSONObject result, Post post) throws JSONException { + String id = result.getString(JSONUtils.ID_KEY); + String author = result.getString(JSONUtils.AUTHOR_KEY); + String title = result.getString(JSONUtils.TITLE_KEY); + String body = Utils.modifyMarkdown(result.getString(JSONUtils.SELFTEXT_KEY).trim()); + + if ( id.equals(post.getId()) && + (!author.equals(post.getAuthor()) || + foundSelfText(post.getSelfText(), body)) + ) { + post.setAuthor(author); + post.setTitle(title); + post.setSelfText(body); + post.setSelfTextPlain(""); + post.setSelfTextPlainTrimmed(""); + + String url = result.optString(JSONUtils.URL_KEY); + + if (url.endsWith("gif") || url.endsWith("mp4")) { + post.setVideoUrl(url); + post.setVideoDownloadUrl(url); + } else if (post.getPostType() == Post.VIDEO_TYPE || post.getPostType() == Post.GIF_TYPE) { + JSONObject redditVideoObject = result.getJSONObject("secure_media").getJSONObject(JSONUtils.REDDIT_VIDEO_KEY); + String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString(); + String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY); + + post.setVideoUrl(videoUrl); + post.setVideoDownloadUrl(videoDownloadUrl); + } else if (post.getPostType() == Post.LINK_TYPE) { + post.setUrl(url); + } + + if (post.getPostType() == Post.VIDEO_TYPE) { + try { + Uri uri = Uri.parse(url); + String authority = uri.getAuthority(); + if (authority != null && (authority.contains("gfycat.com") || authority.contains("redgifs.com"))) { + post.setPostType(Post.LINK_TYPE); + post.setUrl(url); + } + } catch (IllegalArgumentException ignore) { + } + } + + if (!result.isNull("thumbnail")) { + ArrayList previews = post.getPreviews(); + if (previews != null && !previews.isEmpty()) { + if (previews.size() >= 2) { + Post.Preview preview = previews.get(1); + preview.setPreviewUrl(result.getString("thumbnail")); + previews.set(1, preview); + } else { + Post.Preview preview = previews.get(0); + preview.setPreviewUrl(result.getString("thumbnail")); + previews.set(0, preview); + } + } else { + Post.Preview preview = new Post.Preview(result.getString("thumbnail"), 1, 1); + preview.setPreviewUrl(result.getString("thumbnail")); + ArrayList newPreviews = new ArrayList<>(); + newPreviews.add(preview); + post.setPreviews(newPreviews); + } + } + + return post; + } else { + return null; + } + } + + private static boolean foundSelfText(String oldText, String newText) { + return !(newText.equals("[deleted]") || newText.equals("[removed]")) && + !newText.equals(oldText); + } + + public interface FetchRemovedPostListener { + void fetchSuccess(Post post); + + void fetchFailed(); + } + + private static class ParsePostAsyncTask extends AsyncTask { + + private String responseBody; + private FetchRemovedPostListener listener; + Post post; + + public ParsePostAsyncTask(String responseBody, Post post, FetchRemovedPostListener listener) { + this.responseBody = responseBody; + this.post = post; + this.listener = listener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject postJson = new JSONObject(responseBody).getJSONArray(JSONUtils.DATA_KEY).getJSONObject(0); + post = parseRemovedPost(postJson, post); + } catch (JSONException e) { + e.printStackTrace(); + post = null; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (post != null) + listener.fetchSuccess(post); + else + listener.fetchFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/HidePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HidePost.java new file mode 100644 index 00000000..fb490c0c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HidePost.java @@ -0,0 +1,63 @@ +package ml.docilealligator.infinityforreddit.post; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class HidePost { + public static void hidePost(Retrofit oauthRetrofit, String accessToken, String fullname, + HidePostListener hidePostListener) { + Map params = new HashMap<>(); + params.put(APIUtils.ID_KEY, fullname); + oauthRetrofit.create(RedditAPI.class).hide(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + hidePostListener.success(); + } else { + hidePostListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + hidePostListener.failed(); + } + }); + } + + public static void unhidePost(Retrofit oauthRetrofit, String accessToken, String fullname, + HidePostListener hidePostListener) { + Map params = new HashMap<>(); + params.put(APIUtils.ID_KEY, fullname); + oauthRetrofit.create(RedditAPI.class).unhide(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + hidePostListener.success(); + } else { + hidePostListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + hidePostListener.failed(); + } + }); + } + + public interface HidePostListener { + void success(); + + void failed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java new file mode 100644 index 00000000..708f4e75 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java @@ -0,0 +1,666 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.net.Uri; +import android.os.AsyncTask; +import android.text.Html; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; + +import ml.docilealligator.infinityforreddit.fragments.PostFragment; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; + +/** + * Created by alex on 3/21/18. + */ + +public class ParsePost { + public static void parsePosts(String response, int nPosts, int filter, boolean nsfw, + ParsePostsListingListener parsePostsListingListener) { + new ParsePostDataAsyncTask(response, nPosts, filter, nsfw, parsePostsListingListener).execute(); + } + + public static void parsePosts(String response, int nPosts, int filter, boolean nsfw, + List subredditFilterList, ParsePostsListingListener parsePostsListingListener) { + new ParsePostDataAsyncTask(response, nPosts, filter, nsfw, subredditFilterList, parsePostsListingListener).execute(); + } + + public static void parsePost(String response, ParsePostListener parsePostListener) { + new ParsePostDataAsyncTask(response, true, parsePostListener).execute(); + } + + private static Post parseBasicData(JSONObject data) throws JSONException { + String id = data.getString(JSONUtils.ID_KEY); + String fullName = data.getString(JSONUtils.NAME_KEY); + String subredditName = data.getString(JSONUtils.SUBREDDIT_KEY); + String subredditNamePrefixed = data.getString(JSONUtils.SUBREDDIT_NAME_PREFIX_KEY); + String author = data.getString(JSONUtils.AUTHOR_KEY); + StringBuilder authorFlairHTMLBuilder = new StringBuilder(); + if (data.has(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY)) { + JSONArray flairArray = data.getJSONArray(JSONUtils.AUTHOR_FLAIR_RICHTEXT_KEY); + for (int i = 0; i < flairArray.length(); i++) { + JSONObject flairObject = flairArray.getJSONObject(i); + String e = flairObject.getString(JSONUtils.E_KEY); + if (e.equals("text")) { + authorFlairHTMLBuilder.append(flairObject.getString(JSONUtils.T_KEY)); + } else if (e.equals("emoji")) { + authorFlairHTMLBuilder.append(""); + } + } + } + String authorFlair = data.isNull(JSONUtils.AUTHOR_FLAIR_TEXT_KEY) ? "" : data.getString(JSONUtils.AUTHOR_FLAIR_TEXT_KEY); + long postTime = data.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; + String title = data.getString(JSONUtils.TITLE_KEY); + int score = data.getInt(JSONUtils.SCORE_KEY); + int voteType; + int nComments = data.getInt(JSONUtils.NUM_COMMENTS_KEY); + boolean hidden = data.getBoolean(JSONUtils.HIDDEN_KEY); + boolean spoiler = data.getBoolean(JSONUtils.SPOILER_KEY); + boolean nsfw = data.getBoolean(JSONUtils.NSFW_KEY); + boolean stickied = data.getBoolean(JSONUtils.STICKIED_KEY); + boolean archived = data.getBoolean(JSONUtils.ARCHIVED_KEY); + boolean locked = data.getBoolean(JSONUtils.LOCKEC_KEY); + boolean saved = data.getBoolean(JSONUtils.SAVED_KEY); + StringBuilder postFlairHTMLBuilder = new StringBuilder(); + String flair = ""; + if (data.has(JSONUtils.LINK_FLAIR_RICHTEXT_KEY)) { + JSONArray flairArray = data.getJSONArray(JSONUtils.LINK_FLAIR_RICHTEXT_KEY); + for (int i = 0; i < flairArray.length(); i++) { + JSONObject flairObject = flairArray.getJSONObject(i); + String e = flairObject.getString(JSONUtils.E_KEY); + if (e.equals("text")) { + postFlairHTMLBuilder.append(Html.escapeHtml(flairObject.getString(JSONUtils.T_KEY))); + } else if (e.equals("emoji")) { + postFlairHTMLBuilder.append(""); + } + } + flair = postFlairHTMLBuilder.toString(); + } + + if (flair.equals("") && data.has(JSONUtils.LINK_FLAIR_TEXT_KEY) && !data.isNull(JSONUtils.LINK_FLAIR_TEXT_KEY)) { + flair = data.getString(JSONUtils.LINK_FLAIR_TEXT_KEY); + } + + StringBuilder awardingsBuilder = new StringBuilder(); + JSONArray awardingsArray = data.getJSONArray(JSONUtils.ALL_AWARDINGS_KEY); + int nAwards = 0; + for (int i = 0; i < awardingsArray.length(); i++) { + JSONObject award = awardingsArray.getJSONObject(i); + int count = award.getInt(JSONUtils.COUNT_KEY); + nAwards += count; + JSONArray icons = award.getJSONArray(JSONUtils.RESIZED_ICONS_KEY); + if (icons.length() > 4) { + String iconUrl = icons.getJSONObject(3).getString(JSONUtils.URL_KEY); + awardingsBuilder.append(" ").append("x").append(count).append(" "); + } else if (icons.length() > 0) { + String iconUrl = icons.getJSONObject(icons.length() - 1).getString(JSONUtils.URL_KEY); + awardingsBuilder.append(" ").append("x").append(count).append(" "); + } + } + + if (data.isNull(JSONUtils.LIKES_KEY)) { + voteType = 0; + } else { + voteType = data.getBoolean(JSONUtils.LIKES_KEY) ? 1 : -1; + score -= voteType; + } + + String permalink = Html.fromHtml(data.getString(JSONUtils.PERMALINK_KEY)).toString(); + + ArrayList previews = new ArrayList<>(); + if (data.has(JSONUtils.PREVIEW_KEY)) { + JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); + String previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); + int previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); + int previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); + previews.add(new Post.Preview(previewUrl, previewWidth, previewHeight)); + + JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY); + for (int i = 0; i < thumbnailPreviews.length(); i++) { + JSONObject thumbnailPreview = thumbnailPreviews.getJSONObject(i); + String thumbnailPreviewUrl = thumbnailPreview.getString(JSONUtils.URL_KEY); + int thumbnailPreviewWidth = thumbnailPreview.getInt(JSONUtils.WIDTH_KEY); + int thumbnailPreviewHeight = thumbnailPreview.getInt(JSONUtils.HEIGHT_KEY); + + previews.add(new Post.Preview(thumbnailPreviewUrl, thumbnailPreviewWidth, thumbnailPreviewHeight)); + } + } + if (data.has(JSONUtils.CROSSPOST_PARENT_LIST)) { + //Cross post + data = data.getJSONArray(JSONUtils.CROSSPOST_PARENT_LIST).getJSONObject(0); + Post crosspostParent = parseBasicData(data); + Post post = parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, + author, authorFlair, authorFlairHTMLBuilder.toString(), + postTime, title, previews, + score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, + spoiler, nsfw, stickied, archived, locked, saved, true); + post.setCrosspostParentId(crosspostParent.getId()); + return post; + } else { + return parseData(data, permalink, id, fullName, subredditName, subredditNamePrefixed, + author, authorFlair, authorFlairHTMLBuilder.toString(), + postTime, title, previews, + score, voteType, nComments, flair, awardingsBuilder.toString(), nAwards, hidden, + spoiler, nsfw, stickied, archived, locked, saved, false); + } + } + + private static Post parseData(JSONObject data, String permalink, String id, String fullName, + String subredditName, String subredditNamePrefixed, String author, + String authorFlair, String authorFlairHTML, + long postTimeMillis, String title, ArrayList previews, + int score, int voteType, int nComments, String flair, + String awards, int nAwards, boolean hidden, boolean spoiler, + boolean nsfw, boolean stickied, boolean archived, boolean locked, + boolean saved, boolean isCrosspost) throws JSONException { + Post post; + + boolean isVideo = data.getBoolean(JSONUtils.IS_VIDEO_KEY); + String url = Html.fromHtml(data.getString(JSONUtils.URL_KEY)).toString(); + + if (!data.has(JSONUtils.PREVIEW_KEY) && previews.isEmpty()) { + if (url.contains(permalink)) { + //Text post + int postType = Post.TEXT_TYPE; + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, + title, permalink, score, postType, voteType, nComments, flair, awards, nAwards, + hidden, spoiler, nsfw, stickied, archived, locked, saved, isCrosspost); + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + if (data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { + post.setSelfTextPlainTrimmed(""); + } else { + String selfTextPlain = Utils.trimTrailingWhitespace( + Html.fromHtml(data.getString(JSONUtils.SELFTEXT_HTML_KEY))).toString(); + post.setSelfTextPlain(selfTextPlain); + if (selfTextPlain.length() > 250) { + selfTextPlain = selfTextPlain.substring(0, 250); + } + post.setSelfTextPlainTrimmed(selfTextPlain); + } + } + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //Image post + int postType = Post.IMAGE_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, + locked, saved, isCrosspost); + + if (previews.isEmpty()) { + previews.add(new Post.Preview(url, 0, 0)); + } + post.setPreviews(previews); + } else { + //No preview link post + int postType = Post.NO_PREVIEW_LINK_TYPE; + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, + title, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, + archived, locked, saved, isCrosspost); + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + } + } + } + } else { + if (previews.isEmpty()) { + if (data.has(JSONUtils.PREVIEW_KEY)) { + JSONObject images = data.getJSONObject(JSONUtils.PREVIEW_KEY).getJSONArray(JSONUtils.IMAGES_KEY).getJSONObject(0); + String previewUrl = images.getJSONObject(JSONUtils.SOURCE_KEY).getString(JSONUtils.URL_KEY); + int previewWidth = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.WIDTH_KEY); + int previewHeight = images.getJSONObject(JSONUtils.SOURCE_KEY).getInt(JSONUtils.HEIGHT_KEY); + previews.add(new Post.Preview(previewUrl, previewWidth, previewHeight)); + + JSONArray thumbnailPreviews = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY); + for (int i = 0; i < thumbnailPreviews.length(); i++) { + JSONObject thumbnailPreview = images.getJSONArray(JSONUtils.RESOLUTIONS_KEY).getJSONObject(2); + String thumbnailPreviewUrl = thumbnailPreview.getString(JSONUtils.URL_KEY); + int thumbnailPreviewWidth = thumbnailPreview.getInt(JSONUtils.WIDTH_KEY); + int thumbnailPreviewHeight = thumbnailPreview.getInt(JSONUtils.HEIGHT_KEY); + + previews.add(new Post.Preview(thumbnailPreviewUrl, thumbnailPreviewWidth, thumbnailPreviewHeight)); + } + } + } + + if (isVideo) { + //Video post + JSONObject redditVideoObject = data.getJSONObject(JSONUtils.MEDIA_KEY).getJSONObject(JSONUtils.REDDIT_VIDEO_KEY); + int postType = Post.VIDEO_TYPE; + String videoUrl = Html.fromHtml(redditVideoObject.getString(JSONUtils.HLS_URL_KEY)).toString(); + String videoDownloadUrl = redditVideoObject.getString(JSONUtils.FALLBACK_URL_KEY); + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, + saved, isCrosspost); + + post.setPreviews(previews); + post.setVideoUrl(videoUrl); + post.setVideoDownloadUrl(videoDownloadUrl); + } else if (data.has(JSONUtils.PREVIEW_KEY)) { + if (data.getJSONObject(JSONUtils.PREVIEW_KEY).has(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY)) { + //Gif video post (HLS) + int postType = Post.VIDEO_TYPE; + String videoUrl = Html.fromHtml(data.getJSONObject(JSONUtils.PREVIEW_KEY) + .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.HLS_URL_KEY)).toString(); + String videoDownloadUrl = data.getJSONObject(JSONUtils.PREVIEW_KEY) + .getJSONObject(JSONUtils.REDDIT_VIDEO_PREVIEW_KEY).getString(JSONUtils.FALLBACK_URL_KEY); + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, + locked, saved, isCrosspost); + post.setPreviews(previews); + post.setVideoUrl(videoUrl); + post.setVideoDownloadUrl(videoDownloadUrl); + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //Image post + int postType = Post.IMAGE_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, + title, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, + stickied, archived, locked, saved, isCrosspost); + + if (previews.isEmpty()) { + previews.add(new Post.Preview(url, 0, 0)); + } + post.setPreviews(previews); + } else if (url.endsWith("gif")){ + //Gif post + int postType = Post.GIF_TYPE; + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, + title, url, permalink, score, + postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, + nsfw, stickied, archived, locked, saved, isCrosspost); + + post.setPreviews(previews); + post.setVideoUrl(url); + } else if (url.endsWith("mp4")) { + //Video post + int postType = Post.VIDEO_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, + archived, locked, saved, isCrosspost); + post.setPreviews(previews); + post.setVideoUrl(url); + post.setVideoDownloadUrl(url); + } else { + if (url.contains(permalink)) { + //Text post but with a preview + int postType = Post.TEXT_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, + title, permalink, score, postType, voteType, nComments, flair, + awards, nAwards, hidden, spoiler, nsfw, stickied, archived, locked, + saved, isCrosspost); + + //Need attention + post.setPreviews(previews); + + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + if (data.isNull(JSONUtils.SELFTEXT_HTML_KEY)) { + post.setSelfTextPlainTrimmed(""); + } else { + String selfTextPlain = Utils.trimTrailingWhitespace( + Html.fromHtml(data.getString(JSONUtils.SELFTEXT_HTML_KEY))).toString(); + post.setSelfTextPlain(selfTextPlain); + if (selfTextPlain.length() > 250) { + selfTextPlain = selfTextPlain.substring(0, 250); + } + post.setSelfTextPlainTrimmed(selfTextPlain); + } + } + } else { + //Link post + int postType = Post.LINK_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, + title, url, permalink, score, + postType, voteType, nComments, flair, awards, nAwards, hidden, spoiler, + nsfw, stickied, archived, locked, saved, isCrosspost); + if (data.isNull(JSONUtils.SELFTEXT_KEY)) { + post.setSelfText(""); + } else { + post.setSelfText(Utils.modifyMarkdown(data.getString(JSONUtils.SELFTEXT_KEY).trim())); + } + + post.setPreviews(previews); + } + } + } + } else { + if (url.endsWith("jpg") || url.endsWith("png")) { + //Image post + int postType = Post.IMAGE_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, + archived, locked, saved, isCrosspost); + + if (previews.isEmpty()) { + previews.add(new Post.Preview(url, 0, 0)); + } + post.setPreviews(previews); + } else if (url.endsWith("mp4")) { + //Video post + int postType = Post.VIDEO_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, + voteType, nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, + archived, locked, saved, isCrosspost); + post.setPreviews(previews); + post.setVideoUrl(url); + post.setVideoDownloadUrl(url); + } else { + //CP No Preview Link post + int postType = Post.NO_PREVIEW_LINK_TYPE; + + post = new Post(id, fullName, subredditName, subredditNamePrefixed, author, + authorFlair, authorFlairHTML, postTimeMillis, title, url, permalink, score, postType, voteType, + nComments, flair, awards, nAwards, hidden, spoiler, nsfw, stickied, archived, + locked, saved, isCrosspost); + //Need attention + } + } + } + + if (post.getPostType() == Post.VIDEO_TYPE) { + try { + Uri uri = Uri.parse(url); + String authority = uri.getAuthority(); + if (authority != null && (authority.contains("gfycat.com"))) { + post.setIsGfycat(true); + post.setVideoUrl(url); + String gfycatId = url.substring(url.lastIndexOf("/") + 1); + if (gfycatId.contains("-")) { + gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); + } + post.setGfycatId(gfycatId); + } else if (authority != null && authority.contains("redgifs.com")) { + String gfycatId = url.substring(url.lastIndexOf("/") + 1); + if (gfycatId.contains("-")) { + gfycatId = gfycatId.substring(0, gfycatId.indexOf('-')); + } + post.setIsRedgifs(true); + post.setVideoUrl(url); + post.setGfycatId(gfycatId); + } + } catch (IllegalArgumentException ignore) { } + } else if (post.getPostType() == Post.LINK_TYPE || post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + if (data.has(JSONUtils.GALLERY_DATA_KEY)) { + JSONArray galleryIdsArray = data.getJSONObject(JSONUtils.GALLERY_DATA_KEY).getJSONArray(JSONUtils.ITEMS_KEY); + JSONObject galleryObject = data.getJSONObject(JSONUtils.MEDIA_METADATA_KEY); + ArrayList gallery = new ArrayList<>(); + for (int i = 0; i < galleryIdsArray.length(); i++) { + String galleryId = galleryIdsArray.getJSONObject(i).getString(JSONUtils.MEDIA_ID_KEY); + JSONObject singleGalleryObject = galleryObject.getJSONObject(galleryId); + String mimeType = singleGalleryObject.getString(JSONUtils.M_KEY); + String galleryItemUrl; + if (mimeType.contains("jpg") || mimeType.contains("png")) { + galleryItemUrl = singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getString(JSONUtils.U_KEY); + } else { + JSONObject sourceObject = singleGalleryObject.getJSONObject(JSONUtils.S_KEY); + if (mimeType.contains("gif")) { + galleryItemUrl = sourceObject.getString(JSONUtils.GIF_KEY); + } else { + galleryItemUrl = sourceObject.getString(JSONUtils.MP4_KEY); + } + } + if ((previews.isEmpty()) && mimeType.contains("jpg") || mimeType.contains("png")) { + previews.add(new Post.Preview(galleryItemUrl, singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getInt(JSONUtils.X_KEY), + singleGalleryObject.getJSONObject(JSONUtils.S_KEY).getInt(JSONUtils.Y_KEY))); + } + gallery.add(new Post.Gallery(mimeType, galleryItemUrl, subredditName + "-" + galleryId + "." + mimeType.substring(mimeType.lastIndexOf("/") + 1))); + } + + if (!gallery.isEmpty()) { + post.setPostType(Post.GALLERY_TYPE); + post.setGallery(gallery); + post.setPreviews(previews); + } + } else if (post.getPostType() == Post.LINK_TYPE) { + Uri uri = Uri.parse(url); + String authority = uri.getAuthority(); + if (authority != null && (authority.contains("gfycat.com"))) { + post.setPostType(Post.VIDEO_TYPE); + post.setIsGfycat(true); + post.setVideoUrl(url); + post.setGfycatId(url.substring(url.lastIndexOf("/") + 1)); + } else if (authority != null && authority.contains("redgifs.com")) { + post.setPostType(Post.VIDEO_TYPE); + post.setIsRedgifs(true); + post.setVideoUrl(url); + post.setGfycatId(url.substring(url.lastIndexOf("/") + 1)); + } + } + } + + return post; + } + + public interface ParsePostsListingListener { + void onParsePostsListingSuccess(LinkedHashSet newPostData, String lastItem); + + void onParsePostsListingFail(); + } + + public interface ParsePostListener { + void onParsePostSuccess(Post post); + + void onParsePostFail(); + } + + public interface ParseRandomPostListener { + void onParseRandomPostSuccess(String postId, String subredditName); + void onParseRandomPostFailed(); + } + + private static class ParsePostDataAsyncTask extends AsyncTask { + private JSONArray allData; + private int nPosts; + private int filter; + private boolean nsfw; + private List subredditFilterList; + private ParsePostsListingListener parsePostsListingListener; + private ParsePostListener parsePostListener; + private LinkedHashSet newPosts; + private Post post; + private String lastItem; + private boolean parseFailed; + + ParsePostDataAsyncTask(String response, int nPosts, int filter, boolean nsfw, + ParsePostsListingListener parsePostsListingListener) { + this.parsePostsListingListener = parsePostsListingListener; + try { + JSONObject jsonResponse = new JSONObject(response); + allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + lastItem = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + this.nPosts = nPosts; + this.filter = filter; + this.nsfw = nsfw; + newPosts = new LinkedHashSet<>(); + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + ParsePostDataAsyncTask(String response, int nPosts, int filter, boolean nsfw, + List subredditFilterList, ParsePostsListingListener parsePostsListingListener) { + this(response, nPosts, filter, nsfw, parsePostsListingListener); + this.subredditFilterList = subredditFilterList; + } + + ParsePostDataAsyncTask(String response, boolean nsfw, + ParsePostListener parsePostListener) { + this.parsePostListener = parsePostListener; + try { + allData = new JSONArray(response).getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + this.nsfw = nsfw; + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + @Override + protected Void doInBackground(Void... voids) { + if (parseFailed) { + return null; + } + + if (newPosts == null) { + //Only one post + if (allData.length() == 0) { + parseFailed = true; + return null; + } + + try { + JSONObject data = allData.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); + post = parseBasicData(data); + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } else { + //Posts listing + int size; + if (nPosts < 0 || nPosts > allData.length()) { + size = allData.length(); + } else { + size = nPosts; + } + + for (int i = 0; i < size; i++) { + try { + if (allData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { + JSONObject data = allData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + Post post = parseBasicData(data); + boolean availablePost = true; + if (subredditFilterList != null) { + for (SubredditFilter subredditFilter : subredditFilterList) { + if (subredditFilter.getSubredditName().equals(post.getSubredditName())) { + availablePost = false; + break; + } + } + } + if (availablePost && !(!nsfw && post.isNSFW())) { + if (filter == PostFragment.EXTRA_NO_FILTER) { + newPosts.add(post); + } else if (filter == post.getPostType()) { + newPosts.add(post); + } else if (filter == Post.LINK_TYPE && post.getPostType() == Post.NO_PREVIEW_LINK_TYPE) { + newPosts.add(post); + } else if (filter == Post.NSFW_TYPE && post.isNSFW()) { + newPosts.add(post); + } + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!parseFailed) { + if (newPosts != null) { + parsePostsListingListener.onParsePostsListingSuccess(newPosts, lastItem); + } else { + parsePostListener.onParsePostSuccess(post); + } + } else { + if (parsePostsListingListener != null) { + parsePostsListingListener.onParsePostsListingFail(); + } else { + parsePostListener.onParsePostFail(); + } + } + } + } + + public static class ParseRandomPostAsyncTask extends AsyncTask { + + private String response; + private boolean isNSFW; + private ParseRandomPostListener parseRandomPostListener; + private String subredditName; + private String postId; + private boolean parseFailed = false; + + ParseRandomPostAsyncTask(String response, boolean isNSFW, ParseRandomPostListener parseRandomPostListener) { + this.response = response; + this.isNSFW = isNSFW; + this.parseRandomPostListener = parseRandomPostListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONArray postsArray = new JSONObject(response).getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + if (postsArray.length() == 0) { + parseFailed = true; + } else { + JSONObject post = postsArray.getJSONObject(0).getJSONObject(JSONUtils.DATA_KEY); + subredditName = post.getString(JSONUtils.SUBREDDIT_KEY); + if (isNSFW) { + postId = post.getString(JSONUtils.ID_KEY); + } else { + postId = post.getString(JSONUtils.LINK_ID_KEY).substring("t3_".length()); + } + } + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (parseFailed) { + parseRandomPostListener.onParseRandomPostFailed(); + } else { + parseRandomPostListener.onParseRandomPostSuccess(postId, subredditName); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java new file mode 100644 index 00000000..1e220487 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/Post.java @@ -0,0 +1,652 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.Nullable; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.utils.APIUtils; + +/** + * Created by alex on 3/1/18. + */ + +public class Post implements Parcelable { + public static final int NSFW_TYPE = -1; + public static final int TEXT_TYPE = 0; + public static final int IMAGE_TYPE = 1; + public static final int LINK_TYPE = 2; + public static final int VIDEO_TYPE = 3; + public static final int GIF_TYPE = 4; + public static final int NO_PREVIEW_LINK_TYPE = 5; + public static final int GALLERY_TYPE = 6; + public static final Creator CREATOR = new Creator() { + @Override + public Post createFromParcel(Parcel in) { + return new Post(in); + } + + @Override + public Post[] newArray(int size) { + return new Post[size]; + } + }; + private String id; + private String fullName; + private String subredditName; + private String subredditNamePrefixed; + private String subredditIconUrl; + private String author; + private String authorNamePrefixed; + private String authorIconUrl; + private String authorFlair; + private String authorFlairHTML; + private String title; + private String selfText; + private String selfTextPlain; + private String selfTextPlainTrimmed; + private String url; + private String videoUrl; + private String videoDownloadUrl; + private String gfycatId; + private boolean isGfycat; + private boolean isRedgifs; + private boolean loadGfyOrRedgifsVideoSuccess; + private String permalink; + private String flair; + private String awards; + private int nAwards; + private long postTimeMillis; + private int score; + private int postType; + private int voteType; + private int nComments; + private boolean hidden; + private boolean spoiler; + private boolean nsfw; + private boolean stickied; + private boolean archived; + private boolean locked; + private boolean saved; + private boolean isCrosspost; + private String crosspostParentId; + private ArrayList previews = new ArrayList<>(); + private ArrayList gallery = new ArrayList<>(); + + public Post(String id, String fullName, String subredditName, String subredditNamePrefixed, + String author, String authorFlair, String authorFlairHTML, + long postTimeMillis, String title, + String permalink, int score, int postType, int voteType, int nComments, String flair, + String awards, int nAwards, boolean hidden, boolean spoiler, boolean nsfw, boolean stickied, + boolean archived, boolean locked, boolean saved, boolean isCrosspost) { + this.id = id; + this.fullName = fullName; + this.subredditName = subredditName; + this.subredditNamePrefixed = subredditNamePrefixed; + this.author = author; + this.authorNamePrefixed = "u/" + author; + this.authorFlair = authorFlair; + this.authorFlairHTML = authorFlairHTML; + this.postTimeMillis = postTimeMillis; + this.title = title; + this.permalink = APIUtils.API_BASE_URI + permalink; + this.score = score; + this.postType = postType; + this.voteType = voteType; + this.nComments = nComments; + this.flair = flair; + this.awards = awards; + this.nAwards = nAwards; + this.hidden = hidden; + this.spoiler = spoiler; + this.nsfw = nsfw; + this.stickied = stickied; + this.archived = archived; + this.locked = locked; + this.saved = saved; + this.isCrosspost = isCrosspost; + } + + public Post(String id, String fullName, String subredditName, String subredditNamePrefixed, + String author, String authorFlair, String authorFlairHTML, + long postTimeMillis, String title, + String url, String permalink, int score, int postType, int voteType, int nComments, + String flair, String awards, int nAwards, boolean hidden, boolean spoiler, boolean nsfw, + boolean stickied, boolean archived, boolean locked, boolean saved, boolean isCrosspost) { + this.id = id; + this.fullName = fullName; + this.subredditName = subredditName; + this.subredditNamePrefixed = subredditNamePrefixed; + this.author = author; + this.authorNamePrefixed = "u/" + author; + this.authorFlair = authorFlair; + this.authorFlairHTML = authorFlairHTML; + this.postTimeMillis = postTimeMillis; + this.title = title; + this.url = url; + this.permalink = APIUtils.API_BASE_URI + permalink; + this.score = score; + this.postType = postType; + this.voteType = voteType; + this.nComments = nComments; + this.flair = flair; + this.awards = awards; + this.nAwards = nAwards; + this.hidden = hidden; + this.spoiler = spoiler; + this.nsfw = nsfw; + this.stickied = stickied; + this.archived = archived; + this.locked = locked; + this.saved = saved; + this.isCrosspost = isCrosspost; + } + + protected Post(Parcel in) { + id = in.readString(); + fullName = in.readString(); + subredditName = in.readString(); + subredditNamePrefixed = in.readString(); + subredditIconUrl = in.readString(); + author = in.readString(); + authorNamePrefixed = in.readString(); + authorFlair = in.readString(); + authorFlairHTML = in.readString(); + authorIconUrl = in.readString(); + postTimeMillis = in.readLong(); + title = in.readString(); + selfText = in.readString(); + selfTextPlain = in.readString(); + selfTextPlainTrimmed = in.readString(); + url = in.readString(); + videoUrl = in.readString(); + videoDownloadUrl = in.readString(); + gfycatId = in.readString(); + isGfycat = in.readByte() != 0; + isRedgifs = in.readByte() != 0; + loadGfyOrRedgifsVideoSuccess = in.readByte() != 0; + permalink = in.readString(); + flair = in.readString(); + awards = in.readString(); + nAwards = in.readInt(); + score = in.readInt(); + postType = in.readInt(); + voteType = in.readInt(); + nComments = in.readInt(); + hidden = in.readByte() != 0; + spoiler = in.readByte() != 0; + nsfw = in.readByte() != 0; + stickied = in.readByte() != 0; + archived = in.readByte() != 0; + locked = in.readByte() != 0; + saved = in.readByte() != 0; + isCrosspost = in.readByte() != 0; + crosspostParentId = in.readString(); + in.readTypedList(previews, Preview.CREATOR); + in.readTypedList(gallery, Gallery.CREATOR); + } + + public String getId() { + return id; + } + + public String getFullName() { + return fullName; + } + + public String getSubredditName() { + return subredditName; + } + + public String getSubredditNamePrefixed() { + return subredditNamePrefixed; + } + + public String getSubredditIconUrl() { + return subredditIconUrl; + } + + public void setSubredditIconUrl(String subredditIconUrl) { + this.subredditIconUrl = subredditIconUrl; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + this.authorNamePrefixed = "u/" + author; + } + + public String getAuthorNamePrefixed() { + return authorNamePrefixed; + } + + public String getAuthorFlair() { + return authorFlair; + } + + public String getAuthorFlairHTML() { + return authorFlairHTML; + } + + public String getAuthorIconUrl() { + return authorIconUrl; + } + + public void setAuthorIconUrl(String authorIconUrl) { + this.authorIconUrl = authorIconUrl; + } + + public long getPostTimeMillis() { + return postTimeMillis; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getSelfText() { + return selfText; + } + + public void setSelfText(String selfText) { + this.selfText = selfText; + } + + public String getSelfTextPlain() { + return selfTextPlain; + } + + public void setSelfTextPlain(String selfTextPlain) { + this.selfTextPlain = selfTextPlain; + } + + public String getSelfTextPlainTrimmed() { + return selfTextPlainTrimmed; + } + + public void setSelfTextPlainTrimmed(String selfTextPlainTrimmed) { + this.selfTextPlainTrimmed = selfTextPlainTrimmed; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getVideoUrl() { + return videoUrl; + } + + public void setVideoUrl(String videoUrl) { + this.videoUrl = videoUrl; + } + + public String getVideoDownloadUrl() { + return videoDownloadUrl; + } + + public void setVideoDownloadUrl(String videoDownloadUrl) { + this.videoDownloadUrl = videoDownloadUrl; + } + + public String getGfycatId() { + return gfycatId; + } + + public void setGfycatId(String gfycatId) { + this.gfycatId = gfycatId; + } + + public boolean isGfycat() { + return isGfycat; + } + + public void setIsGfycat(boolean isGfycat) { + this.isGfycat = isGfycat; + } + + public boolean isRedgifs() { + return isRedgifs; + } + + public void setIsRedgifs(boolean isRedgifs) { + this.isRedgifs = isRedgifs; + } + + public boolean isLoadGfyOrRedgifsVideoSuccess() { + return loadGfyOrRedgifsVideoSuccess; + } + + public void setLoadGfyOrRedgifsVideoSuccess(boolean loadGfyOrRedgifsVideoSuccess) { + this.loadGfyOrRedgifsVideoSuccess = loadGfyOrRedgifsVideoSuccess; + } + + public String getPermalink() { + return permalink; + } + + public String getFlair() { + return flair; + } + + public void setFlair(String flair) { + this.flair = flair; + } + + public String getAwards() { + return awards; + } + + public void addAwards(String newAwardsHTML) { + awards += newAwardsHTML; + } + + public int getnAwards() { + return nAwards; + } + + public void addAwards(int newNAwards) { + nAwards += newNAwards; + } + + public int getScore() { + return score; + } + + public void setScore(int score) { + this.score = score; + } + + public int getPostType() { + return postType; + } + + public void setPostType(int postType) { + this.postType = postType; + } + + public int getVoteType() { + return voteType; + } + + public void setVoteType(int voteType) { + this.voteType = voteType; + } + + public int getNComments() { + return nComments; + } + + public void setNComments(int nComments) { + this.nComments = nComments; + } + + public boolean isHidden() { + return hidden; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + public boolean isSpoiler() { + return spoiler; + } + + public void setSpoiler(boolean spoiler) { + this.spoiler = spoiler; + } + + public boolean isNSFW() { + return nsfw; + } + + public void setNSFW(boolean nsfw) { + this.nsfw = nsfw; + } + + @Override + public int describeContents() { + return 0; + } + + public boolean isStickied() { + return stickied; + } + + public boolean isArchived() { + return archived; + } + + public boolean isLocked() { + return locked; + } + + public boolean isSaved() { + return saved; + } + + public void setSaved(boolean saved) { + this.saved = saved; + } + + public boolean isCrosspost() { + return isCrosspost; + } + + public String getCrosspostParentId() { + return crosspostParentId; + } + + public void setCrosspostParentId(String crosspostParentId) { + this.crosspostParentId = crosspostParentId; + } + + public ArrayList getPreviews() { + return previews; + } + + public void setPreviews(ArrayList previews) { + this.previews = previews; + } + + public ArrayList getGallery() { + return gallery; + } + + public void setGallery(ArrayList gallery) { + this.gallery = gallery; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(id); + parcel.writeString(fullName); + parcel.writeString(subredditName); + parcel.writeString(subredditNamePrefixed); + parcel.writeString(subredditIconUrl); + parcel.writeString(author); + parcel.writeString(authorNamePrefixed); + parcel.writeString(authorFlair); + parcel.writeString(authorFlairHTML); + parcel.writeString(authorIconUrl); + parcel.writeLong(postTimeMillis); + parcel.writeString(title); + parcel.writeString(selfText); + parcel.writeString(selfTextPlain); + parcel.writeString(selfTextPlainTrimmed); + parcel.writeString(url); + parcel.writeString(videoUrl); + parcel.writeString(videoDownloadUrl); + parcel.writeString(gfycatId); + parcel.writeByte((byte) (isGfycat ? 1 : 0)); + parcel.writeByte((byte) (isRedgifs ? 1 : 0)); + parcel.writeByte((byte) (loadGfyOrRedgifsVideoSuccess ? 1 : 0)); + parcel.writeString(permalink); + parcel.writeString(flair); + parcel.writeString(awards); + parcel.writeInt(nAwards); + parcel.writeInt(score); + parcel.writeInt(postType); + parcel.writeInt(voteType); + parcel.writeInt(nComments); + parcel.writeByte((byte) (hidden ? 1 : 0)); + parcel.writeByte((byte) (spoiler ? 1 : 0)); + parcel.writeByte((byte) (nsfw ? 1 : 0)); + parcel.writeByte((byte) (stickied ? 1 : 0)); + parcel.writeByte((byte) (archived ? 1 : 0)); + parcel.writeByte((byte) (locked ? 1 : 0)); + parcel.writeByte((byte) (saved ? 1 : 0)); + parcel.writeByte((byte) (isCrosspost ? 1 : 0)); + parcel.writeString(crosspostParentId); + parcel.writeTypedList(previews); + parcel.writeTypedList(gallery); + } + + @Override + public boolean equals(@Nullable Object obj) { + if (!(obj instanceof Post)) { + return false; + } + return ((Post) obj).id.equals(id); + } + + @Override + public int hashCode() { + return id.hashCode(); + } + + public static class Gallery implements Parcelable { + public static final int TYPE_IMAGE = 0; + public static final int TYPE_GIF = 1; + public static final int TYPE_VIDEO = 2; + + public String mimeType; + public String url; + public String fileName; + public int mediaType; + + public Gallery(String mimeType, String url, String fileName) { + this.mimeType = mimeType; + this.url = url; + this.fileName = fileName; + if (mimeType.contains("gif")) { + mediaType = TYPE_GIF; + } else if (mimeType.contains("jpg") || mimeType.contains("png")) { + mediaType = TYPE_IMAGE; + } else { + mediaType = TYPE_VIDEO; + } + } + + protected Gallery(Parcel in) { + mimeType = in.readString(); + url = in.readString(); + fileName = in.readString(); + mediaType = in.readInt(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Gallery createFromParcel(Parcel in) { + return new Gallery(in); + } + + @Override + public Gallery[] newArray(int size) { + return new Gallery[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(mimeType); + parcel.writeString(url); + parcel.writeString(fileName); + parcel.writeInt(mediaType); + } + } + + public static class Preview implements Parcelable { + private String previewUrl; + private int previewWidth; + private int previewHeight; + + public Preview(String previewUrl, int previewWidth, int previewHeight) { + this.previewUrl = previewUrl; + this.previewWidth = previewWidth; + this.previewHeight = previewHeight; + } + + protected Preview(Parcel in) { + previewUrl = in.readString(); + previewWidth = in.readInt(); + previewHeight = in.readInt(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public Preview createFromParcel(Parcel in) { + return new Preview(in); + } + + @Override + public Preview[] newArray(int size) { + return new Preview[size]; + } + }; + + public String getPreviewUrl() { + return previewUrl; + } + + public void setPreviewUrl(String previewUrl) { + this.previewUrl = previewUrl; + } + + public int getPreviewWidth() { + return previewWidth; + } + + public void setPreviewWidth(int previewWidth) { + this.previewWidth = previewWidth; + } + + public int getPreviewHeight() { + return previewHeight; + } + + public void setPreviewHeight(int previewHeight) { + this.previewHeight = previewHeight; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(previewUrl); + parcel.writeInt(previewWidth); + parcel.writeInt(previewHeight); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java new file mode 100644 index 00000000..e1e50733 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSource.java @@ -0,0 +1,927 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.PageKeyedDataSource; + +import java.util.ArrayList; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; + +public class PostDataSource extends PageKeyedDataSource { + + public static final int TYPE_FRONT_PAGE = 0; + public static final int TYPE_SUBREDDIT = 1; + public static final int TYPE_USER = 2; + public static final int TYPE_SEARCH = 3; + public static final int TYPE_MULTI_REDDIT = 4; + + public static final String USER_WHERE_SUBMITTED = "submitted"; + public static final String USER_WHERE_UPVOTED = "upvoted"; + public static final String USER_WHERE_DOWNVOTED = "downvoted"; + public static final String USER_WHERE_HIDDEN = "hidden"; + public static final String USER_WHERE_SAVED = "saved"; + public static final String USER_WHERE_GILDED = "gilded"; + + private Retrofit retrofit; + private String accessToken; + private String accountName; + private Locale locale; + private SharedPreferences sharedPreferences; + private SharedPreferences postFeedScrolledPositionSharedPreferences; + private String subredditOrUserName; + private String query; + private int postType; + private SortType sortType; + private boolean nsfw; + private int filter; + private List subredditFilterList; + private String userWhere; + private String multiRedditPath; + private LinkedHashSet postLinkedHashSet; + + private MutableLiveData paginationNetworkStateLiveData; + private MutableLiveData initialLoadStateLiveData; + private MutableLiveData hasPostLiveData; + + private LoadParams params; + private LoadCallback callback; + + PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, int postType, + SortType sortType, int filter, boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasPostLiveData = new MutableLiveData<>(); + this.postType = postType; + this.sortType = sortType == null ? new SortType(SortType.Type.BEST) : sortType; + this.filter = filter; + this.nsfw = nsfw; + postLinkedHashSet = new LinkedHashSet<>(); + } + + PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String path, int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + if (postType == TYPE_SUBREDDIT) { + this.subredditOrUserName = path; + } else { + if (sortType != null) { + if (path.endsWith("/")) { + multiRedditPath = path + sortType.getType().value; + } else { + multiRedditPath = path + "/" + sortType.getType().value; + } + } else { + multiRedditPath = path; + } + } + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasPostLiveData = new MutableLiveData<>(); + this.postType = postType; + if (sortType == null) { + if (path.equals("popular") || path.equals("all")) { + this.sortType = new SortType(SortType.Type.HOT); + } else { + this.sortType = new SortType(SortType.Type.BEST); + } + } else { + this.sortType = sortType; + } + this.filter = filter; + this.nsfw = nsfw; + this.subredditFilterList = subredditFilterList; + postLinkedHashSet = new LinkedHashSet<>(); + } + + PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, + int postType, SortType sortType, String where, int filter, boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditOrUserName = subredditOrUserName; + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasPostLiveData = new MutableLiveData<>(); + this.postType = postType; + this.sortType = sortType == null ? new SortType(SortType.Type.NEW) : sortType; + userWhere = where; + this.filter = filter; + this.nsfw = nsfw; + postLinkedHashSet = new LinkedHashSet<>(); + } + + PostDataSource(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, + String query, int postType, SortType sortType, int filter, boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditOrUserName = subredditOrUserName; + this.query = query; + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasPostLiveData = new MutableLiveData<>(); + this.postType = postType; + this.sortType = sortType == null ? new SortType(SortType.Type.RELEVANCE) : sortType; + this.filter = filter; + this.nsfw = nsfw; + postLinkedHashSet = new LinkedHashSet<>(); + } + + MutableLiveData getPaginationNetworkStateLiveData() { + return paginationNetworkStateLiveData; + } + + MutableLiveData getInitialLoadStateLiveData() { + return initialLoadStateLiveData; + } + + MutableLiveData hasPostLiveData() { + return hasPostLiveData; + } + + @Override + public void loadInitial(@NonNull LoadInitialParams params, @NonNull final LoadInitialCallback callback) { + initialLoadStateLiveData.postValue(NetworkState.LOADING); + switch (postType) { + case TYPE_FRONT_PAGE: + boolean savePostFeedScrolledPosition = sortType != null && sortType.getType() == SortType.Type.BEST && sharedPreferences.getBoolean(SharedPreferencesUtils.SAVE_FRONT_PAGE_SCROLLED_POSITION, false); + String accountNameForCache = accountName == null ? SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_ANONYMOUS : accountName; + if (savePostFeedScrolledPosition) { + loadBestPostsInitial(callback, postFeedScrolledPositionSharedPreferences.getString(accountNameForCache + SharedPreferencesUtils.FRONT_PAGE_SCROLLED_POSITION_FRONT_PAGE_BASE, null)); + } else { + loadBestPostsInitial(callback, null); + } + break; + case TYPE_SUBREDDIT: + loadSubredditPostsInitial(callback, null); + break; + case TYPE_USER: + loadUserPostsInitial(callback, null); + break; + case TYPE_SEARCH: + loadSearchPostsInitial(callback, null); + break; + case TYPE_MULTI_REDDIT: + loadMultiRedditPostsInitial(callback, null); + break; + } + } + + @Override + public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { + + } + + @Override + public void loadAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback) { + this.params = params; + this.callback = callback; + + if (params == null || "".equals(params.key) || "null".equals(params.key)) { + return; + } + + paginationNetworkStateLiveData.postValue(NetworkState.LOADING); + + switch (postType) { + case TYPE_FRONT_PAGE: + loadBestPostsAfter(params, callback, null); + break; + case TYPE_SUBREDDIT: + loadSubredditPostsAfter(params, callback, null); + break; + case TYPE_USER: + loadUserPostsAfter(params, callback, null); + break; + case TYPE_SEARCH: + loadSearchPostsAfter(params, callback, null); + break; + case TYPE_MULTI_REDDIT: + loadMultiRedditPostsAfter(params, callback, null); + break; + } + } + + private void loadBestPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { + RedditAPI api = retrofit.create(RedditAPI.class); + Call bestPost; + if(sortType.getTime() != null) { + bestPost = api.getBestPosts(sortType.getType().value, sortType.getTime().value, lastItem, + APIUtils.getOAuthHeader(accessToken)); + } else { + bestPost = api.getBestPosts(sortType.getType().value, lastItem, APIUtils.getOAuthHeader(accessToken)); + } + bestPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + String nextPageKey; + if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; + } else { + nextPageKey = lastItem; + } + + if (newPosts.size() != 0) { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(true); + } else if (nextPageKey != null) { + loadBestPostsInitial(callback, nextPageKey); + return; + } else { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(false); + } + + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onParsePostsListingFail() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing posts")); + } + }); + } else { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, + "code: " + response.code() + " message: " + response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, + errorMessage + " " + call.request().url().toString())); + } + }); + } + + private void loadBestPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + + RedditAPI api = retrofit.create(RedditAPI.class); + Call bestPost; + if(sortType.getTime() != null) { + bestPost = api.getBestPosts(sortType.getType().value, sortType.getTime().value, after, + APIUtils.getOAuthHeader(accessToken)); + } else { + bestPost = api.getBestPosts(sortType.getType().value, after, APIUtils.getOAuthHeader(accessToken)); + } + + bestPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadBestPostsAfter(params, callback, lastItem); + } else { + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + } + + @Override + public void onParsePostsListingFail() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing more posts")); + } + }); + } else { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + private void loadSubredditPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { + RedditAPI api = retrofit.create(RedditAPI.class); + + Call getPost; + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, sortType.getTime().value, lastItem); + } else { + getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, lastItem); + } + } else { + if (sortType.getTime() != null) { + getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, + sortType.getTime().value, lastItem, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, + lastItem, APIUtils.getOAuthHeader(accessToken)); + } + } + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, subredditFilterList, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + String nextPageKey; + if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; + } else { + nextPageKey = lastItem; + } + + if (newPosts.size() != 0) { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(true); + } else if (nextPageKey != null) { + loadSubredditPostsInitial(callback, nextPageKey); + return; + } else { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(false); + } + + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onParsePostsListingFail() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing posts")); + } + }); + } else { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, + "code: " + response + " message: " + response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, + errorMessage + " " + call.request().url().toString())); + } + }); + } + + private void loadSubredditPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + + RedditAPI api = retrofit.create(RedditAPI.class); + + Call getPost; + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, + sortType.getTime().value, after); + } else { + getPost = api.getSubredditBestPosts(subredditOrUserName, sortType.getType().value, after); + } + } else { + if (sortType.getTime() != null) { + getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, + sortType.getTime().value, after, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.getSubredditBestPostsOauth(subredditOrUserName, sortType.getType().value, + after, APIUtils.getOAuthHeader(accessToken)); + } + } + + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, subredditFilterList, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadSubredditPostsAfter(params, callback, lastItem); + } else { + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + } + + @Override + public void onParsePostsListingFail() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + private void loadUserPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { + RedditAPI api = retrofit.create(RedditAPI.class); + + Call getPost; + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.getUserPosts(subredditOrUserName, lastItem, sortType.getType().value, + sortType.getTime().value); + } else { + getPost = api.getUserPosts(subredditOrUserName, lastItem, sortType.getType().value); + } + } else { + if (sortType.getTime() != null) { + getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, lastItem, sortType.getType().value, + sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, lastItem, sortType.getType().value, + APIUtils.getOAuthHeader(accessToken)); + } + } + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + String nextPageKey; + if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; + } else { + nextPageKey = lastItem; + } + + if (newPosts.size() != 0) { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(true); + } else if (nextPageKey != null) { + loadUserPostsInitial(callback, nextPageKey); + return; + } else { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(false); + } + + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onParsePostsListingFail() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + private void loadUserPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + + RedditAPI api = retrofit.create(RedditAPI.class); + + Call getPost; + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.getUserPosts(subredditOrUserName, after, sortType.getType().value, + sortType.getTime().value); + } else { + getPost = api.getUserPosts(subredditOrUserName, after, sortType.getType().value); + } + } else { + if (sortType.getTime() != null) { + getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, after, sortType.getType().value, + sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.getUserPostsOauth(subredditOrUserName, userWhere, after, sortType.getType().value, + APIUtils.getOAuthHeader(accessToken)); + } + } + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadUserPostsAfter(params, callback, lastItem); + } else { + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + } + + @Override + public void onParsePostsListingFail() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + private void loadSearchPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { + RedditAPI api = retrofit.create(RedditAPI.class); + Call getPost; + + if (subredditOrUserName == null) { + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.searchPosts(query, lastItem, sortType.getType().value, sortType.getTime().value); + } else { + getPost = api.searchPosts(query, lastItem, sortType.getType().value); + } + } else { + if(sortType.getTime() != null) { + getPost = api.searchPostsOauth(query, lastItem, sortType.getType().value, + sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.searchPostsOauth(query, lastItem, sortType.getType().value, + APIUtils.getOAuthHeader(accessToken)); + } + } + } else { + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, + sortType.getType().value, sortType.getTime().value, lastItem); + } else { + getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, + sortType.getType().value, lastItem); + } + } else { + if (sortType.getTime() != null) { + getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, + sortType.getType().value, sortType.getTime().value, lastItem, + APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, + sortType.getType().value, lastItem, + APIUtils.getOAuthHeader(accessToken)); + } + } + } + + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + String nextPageKey; + if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; + } else { + nextPageKey = lastItem; + } + + if (newPosts.size() != 0) { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(true); + } else if (nextPageKey != null) { + loadSearchPostsInitial(callback, nextPageKey); + return; + } else { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(false); + } + + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onParsePostsListingFail() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + private void loadSearchPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + + RedditAPI api = retrofit.create(RedditAPI.class); + Call getPost; + + if (subredditOrUserName == null) { + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.searchPosts(query, after, sortType.getType().value, sortType.getTime().value); + } else { + getPost = api.searchPosts(query, after, sortType.getType().value); + } + } else { + if (sortType.getTime() != null) { + getPost = api.searchPostsOauth(query, after, sortType.getType().value, + sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.searchPostsOauth(query, after, sortType.getType().value, APIUtils.getOAuthHeader(accessToken)); + } + } + } else { + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, + sortType.getType().value, sortType.getTime().value, after); + } else { + getPost = api.searchPostsInSpecificSubreddit(subredditOrUserName, query, + sortType.getType().value, after); + } + } else { + if (sortType.getTime() != null) { + getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, + sortType.getType().value, sortType.getTime().value, after, + APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.searchPostsInSpecificSubredditOauth(subredditOrUserName, query, + sortType.getType().value, after, APIUtils.getOAuthHeader(accessToken)); + } + } + } + + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadSearchPostsAfter(params, callback, lastItem); + } else { + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + } + + @Override + public void onParsePostsListingFail() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + private void loadMultiRedditPostsInitial(@NonNull final LoadInitialCallback callback, String lastItem) { + RedditAPI api = retrofit.create(RedditAPI.class); + Call getPost; + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.getMultiRedditPosts(multiRedditPath, lastItem, sortType.getTime().value); + } else { + getPost = api.getMultiRedditPosts(multiRedditPath, lastItem); + } + } else { + if (sortType.getTime() != null) { + getPost = api.getMultiRedditPostsOauth(multiRedditPath, lastItem, + sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.getMultiRedditPostsOauth(multiRedditPath, lastItem, + APIUtils.getOAuthHeader(accessToken)); + } + } + + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + String nextPageKey; + if (lastItem == null || lastItem.equals("") || lastItem.equals("null")) { + nextPageKey = null; + } else { + nextPageKey = lastItem; + } + + if (newPosts.size() != 0) { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(true); + } else if (nextPageKey != null) { + loadMultiRedditPostsInitial(callback, nextPageKey); + return; + } else { + postLinkedHashSet.addAll(newPosts); + callback.onResult(new ArrayList<>(newPosts), null, nextPageKey); + hasPostLiveData.postValue(false); + } + + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onParsePostsListingFail() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + private void loadMultiRedditPostsAfter(@NonNull LoadParams params, @NonNull final LoadCallback callback, String lastItem) { + String after = lastItem == null ? params.key : lastItem; + + RedditAPI api = retrofit.create(RedditAPI.class); + + Call getPost; + if (accessToken == null) { + if (sortType.getTime() != null) { + getPost = api.getMultiRedditPosts(multiRedditPath, after, + sortType.getTime().value); + } else { + getPost = api.getMultiRedditPosts(multiRedditPath, after); + } + } else { + if (sortType.getTime() != null) { + getPost = api.getMultiRedditPostsOauth(multiRedditPath, after, + sortType.getTime().value, APIUtils.getOAuthHeader(accessToken)); + } else { + getPost = api.getMultiRedditPostsOauth(multiRedditPath, after, + APIUtils.getOAuthHeader(accessToken)); + } + } + getPost.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePosts(response.body(), -1, filter, nsfw, + new ParsePost.ParsePostsListingListener() { + @Override + public void onParsePostsListingSuccess(LinkedHashSet newPosts, String lastItem) { + if (newPosts.size() == 0 && lastItem != null && !lastItem.equals("") && !lastItem.equals("null")) { + loadMultiRedditPostsAfter(params, callback, lastItem); + } else { + int currentPostsSize = postLinkedHashSet.size(); + postLinkedHashSet.addAll(newPosts); + if (currentPostsSize == postLinkedHashSet.size()) { + callback.onResult(new ArrayList<>(), lastItem); + } else { + List newPostsList = new ArrayList<>(postLinkedHashSet).subList(currentPostsSize, postLinkedHashSet.size()); + callback.onResult(newPostsList, lastItem); + } + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + } + + @Override + public void onParsePostsListingFail() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error parsing data")); + } + }); + } else { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, response.message())); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String errorMessage = t.getMessage(); + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage)); + } + }); + } + + void retryLoadingMore() { + loadAfter(params, callback); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java new file mode 100644 index 00000000..5973e009 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostDataSourceFactory.java @@ -0,0 +1,141 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.DataSource; + +import java.util.List; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; +import retrofit2.Retrofit; + +class PostDataSourceFactory extends DataSource.Factory { + private Retrofit retrofit; + private String accessToken; + private String accountName; + private Locale locale; + private SharedPreferences sharedPreferences; + private SharedPreferences postFeedScrolledPositionSharedPreferences; + private String subredditName; + private String query; + private int postType; + private SortType sortType; + private String userWhere; + private int filter; + private boolean nsfw; + private List subredditFilterList; + + private PostDataSource postDataSource; + private MutableLiveData postDataSourceLiveData; + + PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + int postType, SortType sortType, int filter, boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + postDataSourceLiveData = new MutableLiveData<>(); + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + } + + PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String subredditName, int postType, SortType sortType, int filter, boolean nsfw, + List subredditFilterList) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + postDataSourceLiveData = new MutableLiveData<>(); + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + this.subredditFilterList = subredditFilterList; + } + + PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String subredditName, int postType, SortType sortType, String where, int filter, + boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + postDataSourceLiveData = new MutableLiveData<>(); + this.postType = postType; + this.sortType = sortType; + userWhere = where; + this.filter = filter; + this.nsfw = nsfw; + } + + PostDataSourceFactory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + String subredditName, String query, int postType, SortType sortType, int filter, + boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + this.query = query; + postDataSourceLiveData = new MutableLiveData<>(); + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + } + + @NonNull + @Override + public DataSource create() { + if (postType == PostDataSource.TYPE_FRONT_PAGE) { + postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, + sharedPreferences, postFeedScrolledPositionSharedPreferences, postType, sortType, filter, nsfw); + } else if (postType == PostDataSource.TYPE_SEARCH) { + postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, + sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw); + } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { + postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, + sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList); + } else { + postDataSource = new PostDataSource(retrofit, accessToken, accountName, locale, + sharedPreferences, postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, userWhere, filter, nsfw); + } + + postDataSourceLiveData.postValue(postDataSource); + return postDataSource; + } + + public MutableLiveData getPostDataSourceLiveData() { + return postDataSourceLiveData; + } + + PostDataSource getPostDataSource() { + return postDataSource; + } + + void changeNSFWAndSortType(boolean nsfw, SortType sortType) { + this.nsfw = nsfw; + this.sortType = sortType; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java new file mode 100644 index 00000000..114c68ee --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java @@ -0,0 +1,322 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.content.SharedPreferences; + +import androidx.annotation.NonNull; +import androidx.core.util.Pair; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MediatorLiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Transformations; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.LivePagedListBuilder; +import androidx.paging.PagedList; + +import java.util.List; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.SortType; +import ml.docilealligator.infinityforreddit.subredditfilter.SubredditFilter; +import retrofit2.Retrofit; + +public class PostViewModel extends ViewModel { + private PostDataSourceFactory postDataSourceFactory; + private LiveData paginationNetworkState; + private LiveData initialLoadingState; + private LiveData hasPostLiveData; + private LiveData> posts; + private MutableLiveData nsfwLiveData; + private MutableLiveData sortTypeLiveData; + private NSFWAndSortTypeLiveData nsfwAndSortTypeLiveData; + + public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences cache, int postType, + SortType sortType, int filter, boolean nsfw) { + postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, + sharedPreferences, cache, postType, sortType, filter, nsfw); + + initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getPaginationNetworkStateLiveData); + hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::hasPostLiveData); + + nsfwLiveData = new MutableLiveData<>(); + nsfwLiveData.postValue(nsfw); + sortTypeLiveData = new MutableLiveData<>(); + sortTypeLiveData.postValue(sortType); + + nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { + postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); + return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); + }); + } + + public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, + int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { + postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, + sharedPreferences, cache, subredditName, postType, sortType, filter, nsfw, subredditFilterList); + + initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getPaginationNetworkStateLiveData); + hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::hasPostLiveData); + + nsfwLiveData = new MutableLiveData<>(); + nsfwLiveData.postValue(nsfw); + sortTypeLiveData = new MutableLiveData<>(); + sortTypeLiveData.postValue(sortType); + + nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { + postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); + return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); + }); + } + + public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, + int postType, SortType sortType, String where, int filter, + boolean nsfw) { + postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, + sharedPreferences, cache, subredditName, postType, sortType, where, filter, nsfw); + + initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getPaginationNetworkStateLiveData); + hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::hasPostLiveData); + + nsfwLiveData = new MutableLiveData<>(); + nsfwLiveData.postValue(nsfw); + sortTypeLiveData = new MutableLiveData<>(); + sortTypeLiveData.postValue(sortType); + + nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { + postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); + return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); + }); + } + + public PostViewModel(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences cache, String subredditName, + String query, int postType, SortType sortType, int filter, + boolean nsfw) { + postDataSourceFactory = new PostDataSourceFactory(retrofit, accessToken, accountName, locale, + sharedPreferences, cache, subredditName, query, postType, sortType, filter, nsfw); + + initialLoadingState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::getPaginationNetworkStateLiveData); + hasPostLiveData = Transformations.switchMap(postDataSourceFactory.getPostDataSourceLiveData(), + PostDataSource::hasPostLiveData); + + nsfwLiveData = new MutableLiveData<>(); + nsfwLiveData.postValue(nsfw); + sortTypeLiveData = new MutableLiveData<>(); + sortTypeLiveData.postValue(sortType); + + nsfwAndSortTypeLiveData = new NSFWAndSortTypeLiveData(nsfwLiveData, sortTypeLiveData); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + posts = Transformations.switchMap(nsfwAndSortTypeLiveData, nsfwAndSort -> { + postDataSourceFactory.changeNSFWAndSortType(nsfwLiveData.getValue(), sortTypeLiveData.getValue()); + return (new LivePagedListBuilder(postDataSourceFactory, pagedListConfig)).build(); + }); + } + + public LiveData> getPosts() { + return posts; + } + + public LiveData getPaginationNetworkState() { + return paginationNetworkState; + } + + public LiveData getInitialLoadingState() { + return initialLoadingState; + } + + public LiveData hasPost() { + return hasPostLiveData; + } + + public void refresh() { + postDataSourceFactory.getPostDataSource().invalidate(); + } + + public void retryLoadingMore() { + postDataSourceFactory.getPostDataSource().retryLoadingMore(); + } + + public void changeSortType(SortType sortType) { + sortTypeLiveData.postValue(sortType); + } + + public void changeNSFW(boolean nsfw) { + nsfwLiveData.postValue(nsfw); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Retrofit retrofit; + private String accessToken; + private String accountName; + private Locale locale; + private SharedPreferences sharedPreferences; + private SharedPreferences postFeedScrolledPositionSharedPreferences; + private String subredditName; + private String query; + private int postType; + private SortType sortType; + private String userWhere; + private int filter; + private boolean nsfw; + private List subredditFilterList; + + public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, + int postType, SortType sortType, int filter, boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + } + + public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, + int postType, SortType sortType, int filter, boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + } + + //With subreddit filter + public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, + int postType, SortType sortType, int filter, boolean nsfw, List subredditFilterList) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + this.subredditFilterList = subredditFilterList; + } + + //User posts + public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, + int postType, SortType sortType, String where, int filter, + boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + this.postType = postType; + this.sortType = sortType; + userWhere = where; + this.filter = filter; + this.nsfw = nsfw; + } + + public Factory(Retrofit retrofit, String accessToken, String accountName, Locale locale, + SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditName, + String query, int postType, SortType sortType, int filter, boolean nsfw) { + this.retrofit = retrofit; + this.accessToken = accessToken; + this.accountName = accountName; + this.locale = locale; + this.sharedPreferences = sharedPreferences; + this.postFeedScrolledPositionSharedPreferences = postFeedScrolledPositionSharedPreferences; + this.subredditName = subredditName; + this.query = query; + this.postType = postType; + this.sortType = sortType; + this.filter = filter; + this.nsfw = nsfw; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + if (postType == PostDataSource.TYPE_FRONT_PAGE) { + return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, + postFeedScrolledPositionSharedPreferences, postType, sortType, filter, nsfw); + } else if (postType == PostDataSource.TYPE_SEARCH) { + return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, query, postType, sortType, filter, nsfw); + } else if (postType == PostDataSource.TYPE_SUBREDDIT || postType == PostDataSource.TYPE_MULTI_REDDIT) { + return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, filter, nsfw, subredditFilterList); + } else { + return (T) new PostViewModel(retrofit, accessToken, accountName, locale, sharedPreferences, + postFeedScrolledPositionSharedPreferences, subredditName, postType, sortType, userWhere, filter, nsfw); + } + } + } + + private static class NSFWAndSortTypeLiveData extends MediatorLiveData> { + public NSFWAndSortTypeLiveData(LiveData nsfw, LiveData sortType) { + addSource(nsfw, accessToken1 -> setValue(Pair.create(accessToken1, sortType.getValue()))); + addSource(sortType, sortType1 -> setValue(Pair.create(nsfw.getValue(), sortType1))); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java new file mode 100644 index 00000000..14216298 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/SubmitPost.java @@ -0,0 +1,478 @@ +package ml.docilealligator.infinityforreddit.post; + +import android.graphics.Bitmap; +import android.os.AsyncTask; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; +import org.xmlpull.v1.XmlPullParserFactory; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.StringReader; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import okhttp3.MediaType; +import okhttp3.MultipartBody; +import okhttp3.RequestBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class SubmitPost { + public static void submitTextOrLinkPost(Retrofit oauthRetrofit, String accessToken, + Locale locale, String subredditName, String title, String content, + Flair flair, boolean isSpoiler, boolean isNSFW, String kind, + SubmitPostListener submitPostListener) { + submitPost(oauthRetrofit, accessToken, locale, subredditName, title, content, + flair, isSpoiler, isNSFW, kind, null, submitPostListener); + } + + public static void submitImagePost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + String accessToken, Locale locale, + String subredditName, String title, Bitmap image, Flair flair, + boolean isSpoiler, boolean isNSFW, SubmitPostListener submitPostListener) { + uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, image, + new UploadImageListener() { + @Override + public void uploaded(String imageUrl) { + submitPost(oauthRetrofit, accessToken, locale, + subredditName, title, imageUrl, flair, isSpoiler, isNSFW, + APIUtils.KIND_IMAGE, null, submitPostListener); + } + + @Override + public void uploadFailed(@Nullable String errorMessage) { + submitPostListener.submitFailed(errorMessage); + } + }); + } + + public static void submitVideoPost(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + Retrofit uploadVideoRetrofit, String accessToken, + Locale locale, String subredditName, String title, File buffer, String mimeType, + Bitmap posterBitmap, Flair flair, boolean isSpoiler, boolean isNSFW, + SubmitPostListener submitPostListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + String fileType = mimeType.substring(mimeType.indexOf("/") + 1); + + Map uploadImageParams = new HashMap<>(); + uploadImageParams.put(APIUtils.FILEPATH_KEY, "post_video." + fileType); + uploadImageParams.put(APIUtils.MIMETYPE_KEY, mimeType); + + Call uploadImageCall = api.uploadImage(APIUtils.getOAuthHeader(accessToken), uploadImageParams); + uploadImageCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { + @Override + public void parseSuccessful(Map nameValuePairsMap) { + RequestBody fileBody = RequestBody.create(buffer, MediaType.parse("application/octet-stream")); + MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_video." + fileType, fileBody); + + RedditAPI uploadVideoToAWSApi; + if (fileType.equals("gif")) { + uploadVideoToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); + } else { + uploadVideoToAWSApi = uploadVideoRetrofit.create(RedditAPI.class); + } + Call uploadMediaToAWS = uploadVideoToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); + + uploadMediaToAWS.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { + @Override + public void parseSuccessful(String url) { + uploadImage(oauthRetrofit, uploadMediaRetrofit, accessToken, + posterBitmap, new UploadImageListener() { + @Override + public void uploaded(String imageUrl) { + if (fileType.equals("gif")) { + submitPost(oauthRetrofit, accessToken, locale, + subredditName, title, url, flair, isSpoiler, isNSFW, + APIUtils.KIND_VIDEOGIF, imageUrl, submitPostListener); + } else { + submitPost(oauthRetrofit, accessToken, locale, + subredditName, title, url, flair, isSpoiler, isNSFW, + APIUtils.KIND_VIDEO, imageUrl, submitPostListener); + } + } + + @Override + public void uploadFailed(@Nullable String errorMessage) { + submitPostListener.submitFailed(errorMessage); + } + }); + } + + @Override + public void parseFailed() { + submitPostListener.submitFailed(null); + } + }).execute(); + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } + + @Override + public void parseFailed() { + submitPostListener.submitFailed(null); + } + }).execute(); + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } + + public static void submitCrosspost(Retrofit oauthRetrofit, String accessToken, + Locale locale, String subredditName, String title, String crosspostFullname, + Flair flair, boolean isSpoiler, boolean isNSFW, String kind, + SubmitPostListener submitPostListener) { + submitPost(oauthRetrofit, accessToken, locale, subredditName, title, crosspostFullname, + flair, isSpoiler, isNSFW, kind, null, submitPostListener); + } + + private static void submitPost(Retrofit oauthRetrofit, String accessToken, + Locale locale, String subredditName, String title, String content, + Flair flair, boolean isSpoiler, boolean isNSFW, String kind, + @Nullable String posterUrl, SubmitPostListener submitPostListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Map params = new HashMap<>(); + params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); + params.put(APIUtils.SR_KEY, subredditName); + params.put(APIUtils.TITLE_KEY, title); + params.put(APIUtils.KIND_KEY, kind); + switch (kind) { + case APIUtils.KIND_SELF: + params.put(APIUtils.TEXT_KEY, content); + break; + case APIUtils.KIND_LINK: + case APIUtils.KIND_IMAGE: + params.put(APIUtils.URL_KEY, content); + break; + case APIUtils.KIND_VIDEOGIF: + params.put(APIUtils.KIND_KEY, APIUtils.KIND_IMAGE); + params.put(APIUtils.URL_KEY, content); + params.put(APIUtils.VIDEO_POSTER_URL_KEY, posterUrl); + break; + case APIUtils.KIND_VIDEO: + params.put(APIUtils.URL_KEY, content); + params.put(APIUtils.VIDEO_POSTER_URL_KEY, posterUrl); + break; + case APIUtils.KIND_CROSSPOST: + params.put(APIUtils.CROSSPOST_FULLNAME_KEY, content); + break; + } + + if (flair != null) { + params.put(APIUtils.FLAIR_TEXT_KEY, flair.getText()); + params.put(APIUtils.FLAIR_ID_KEY, flair.getId()); + } + params.put(APIUtils.SPOILER_KEY, Boolean.toString(isSpoiler)); + params.put(APIUtils.NSFW_KEY, Boolean.toString(isNSFW)); + + Call submitPostCall = api.submit(APIUtils.getOAuthHeader(accessToken), params); + submitPostCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + try { + getSubmittedPost(response.body(), kind, oauthRetrofit, accessToken, + locale, submitPostListener); + } catch (JSONException e) { + e.printStackTrace(); + submitPostListener.submitFailed(null); + } + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } + + private static void uploadImage(Retrofit oauthRetrofit, Retrofit uploadMediaRetrofit, + String accessToken, Bitmap image, + UploadImageListener uploadImageListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Map uploadImageParams = new HashMap<>(); + uploadImageParams.put(APIUtils.FILEPATH_KEY, "post_image.jpg"); + uploadImageParams.put(APIUtils.MIMETYPE_KEY, "image/jpeg"); + + Call uploadImageCall = api.uploadImage(APIUtils.getOAuthHeader(accessToken), uploadImageParams); + uploadImageCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseJSONResponseFromAWSAsyncTask(response.body(), new ParseJSONResponseFromAWSAsyncTask.ParseJSONResponseFromAWSListener() { + @Override + public void parseSuccessful(Map nameValuePairsMap) { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + image.compress(Bitmap.CompressFormat.JPEG, 100, stream); + byte[] byteArray = stream.toByteArray(); + + RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), byteArray); + MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("file", "post_image.jpg", fileBody); + + RedditAPI uploadMediaToAWSApi = uploadMediaRetrofit.create(RedditAPI.class); + Call uploadMediaToAWS = uploadMediaToAWSApi.uploadMediaToAWS(nameValuePairsMap, fileToUpload); + + uploadMediaToAWS.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseXMLReponseFromAWSAsyncTask(response.body(), new ParseXMLReponseFromAWSAsyncTask.ParseXMLResponseFromAWSListener() { + @Override + public void parseSuccessful(String url) { + uploadImageListener.uploaded(url); + } + + @Override + public void parseFailed() { + uploadImageListener.uploadFailed(null); + } + }).execute(); + } else { + uploadImageListener.uploadFailed("Error: " + response.code()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + uploadImageListener.uploadFailed(t.getMessage()); + } + }); + } + + @Override + public void parseFailed() { + uploadImageListener.uploadFailed(null); + } + }).execute(); + } else { + uploadImageListener.uploadFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + uploadImageListener.uploadFailed(t.getMessage()); + } + }); + } + + private static void getSubmittedPost(String response, String kind, Retrofit oauthRetrofit, + String accessToken, Locale locale, + SubmitPostListener submitPostListener) throws JSONException { + JSONObject responseObject = new JSONObject(response).getJSONObject(JSONUtils.JSON_KEY); + if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) + .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); + if (error.length() != 0) { + String errorString; + if (error.length() >= 2) { + errorString = error.getString(1); + } else { + errorString = error.getString(0); + } + submitPostListener.submitFailed(errorString); + } else { + submitPostListener.submitFailed(null); + } + + return; + } + + if (!kind.equals(APIUtils.KIND_IMAGE) && !kind.equals(APIUtils.KIND_VIDEO) && !kind.equals(APIUtils.KIND_VIDEOGIF)) { + String postId = responseObject.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.ID_KEY); + + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Call getPostCall = api.getPostOauth(postId, APIUtils.getOAuthHeader(accessToken)); + getPostCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParsePost.parsePost(response.body(), new ParsePost.ParsePostListener() { + @Override + public void onParsePostSuccess(Post post) { + submitPostListener.submitSuccessful(post); + } + + @Override + public void onParsePostFail() { + submitPostListener.submitFailed(null); + } + }); + } else { + submitPostListener.submitFailed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + submitPostListener.submitFailed(t.getMessage()); + } + }); + } else { + submitPostListener.submitSuccessful(null); + } + } + + public interface SubmitPostListener { + void submitSuccessful(Post post); + + void submitFailed(@Nullable String errorMessage); + } + + private interface UploadImageListener { + void uploaded(String imageUrl); + + void uploadFailed(@Nullable String errorMessage); + } + + private static class ParseJSONResponseFromAWSAsyncTask extends AsyncTask { + private String response; + private ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener; + private Map nameValuePairsMap; + private boolean successful; + ParseJSONResponseFromAWSAsyncTask(String response, ParseJSONResponseFromAWSListener parseJSONResponseFromAWSListener) { + this.response = response; + this.parseJSONResponseFromAWSListener = parseJSONResponseFromAWSListener; + nameValuePairsMap = new HashMap<>(); + successful = false; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject responseObject = new JSONObject(response); + JSONArray nameValuePairs = responseObject.getJSONObject(JSONUtils.ARGS_KEY).getJSONArray(JSONUtils.FIELDS_KEY); + + nameValuePairsMap = new HashMap<>(); + for (int i = 0; i < nameValuePairs.length(); i++) { + nameValuePairsMap.put(nameValuePairs.getJSONObject(i).getString(JSONUtils.NAME_KEY), + APIUtils.getRequestBody(nameValuePairs.getJSONObject(i).getString(JSONUtils.VALUE_KEY))); + } + + successful = true; + } catch (JSONException e) { + e.printStackTrace(); + successful = false; + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (successful) { + parseJSONResponseFromAWSListener.parseSuccessful(nameValuePairsMap); + } else { + parseJSONResponseFromAWSListener.parseFailed(); + } + } + + interface ParseJSONResponseFromAWSListener { + void parseSuccessful(Map nameValuePairsMap); + + void parseFailed(); + } + } + + private static class ParseXMLReponseFromAWSAsyncTask extends AsyncTask { + private String response; + private ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener; + private String imageUrl; + private boolean successful; + ParseXMLReponseFromAWSAsyncTask(String response, ParseXMLResponseFromAWSListener parseXMLResponseFromAWSListener) { + this.response = response; + this.parseXMLResponseFromAWSListener = parseXMLResponseFromAWSListener; + successful = false; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + XmlPullParser xmlPullParser = XmlPullParserFactory.newInstance().newPullParser(); + xmlPullParser.setInput(new StringReader(response)); + + boolean isLocationTag = false; + int eventType = xmlPullParser.getEventType(); + while (eventType != XmlPullParser.END_DOCUMENT) { + if (eventType == XmlPullParser.START_TAG) { + if (xmlPullParser.getName().equals("Location")) { + isLocationTag = true; + } + } else if (eventType == XmlPullParser.TEXT) { + if (isLocationTag) { + imageUrl = xmlPullParser.getText(); + successful = true; + return null; + } + } + eventType = xmlPullParser.next(); + } + } catch (XmlPullParserException | IOException e) { + e.printStackTrace(); + successful = false; + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (successful) { + parseXMLResponseFromAWSListener.parseSuccessful(imageUrl); + } else { + parseXMLResponseFromAWSListener.parseFailed(); + } + } + + interface ParseXMLResponseFromAWSListener { + void parseSuccessful(String url); + + void parseFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/DeleteRecentSearchQuery.java b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/DeleteRecentSearchQuery.java new file mode 100644 index 00000000..e40703c2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/DeleteRecentSearchQuery.java @@ -0,0 +1,44 @@ +package ml.docilealligator.infinityforreddit.recentsearchquery; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.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/ml/docilealligator/infinityforreddit/recentsearchquery/InsertRecentSearchQuery.java b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/InsertRecentSearchQuery.java new file mode 100644 index 00000000..e03a6e70 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/InsertRecentSearchQuery.java @@ -0,0 +1,53 @@ +package ml.docilealligator.infinityforreddit.recentsearchquery; + +import android.os.AsyncTask; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class InsertRecentSearchQuery { + public interface InsertRecentSearchQueryListener { + 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) { + List recentSearchQueries = recentSearchQueryDao.getAllRecentSearchQueries(username); + if (recentSearchQueries.size() >= 5) { + for (int i = 4; i < recentSearchQueries.size(); i++) { + recentSearchQueryDao.deleteRecentSearchQueries(recentSearchQueries.get(i)); + } + } + + recentSearchQueryDao.insert(new RecentSearchQuery(username, recentSearchQuery)); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + insertRecentSearchQueryListener.success(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQuery.java b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQuery.java new file mode 100644 index 00000000..7cbbe77a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQuery.java @@ -0,0 +1,43 @@ +package ml.docilealligator.infinityforreddit.recentsearchquery; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.ForeignKey; + +import ml.docilealligator.infinityforreddit.account.Account; + +@Entity(tableName = "recent_search_queries", primaryKeys = {"username", "search_query"}, + foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", + childColumns = "username", onDelete = ForeignKey.CASCADE)) +public class RecentSearchQuery { + @NonNull + @ColumnInfo(name = "username") + private String username; + @NonNull + @ColumnInfo(name = "search_query") + private String searchQuery; + + public RecentSearchQuery(@NonNull String username, @NonNull String searchQuery) { + this.username = username; + this.searchQuery = searchQuery; + } + + @NonNull + public String getUsername() { + return username; + } + + public void setUsername(@NonNull String username) { + this.username = username; + } + + @NonNull + public String getSearchQuery() { + return searchQuery; + } + + public void setSearchQuery(@NonNull String searchQuery) { + this.searchQuery = searchQuery; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryDao.java new file mode 100644 index 00000000..162b02f7 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryDao.java @@ -0,0 +1,25 @@ +package ml.docilealligator.infinityforreddit.recentsearchquery; + +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 RecentSearchQueryDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(RecentSearchQuery recentSearchQuery); + + @Query("SELECT * FROM recent_search_queries WHERE username = :username") + LiveData> getAllRecentSearchQueriesLiveData(String username); + + @Query("SELECT * FROM recent_search_queries WHERE username = :username") + List getAllRecentSearchQueries(String username); + + @Delete + void deleteRecentSearchQueries(RecentSearchQuery recentSearchQuery); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryRepository.java new file mode 100644 index 00000000..5c4e06d8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryRepository.java @@ -0,0 +1,19 @@ +package ml.docilealligator.infinityforreddit.recentsearchquery; + +import androidx.lifecycle.LiveData; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class RecentSearchQueryRepository { + private LiveData> mAllRecentSearchQueries; + + RecentSearchQueryRepository(RedditDataRoomDatabase redditDataRoomDatabase, String username) { + mAllRecentSearchQueries = redditDataRoomDatabase.recentSearchQueryDao().getAllRecentSearchQueriesLiveData(username); + } + + LiveData> getAllRecentSearchQueries() { + return mAllRecentSearchQueries; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryViewModel.java new file mode 100644 index 00000000..aba1b343 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/recentsearchquery/RecentSearchQueryViewModel.java @@ -0,0 +1,38 @@ +package ml.docilealligator.infinityforreddit.recentsearchquery; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class RecentSearchQueryViewModel extends ViewModel { + private LiveData> mAllRecentSearchQueries; + + public RecentSearchQueryViewModel(RedditDataRoomDatabase redditDataRoomDatabase, String username) { + mAllRecentSearchQueries = new RecentSearchQueryRepository(redditDataRoomDatabase, username).getAllRecentSearchQueries(); + } + + public LiveData> getAllRecentSearchQueries() { + return mAllRecentSearchQueries; + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private String mUsername; + + public Factory(RedditDataRoomDatabase redditDataRoomDatabase, String username) { + mRedditDataRoomDatabase = redditDataRoomDatabase; + mUsername = username; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new RecentSearchQueryViewModel(mRedditDataRoomDatabase, mUsername); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java new file mode 100644 index 00000000..2f2eef38 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadMediaService.java @@ -0,0 +1,470 @@ +package ml.docilealligator.infinityforreddit.services; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Intent; +import android.content.SharedPreferences; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Environment; +import android.os.IBinder; +import android.provider.MediaStore; + +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; +import androidx.documentfile.provider.DocumentFile; + +import org.greenrobot.eventbus.EventBus; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.apis.DownloadFile; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.DownloadProgressResponseBody; +import ml.docilealligator.infinityforreddit.events.DownloadMediaEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.NotificationUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import okhttp3.OkHttpClient; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +import static android.os.Environment.getExternalStoragePublicDirectory; + +public class DownloadMediaService extends Service { + public static final String EXTRA_URL = "EU"; + public static final String EXTRA_FILE_NAME = "EFN"; + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + public static final String EXTRA_MEDIA_TYPE = "EIG"; + public static final int EXTRA_MEDIA_TYPE_IMAGE = 0; + public static final int EXTRA_MEDIA_TYPE_GIF = 1; + public static final int EXTRA_MEDIA_TYPE_VIDEO = 2; + + private static final int NO_ERROR = -1; + private static final int ERROR_CANNOT_GET_DESTINATION_DIRECTORY = 0; + private static final int ERROR_FILE_CANNOT_DOWNLOAD = 1; + private static final int ERROR_FILE_CANNOT_SAVE = 2; + @Inject + @Named("download_media") + Retrofit retrofit; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private int mediaType; + private String mimeType; + private NotificationManagerCompat notificationManager; + private NotificationCompat.Builder builder; + private boolean downloadFinished; + + public DownloadMediaService() { + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + private String getNotificationChannelId() { + switch (mediaType) { + case EXTRA_MEDIA_TYPE_GIF: + return NotificationUtils.CHANNEL_ID_DOWNLOAD_GIF; + case EXTRA_MEDIA_TYPE_VIDEO: + return NotificationUtils.CHANNEL_ID_DOWNLOAD_VIDEO; + default: + return NotificationUtils.CHANNEL_ID_DOWNLOAD_IMAGE; + } + } + + private String getNotificationChannel() { + switch (mediaType) { + case EXTRA_MEDIA_TYPE_GIF: + return NotificationUtils.CHANNEL_DOWNLOAD_GIF; + case EXTRA_MEDIA_TYPE_VIDEO: + return NotificationUtils.CHANNEL_DOWNLOAD_VIDEO; + default: + return NotificationUtils.CHANNEL_DOWNLOAD_IMAGE; + } + } + + private int getNotificationId() { + switch (mediaType) { + case EXTRA_MEDIA_TYPE_GIF: + return NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID; + case EXTRA_MEDIA_TYPE_VIDEO: + return NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID; + default: + return NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID; + } + } + + private String getDownloadLocation() { + switch (mediaType) { + case EXTRA_MEDIA_TYPE_GIF: + return mSharedPreferences.getString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, ""); + case EXTRA_MEDIA_TYPE_VIDEO: + return mSharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, ""); + default: + return mSharedPreferences.getString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, ""); + } + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + notificationManager = NotificationManagerCompat.from(this); + builder = new NotificationCompat.Builder(this, getNotificationChannelId()); + + downloadFinished = false; + String fileUrl = intent.getStringExtra(EXTRA_URL); + final String[] fileName = {intent.getStringExtra(EXTRA_FILE_NAME)}; + String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); + mediaType = intent.getIntExtra(EXTRA_MEDIA_TYPE, EXTRA_MEDIA_TYPE_IMAGE); + mimeType = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? "video/*" : "image/*"; + + final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() { + long time = 0; + + @Override public void update(long bytesRead, long contentLength, boolean done) { + if (!done) { + if (contentLength != -1) { + long currentTime = System.currentTimeMillis(); + if (currentTime - time > 1000) { + time = currentTime; + updateNotification(0, (int) ((100 * bytesRead) / contentLength), null); + } + } + } + } + }; + + OkHttpClient client = new OkHttpClient.Builder() + .addNetworkInterceptor(chain -> { + okhttp3.Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new DownloadProgressResponseBody(originalResponse.body(), progressListener)) + .build(); + }) + .build(); + + retrofit = retrofit.newBuilder().client(client).build(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel serviceChannel; + serviceChannel = new NotificationChannel( + getNotificationChannelId(), + getNotificationChannel(), + NotificationManager.IMPORTANCE_LOW + ); + + NotificationManagerCompat manager = NotificationManagerCompat.from(this); + manager.createNotificationChannel(serviceChannel); + } + + switch (mediaType) { + case EXTRA_MEDIA_TYPE_GIF: + startForeground( + NotificationUtils.DOWNLOAD_GIF_NOTIFICATION_ID, + createNotification(fileName[0]) + ); + break; + case EXTRA_MEDIA_TYPE_VIDEO: + startForeground( + NotificationUtils.DOWNLOAD_VIDEO_NOTIFICATION_ID, + createNotification(fileName[0]) + ); + break; + default: + startForeground( + NotificationUtils.DOWNLOAD_IMAGE_NOTIFICATION_ID, + createNotification(fileName[0]) + ); + } + + boolean separateDownloadFolder = mSharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false); + + retrofit.create(DownloadFile.class).downloadFile(fileUrl).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful() && response.body() != null) { + String destinationFileDirectory = getDownloadLocation(); + String destinationFileUriString; + boolean isDefaultDestination; + if (destinationFileDirectory.equals("")) { + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + File directory = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); + if (directory != null) { + String directoryPath = separateDownloadFolder && subredditName != null && !subredditName.equals("") ? directory.getAbsolutePath() + "/Infinity/" + subredditName + "/" : directory.getAbsolutePath() + "/Infinity/"; + File infinityDir = new File(directoryPath); + if (!infinityDir.exists() && !infinityDir.mkdirs()) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + destinationFileUriString = directoryPath + fileName[0]; + } else { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + } else { + String dir = mediaType == EXTRA_MEDIA_TYPE_VIDEO ? Environment.DIRECTORY_MOVIES : Environment.DIRECTORY_PICTURES; + destinationFileUriString = separateDownloadFolder && subredditName != null && !subredditName.equals("") ? dir + "/Infinity/" + subredditName + "/" : dir + "/Infinity/"; + } + isDefaultDestination = true; + } else { + isDefaultDestination = false; + DocumentFile picFile; + DocumentFile dir; + if (separateDownloadFolder && subredditName != null && !subredditName.equals("")) { + dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory)); + if (dir == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + dir = dir.findFile(subredditName); + if (dir == null) { + dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory)).createDirectory(subredditName); + if (dir == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + } + } else { + dir = DocumentFile.fromTreeUri(DownloadMediaService.this, Uri.parse(destinationFileDirectory)); + if (dir == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + } + DocumentFile checkForDuplicates = dir.findFile(fileName[0]); + int extensionPosition = fileName[0].lastIndexOf('.'); + String extension = fileName[0].substring(extensionPosition); + int num = 1; + while (checkForDuplicates != null) { + fileName[0] = fileName[0].substring(0, extensionPosition) + " (" + num + ")" + extension; + checkForDuplicates = dir.findFile(fileName[0]); + num++; + } + picFile = dir.createFile(mimeType, fileName[0]); + if (picFile == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + destinationFileUriString = picFile.getUri().toString(); + } + + new SaveImageOrGifAndCopyToExternalStorageAsyncTask(response.body(), mediaType, + isDefaultDestination, fileName[0], destinationFileUriString, getContentResolver(), + (destinationFileUri, errorCode) -> downloadFinished(destinationFileUri, errorCode)).execute(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + downloadFinished(null, ERROR_FILE_CANNOT_DOWNLOAD); + } + }); + + return START_NOT_STICKY; + } + + private Notification createNotification(String fileName) { + builder.setContentTitle(fileName).setContentText(getString(R.string.downloading)) + .setProgress(100, 0, false); + return builder.setSmallIcon(R.drawable.ic_notification) + .setColor(mCustomThemeWrapper.getColorPrimaryLightTheme()) + .build(); + } + + private void updateNotification(int contentStringResId, int progress, PendingIntent pendingIntent) { + if (notificationManager != null) { + if (progress < 0) { + builder.setProgress(0, 0, false); + } else { + builder.setProgress(100, progress, false); + } + if (contentStringResId != 0) { + builder.setContentText(getString(contentStringResId)); + } + if (pendingIntent != null) { + builder.setContentIntent(pendingIntent); + } + notificationManager.notify(getNotificationId(), builder.build()); + } + } + + private void downloadFinished(Uri destinationFileUri, int errorCode) { + if (downloadFinished) { + return; + } + + downloadFinished = true; + if (errorCode != NO_ERROR) { + switch (errorCode) { + case ERROR_CANNOT_GET_DESTINATION_DIRECTORY: + updateNotification(R.string.downloading_image_or_gif_failed_cannot_get_destination_directory, -1, null); + break; + case ERROR_FILE_CANNOT_DOWNLOAD: + updateNotification(R.string.downloading_media_failed_cannot_download_media, -1, null); + break; + case ERROR_FILE_CANNOT_SAVE: + updateNotification(R.string.downloading_media_failed_cannot_save_to_destination_directory, -1, null); + break; + } + EventBus.getDefault().post(new DownloadMediaEvent(false)); + } else { + MediaScannerConnection.scanFile( + this, new String[]{destinationFileUri.toString()}, null, + (path, uri) -> { + Intent intent = new Intent(); + intent.setAction(android.content.Intent.ACTION_VIEW); + intent.setDataAndType(destinationFileUri, mimeType); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + updateNotification(R.string.downloading_media_finished, -1, pendingIntent); + EventBus.getDefault().post(new DownloadMediaEvent(true)); + } + ); + } + stopForeground(false); + } + + private static class SaveImageOrGifAndCopyToExternalStorageAsyncTask extends AsyncTask { + + private ResponseBody response; + private int mediaType; + private boolean isDefaultDestination; + private String destinationFileName; + @NonNull + private String destinationFileUriString; + private ContentResolver contentResolver; + private SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener saveImageOrGifAndCopyToExternalStorageAsyncTaskListener; + private int errorCode = NO_ERROR; + + interface SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener { + void finished(Uri destinationFileUri, int errorCode); + } + + public SaveImageOrGifAndCopyToExternalStorageAsyncTask(ResponseBody response, int mediaType, + boolean isDefaultDestination, + String destinationFileName, + @NonNull String destinationFileUriString, + ContentResolver contentResolver, + SaveImageOrGifAndCopyToExternalStorageAsyncTaskListener saveImageOrGifAndCopyToExternalStorageAsyncTaskListener) { + this.response = response; + this.mediaType = mediaType; + this.isDefaultDestination = isDefaultDestination; + this.destinationFileName = destinationFileName; + this.destinationFileUriString = destinationFileUriString; + this.contentResolver = contentResolver; + this.saveImageOrGifAndCopyToExternalStorageAsyncTaskListener = saveImageOrGifAndCopyToExternalStorageAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + writeResponseBodyToDisk(response); + } catch (IOException e) { + errorCode = ERROR_FILE_CANNOT_SAVE; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + saveImageOrGifAndCopyToExternalStorageAsyncTaskListener.finished(Uri.parse(destinationFileUriString), errorCode); + } + + private void writeResponseBodyToDisk(ResponseBody body) throws IOException { + if (isDefaultDestination) { + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + InputStream inputStream = body.byteStream(); + OutputStream outputStream = new FileOutputStream(destinationFileUriString); + byte[] fileReader = new byte[4096]; + + long fileSize = body.contentLength(); + long fileSizeDownloaded = 0; + + while (true) { + int read = inputStream.read(fileReader); + + if (read == -1) { + break; + } + + outputStream.write(fileReader, 0, read); + + fileSizeDownloaded += read; + } + + outputStream.flush(); + } else { + ContentValues contentValues = new ContentValues(); + contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, destinationFileName); + contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mediaType == EXTRA_MEDIA_TYPE_VIDEO ? "video/*" : "image/*"); + contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFileUriString); + contentValues.put(MediaStore.Images.Media.IS_PENDING, 1); + + final Uri contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + Uri uri = contentResolver.insert(contentUri, contentValues); + + if (uri == null) { + throw new IOException("Failed to create new MediaStore record."); + } + + OutputStream stream = contentResolver.openOutputStream(uri); + + if (stream == null) { + throw new IOException("Failed to get output stream."); + } + + InputStream in = body.byteStream(); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + stream.write(buf, 0, len); + } + contentValues.clear(); + contentValues.put(MediaStore.Images.Media.IS_PENDING, 0); + contentResolver.update(uri, contentValues, null, null); + destinationFileUriString = uri.toString(); + } + } else { + try (OutputStream stream = contentResolver.openOutputStream(Uri.parse(destinationFileUriString))) { + if (stream == null) { + throw new IOException("Failed to get output stream."); + } + + InputStream in = body.byteStream(); + + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + stream.write(buf, 0, len); + } + } + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java new file mode 100644 index 00000000..c68be79b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/DownloadRedditVideoService.java @@ -0,0 +1,662 @@ +package ml.docilealligator.infinityforreddit.services; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Intent; +import android.content.SharedPreferences; +import android.media.MediaCodec; +import android.media.MediaExtractor; +import android.media.MediaFormat; +import android.media.MediaMuxer; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.Environment; +import android.os.IBinder; +import android.provider.MediaStore; + +import androidx.annotation.NonNull; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; +import androidx.documentfile.provider.DocumentFile; + +import org.greenrobot.eventbus.EventBus; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.ByteBuffer; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.apis.DownloadFile; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.DownloadProgressResponseBody; +import ml.docilealligator.infinityforreddit.events.DownloadRedditVideoEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.NotificationUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import okhttp3.OkHttpClient; +import okhttp3.ResponseBody; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +import static android.os.Environment.getExternalStoragePublicDirectory; + +public class DownloadRedditVideoService extends Service { + + public static final String EXTRA_VIDEO_URL = "EVU"; + public static final String EXTRA_SUBREDDIT = "ES"; + public static final String EXTRA_POST_ID = "EPI"; + + private static final int NO_ERROR = -1; + private static final int ERROR_CANNOT_GET_CACHE_DIRECTORY = 0; + private static final int ERROR_VIDEO_FILE_CANNOT_DOWNLOAD = 1; + private static final int ERROR_VIDEO_FILE_CANNOT_SAVE = 2; + private static final int ERROR_AUDIO_FILE_CANNOT_SAVE = 3; + private static final int ERROR_MUX_FAILED = 4; + private static final int ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE = 5; + private static final int ERROR_CANNOT_GET_DESTINATION_DIRECTORY = 6; + + @Inject + @Named("download_media") + Retrofit retrofit; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + @Inject + CustomThemeWrapper customThemeWrapper; + String resultFile; + private NotificationManagerCompat notificationManager; + private NotificationCompat.Builder builder; + + public DownloadRedditVideoService() { + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + notificationManager = NotificationManagerCompat.from(this); + builder = new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO); + + final DownloadProgressResponseBody.ProgressListener progressListener = new DownloadProgressResponseBody.ProgressListener() { + long time = 0; + + @Override public void update(long bytesRead, long contentLength, boolean done) { + if (!done) { + if (contentLength != -1) { + long currentTime = System.currentTimeMillis(); + if (currentTime - time > 1000) { + time = currentTime; + updateNotification(0, (int) ((100 * bytesRead) / contentLength), null); + } + } + } + } + }; + + OkHttpClient client = new OkHttpClient.Builder() + .addNetworkInterceptor(chain -> { + okhttp3.Response originalResponse = chain.proceed(chain.request()); + return originalResponse.newBuilder() + .body(new DownloadProgressResponseBody(originalResponse.body(), progressListener)) + .build(); + }) + .build(); + + retrofit = retrofit.newBuilder().client(client).build(); + + String videoUrl = intent.getStringExtra(EXTRA_VIDEO_URL); + String audioUrl = videoUrl.substring(0, videoUrl.lastIndexOf('/')) + "/DASH_audio.mp4"; + String subredditName = intent.getStringExtra(EXTRA_SUBREDDIT); + final String[] fileNameWithoutExtension = {subredditName + "-" + intent.getStringExtra(EXTRA_POST_ID)}; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel serviceChannel; + serviceChannel = new NotificationChannel( + NotificationUtils.CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO, + NotificationUtils.CHANNEL_DOWNLOAD_REDDIT_VIDEO, + NotificationManager.IMPORTANCE_LOW + ); + + NotificationManagerCompat manager = NotificationManagerCompat.from(this); + manager.createNotificationChannel(serviceChannel); + } + + startForeground( + NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID, + createNotification(fileNameWithoutExtension[0] + ".mp4") + ); + + DownloadFile downloadFile = retrofit.create(DownloadFile.class); + + boolean separateDownloadFolder = sharedPreferences.getBoolean(SharedPreferencesUtils.SEPARATE_FOLDER_FOR_EACH_SUBREDDIT, false); + + File directory = getExternalCacheDir(); + String destinationFileName = fileNameWithoutExtension[0] + ".mp4"; + if (directory != null) { + String directoryPath = directory.getAbsolutePath() + "/"; + downloadFile.downloadFile(videoUrl).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response videoResponse) { + if (videoResponse.isSuccessful() && videoResponse.body() != null) { + String destinationFileDirectory = sharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, ""); + String destinationFileUriString; + boolean isDefaultDestination; + if (destinationFileDirectory.equals("")) { + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + File directory = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); + if (directory != null) { + String directoryPath = separateDownloadFolder ? directory.getAbsolutePath() + "/Infinity/" + subredditName + "/" : directory.getAbsolutePath() + "/Infinity/"; + File infinityDir = new File(directoryPath); + if (!infinityDir.exists() && !infinityDir.mkdir()) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + destinationFileUriString = directoryPath + destinationFileName; + } else { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + } else { + destinationFileUriString = separateDownloadFolder ? Environment.DIRECTORY_MOVIES + "/Infinity/" + subredditName + "/" : Environment.DIRECTORY_MOVIES + "/Infinity/"; + } + isDefaultDestination = true; + } else { + isDefaultDestination = false; + DocumentFile picFile; + DocumentFile dir; + if (separateDownloadFolder) { + dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory)); + if (dir == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + dir = dir.findFile(subredditName); + if (dir == null) { + dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory)).createDirectory(subredditName); + if (dir == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + } + } else { + dir = DocumentFile.fromTreeUri(DownloadRedditVideoService.this, Uri.parse(destinationFileDirectory)); + if (dir == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + } + DocumentFile checkForDuplicates = dir.findFile(destinationFileName); + int num = 1; + while (checkForDuplicates != null) { + fileNameWithoutExtension[0] = fileNameWithoutExtension[0] + " (" + num + ")"; + checkForDuplicates = dir.findFile(fileNameWithoutExtension[0] + ".mp4"); + num++; + } + picFile = dir.createFile("video/*", fileNameWithoutExtension[0] + ".mp4"); + if (picFile == null) { + downloadFinished(null, ERROR_CANNOT_GET_DESTINATION_DIRECTORY); + return; + } + destinationFileUriString = picFile.getUri().toString(); + } + + updateNotification(R.string.downloading_reddit_video_audio_track, 0, null); + downloadFile.downloadFile(audioUrl).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response audioResponse) { + if (audioResponse.isSuccessful() && audioResponse.body() != null) { + String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4"; + String audioFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp3"; + String outputFilePath = directoryPath + fileNameWithoutExtension[0] + ".mp4"; + new SaveTempMuxAndCopyAsyncTask(videoResponse.body(), + audioResponse.body(), videoFilePath, audioFilePath, outputFilePath, + destinationFileName, destinationFileUriString, isDefaultDestination, + getContentResolver(), + new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() { + @Override + public void finished(Uri destinationFileUri, int errorCode) { + new File(videoFilePath).delete(); + new File(audioFilePath).delete(); + new File(outputFilePath).delete(); + downloadFinished(destinationFileUri, errorCode); + } + + @Override + public void updateProgressNotification(int stringResId) { + updateNotification(stringResId, -1, null); + } + }).execute(); + } else { + String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4"; + new SaveTempMuxAndCopyAsyncTask(videoResponse.body(), + null, videoFilePath, null, null, + destinationFileName, destinationFileUriString, isDefaultDestination, + getContentResolver(), + new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() { + @Override + public void finished(Uri destinationFileUri, int errorCode) { + new File(videoFilePath).delete(); + downloadFinished(destinationFileUri, errorCode); + } + + @Override + public void updateProgressNotification(int stringResId) { + updateNotification(stringResId, -1, null); + } + }).execute(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + String videoFilePath = directoryPath + fileNameWithoutExtension[0] + "-cache.mp4"; + new SaveTempMuxAndCopyAsyncTask(videoResponse.body(), + null, videoFilePath, null, null, + destinationFileName, destinationFileUriString, isDefaultDestination, + getContentResolver(), + new SaveTempMuxAndCopyAsyncTask.SaveTempMuxAndCopyAsyncTaskListener() { + @Override + public void finished(Uri destinationFileUri, int errorCode) { + new File(videoFilePath).delete(); + downloadFinished(destinationFileUri, errorCode); + } + + @Override + public void updateProgressNotification(int stringResId) { + updateNotification(stringResId, -1, null); + } + }).execute(); + } + }); + } else { + downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + downloadFinished(null, ERROR_VIDEO_FILE_CANNOT_DOWNLOAD); + } + }); + } else { + downloadFinished(null, ERROR_CANNOT_GET_CACHE_DIRECTORY); + } + + return START_NOT_STICKY; + } + + private void downloadFinished(Uri destinationFileUri, int errorCode) { + if (errorCode != NO_ERROR) { + switch (errorCode) { + case ERROR_CANNOT_GET_CACHE_DIRECTORY: + updateNotification(R.string.downloading_reddit_video_failed_cannot_get_cache_directory, -1, null); + break; + case ERROR_VIDEO_FILE_CANNOT_DOWNLOAD: + updateNotification(R.string.downloading_reddit_video_failed_cannot_download_video, -1, null); + break; + case ERROR_VIDEO_FILE_CANNOT_SAVE: + updateNotification(R.string.downloading_reddit_video_failed_cannot_save_video, -1, null); + break; + case ERROR_AUDIO_FILE_CANNOT_SAVE: + updateNotification(R.string.downloading_reddit_video_failed_cannot_save_audio, -1, null); + break; + case ERROR_MUX_FAILED: + updateNotification(R.string.downloading_reddit_video_failed_cannot_mux, -1, null); + break; + case ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE: + updateNotification(R.string.downloading_reddit_video_failed_cannot_save_mux_video, -1, null); + break; + case ERROR_CANNOT_GET_DESTINATION_DIRECTORY: + updateNotification(R.string.downloading_media_failed_cannot_save_to_destination_directory, -1, null); + break; + } + EventBus.getDefault().post(new DownloadRedditVideoEvent(false)); + } else { + MediaScannerConnection.scanFile( + this, new String[]{destinationFileUri.toString()}, null, + (path, uri) -> { + Intent intent = new Intent(); + intent.setAction(android.content.Intent.ACTION_VIEW); + intent.setDataAndType(destinationFileUri, "video/*"); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT); + updateNotification(R.string.downloading_reddit_video_finished, -1, pendingIntent); + EventBus.getDefault().post(new DownloadRedditVideoEvent(true)); + } + ); + } + stopForeground(false); + } + + private Notification createNotification(String fileName) { + builder.setContentTitle(fileName).setContentText(getString(R.string.downloading_reddit_video)).setProgress(100, 0, false); + return builder.setSmallIcon(R.drawable.ic_notification) + .setColor(customThemeWrapper.getColorPrimaryLightTheme()) + .build(); + } + + private void updateNotification(int contentStringResId, int progress, PendingIntent pendingIntent) { + if (notificationManager != null) { + if (progress < 0) { + builder.setProgress(0, 0, false); + } else { + builder.setProgress(100, progress, false); + } + if (contentStringResId != 0) { + builder.setContentText(getString(contentStringResId)); + } + if (pendingIntent != null) { + builder.setContentIntent(pendingIntent); + } + notificationManager.notify(NotificationUtils.DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID, builder.build()); + } + } + + private static class SaveTempMuxAndCopyAsyncTask extends AsyncTask { + + private ResponseBody videoResponse; + private ResponseBody audioResponse; + private String videoFilePath; + private String audioFilePath; + private String outputFilePath; + private String destinationFileName; + @NonNull + private String destinationFileUriString; + private boolean isDefaultDestination; + private ContentResolver contentResolver; + private SaveTempMuxAndCopyAsyncTaskListener saveTempMuxAndCopyAsyncTaskListener; + private int errorCode = NO_ERROR; + + public SaveTempMuxAndCopyAsyncTask(ResponseBody videoResponse, ResponseBody audioResponse, + String videoFilePath, String audioFilePath, String outputFilePath, + String destinationFileName, @NonNull String destinationFileUriString, + boolean isDefaultDestination, ContentResolver contentResolver, + SaveTempMuxAndCopyAsyncTaskListener saveTempMuxAndCopyAsyncTaskListener) { + this.videoResponse = videoResponse; + this.audioResponse = audioResponse; + this.videoFilePath = videoFilePath; + this.audioFilePath = audioFilePath; + this.outputFilePath = outputFilePath; + this.destinationFileName = destinationFileName; + this.destinationFileUriString = destinationFileUriString; + this.isDefaultDestination = isDefaultDestination; + this.contentResolver = contentResolver; + this.saveTempMuxAndCopyAsyncTaskListener = saveTempMuxAndCopyAsyncTaskListener; + } + + @Override + protected void onProgressUpdate(Integer... values) { + super.onProgressUpdate(values); + saveTempMuxAndCopyAsyncTaskListener.updateProgressNotification(values[0]); + } + + @Override + protected Void doInBackground(Void... voids) { + String savedVideoFilePath = writeResponseBodyToDisk(videoResponse, videoFilePath); + if (savedVideoFilePath == null) { + errorCode = ERROR_VIDEO_FILE_CANNOT_SAVE; + return null; + } + if (audioResponse != null) { + String savedAudioFilePath = writeResponseBodyToDisk(audioResponse, audioFilePath); + if (savedAudioFilePath == null) { + errorCode = ERROR_AUDIO_FILE_CANNOT_SAVE; + return null; + } + + publishProgress(R.string.downloading_reddit_video_muxing); + if (!muxVideoAndAudio(videoFilePath, audioFilePath, outputFilePath)) { + errorCode = ERROR_MUX_FAILED; + return null; + } + + publishProgress(R.string.downloading_reddit_video_save_file_to_public_dir); + try { + copyToDestination(outputFilePath); + } catch (IOException e) { + e.printStackTrace(); + errorCode = ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE; + } + } else { + publishProgress(R.string.downloading_reddit_video_save_file_to_public_dir); + try { + copyToDestination(videoFilePath); + } catch (IOException e) { + e.printStackTrace(); + errorCode = ERROR_MUXED_VIDEO_FILE_CANNOT_SAVE; + } + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + saveTempMuxAndCopyAsyncTaskListener.finished(Uri.parse(destinationFileUriString), errorCode); + } + + private String writeResponseBodyToDisk(ResponseBody body, String filePath) { + try { + File file = new File(filePath); + + InputStream inputStream = null; + OutputStream outputStream = null; + + try { + byte[] fileReader = new byte[4096]; + + long fileSize = body.contentLength(); + long fileSizeDownloaded = 0; + + inputStream = body.byteStream(); + outputStream = new FileOutputStream(file); + + while (true) { + int read = inputStream.read(fileReader); + + if (read == -1) { + break; + } + + outputStream.write(fileReader, 0, read); + + fileSizeDownloaded += read; + } + + outputStream.flush(); + + return file.getPath(); + } catch (IOException e) { + return null; + } finally { + if (inputStream != null) { + inputStream.close(); + } + + if (outputStream != null) { + outputStream.close(); + } + } + } catch (IOException e) { + return null; + } + } + + private boolean muxVideoAndAudio(String videoFilePath, String audioFilePath, String outputFilePath) { + try { + File file = new File(outputFilePath); + file.createNewFile(); + MediaExtractor videoExtractor = new MediaExtractor(); + videoExtractor.setDataSource(videoFilePath); + MediaExtractor audioExtractor = new MediaExtractor(); + audioExtractor.setDataSource(audioFilePath); + MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); + + videoExtractor.selectTrack(0); + MediaFormat videoFormat = videoExtractor.getTrackFormat(0); + int videoTrack = muxer.addTrack(videoFormat); + + audioExtractor.selectTrack(0); + MediaFormat audioFormat = audioExtractor.getTrackFormat(0); + int audioTrack = muxer.addTrack(audioFormat); + boolean sawEOS = false; + int offset = 100; + int sampleSize = 4096 * 1024; + ByteBuffer videoBuf = ByteBuffer.allocate(sampleSize); + ByteBuffer audioBuf = ByteBuffer.allocate(sampleSize); + MediaCodec.BufferInfo videoBufferInfo = new MediaCodec.BufferInfo(); + MediaCodec.BufferInfo audioBufferInfo = new MediaCodec.BufferInfo(); + + videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); + audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); + + muxer.start(); + + int muxedSize = 0; + while (!sawEOS) { + videoBufferInfo.offset = offset; + videoBufferInfo.size = videoExtractor.readSampleData(videoBuf, offset); + + if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { + sawEOS = true; + videoBufferInfo.size = 0; + } else { + videoBufferInfo.presentationTimeUs = videoExtractor.getSampleTime(); + videoBufferInfo.flags = videoExtractor.getSampleFlags(); + muxer.writeSampleData(videoTrack, videoBuf, videoBufferInfo); + muxedSize += videoTrack; + videoExtractor.advance(); + } + } + + boolean sawEOS2 = false; + while (!sawEOS2) { + audioBufferInfo.offset = offset; + audioBufferInfo.size = audioExtractor.readSampleData(audioBuf, offset); + + if (videoBufferInfo.size < 0 || audioBufferInfo.size < 0) { + sawEOS2 = true; + audioBufferInfo.size = 0; + } else { + audioBufferInfo.presentationTimeUs = audioExtractor.getSampleTime(); + audioBufferInfo.flags = audioExtractor.getSampleFlags(); + muxer.writeSampleData(audioTrack, audioBuf, audioBufferInfo); + audioExtractor.advance(); + } + } + + muxer.stop(); + muxer.release(); + } catch (IllegalArgumentException ignore) { + } catch (IOException e) { + e.printStackTrace(); + return false; + } + + return true; + } + + private void copyToDestination(String srcPath) throws IOException { + if (isDefaultDestination) { + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + InputStream in = new FileInputStream(srcPath); + OutputStream out = new FileOutputStream(destinationFileUriString); + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + out.write(buf, 0, len); + } + + new File(srcPath).delete(); + } else { + ContentValues contentValues = new ContentValues(); + contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, destinationFileName); + contentValues.put(MediaStore.MediaColumns.MIME_TYPE, "video/*"); + contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFileUriString); + contentValues.put(MediaStore.Video.Media.IS_PENDING, 1); + + OutputStream stream = null; + Uri uri = null; + + try { + final Uri contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + uri = contentResolver.insert(contentUri, contentValues); + + if (uri == null) { + throw new IOException("Failed to create new MediaStore record."); + } + + stream = contentResolver.openOutputStream(uri); + + if (stream == null) { + throw new IOException("Failed to get output stream."); + } + + InputStream in = new FileInputStream(srcPath); + + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + stream.write(buf, 0, len); + } + + contentValues.clear(); + contentValues.put(MediaStore.Video.Media.IS_PENDING, 0); + contentResolver.update(uri, contentValues, null, null); + destinationFileUriString = uri.toString(); + } catch (IOException e) { + if (uri != null) { + // Don't leave an orphan entry in the MediaStore + contentResolver.delete(uri, null, null); + } + + throw e; + } finally { + if (stream != null) { + stream.close(); + } + } + } + } else { + OutputStream stream = contentResolver.openOutputStream(Uri.parse(destinationFileUriString)); + if (stream == null) { + throw new IOException("Failed to get output stream."); + } + + InputStream in = new FileInputStream(srcPath); + + byte[] buf = new byte[1024]; + int len; + while ((len = in.read(buf)) > 0) { + stream.write(buf, 0, len); + } + } + } + + interface SaveTempMuxAndCopyAsyncTaskListener { + void finished(Uri destinationFileUri, int errorCode); + void updateProgressNotification(int stringResId); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java new file mode 100644 index 00000000..b979a07e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java @@ -0,0 +1,354 @@ +package ml.docilealligator.infinityforreddit.services; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.Service; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.AsyncTask; +import android.os.Build; +import android.os.IBinder; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.target.CustomTarget; +import com.bumptech.glide.request.transition.Transition; + +import org.greenrobot.eventbus.EventBus; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitCrosspostEvent; +import ml.docilealligator.infinityforreddit.events.SubmitImagePostEvent; +import ml.docilealligator.infinityforreddit.events.SubmitTextOrLinkPostEvent; +import ml.docilealligator.infinityforreddit.events.SubmitVideoOrGifPostEvent; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.utils.NotificationUtils; +import ml.docilealligator.infinityforreddit.post.Post; +import ml.docilealligator.infinityforreddit.post.SubmitPost; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Retrofit; + +public class SubmitPostService extends Service { + public static final String EXTRA_ACCESS_TOKEN = "EAT"; + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + public static final String EXTRA_TITLE = "ET"; + public static final String EXTRA_CONTENT = "EC"; + public static final String EXTRA_KIND = "EK"; + public static final String EXTRA_FLAIR = "EF"; + public static final String EXTRA_IS_SPOILER = "EIS"; + public static final String EXTRA_IS_NSFW = "EIN"; + public static final String EXTRA_POST_TYPE = "EPT"; + public static final int EXTRA_POST_TEXT_OR_LINK = 0; + public static final int EXTRA_POST_TYPE_IMAGE = 1; + public static final int EXTRA_POST_TYPE_VIDEO = 2; + public static final int EXTRA_POST_TYPE_CROSSPOST = 3; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + @Named("upload_media") + Retrofit mUploadMediaRetrofit; + @Inject + @Named("upload_video") + Retrofit mUploadVideoRetrofit; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private String mAccessToken; + private String subredditName; + private String title; + private Flair flair; + private boolean isSpoiler; + private boolean isNSFW; + private String content; + private String kind; + private Uri mediaUri; + + public SubmitPostService() { + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + mAccessToken = intent.getStringExtra(EXTRA_ACCESS_TOKEN); + subredditName = intent.getStringExtra(EXTRA_SUBREDDIT_NAME); + title = intent.getStringExtra(EXTRA_TITLE); + flair = intent.getParcelableExtra(EXTRA_FLAIR); + isSpoiler = intent.getBooleanExtra(EXTRA_IS_SPOILER, false); + isNSFW = intent.getBooleanExtra(EXTRA_IS_NSFW, false); + int postType = intent.getIntExtra(EXTRA_POST_TYPE, EXTRA_POST_TEXT_OR_LINK); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + NotificationChannel serviceChannel = new NotificationChannel( + NotificationUtils.CHANNEL_SUBMIT_POST, + NotificationUtils.CHANNEL_SUBMIT_POST, + NotificationManager.IMPORTANCE_LOW + ); + + NotificationManagerCompat manager = NotificationManagerCompat.from(this); + manager.createNotificationChannel(serviceChannel); + } + + if (postType == EXTRA_POST_TEXT_OR_LINK) { + content = intent.getStringExtra(EXTRA_CONTENT); + kind = intent.getStringExtra(EXTRA_KIND); + startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting)); + submitTextOrLinkPost(); + } else if (postType == EXTRA_POST_TYPE_CROSSPOST) { + content = intent.getStringExtra(EXTRA_CONTENT); + startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting)); + submitCrosspost(); + } else if (postType == EXTRA_POST_TYPE_IMAGE) { + mediaUri = intent.getData(); + startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting_image)); + submitImagePost(); + } else { + mediaUri = intent.getData(); + startForeground(NotificationUtils.SUBMIT_POST_SERVICE_NOTIFICATION_ID, createNotification(R.string.posting_video)); + submitVideoPost(); + } + + return START_NOT_STICKY; + } + + private Notification createNotification(int stringResId) { + return new NotificationCompat.Builder(this, NotificationUtils.CHANNEL_SUBMIT_POST) + .setContentTitle(getString(stringResId)) + .setContentText(getString(R.string.please_wait)) + .setSmallIcon(R.drawable.ic_notification) + .setColor(mCustomThemeWrapper.getColorPrimaryLightTheme()) + .build(); + } + + private void submitTextOrLinkPost() { + SubmitPost.submitTextOrLinkPost(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale, + subredditName, title, content, flair, isSpoiler, isNSFW, kind, new SubmitPost.SubmitPostListener() { + @Override + public void submitSuccessful(Post post) { + EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(true, post, null)); + + stopService(); + } + + @Override + public void submitFailed(@Nullable String errorMessage) { + EventBus.getDefault().post(new SubmitTextOrLinkPostEvent(false, null, errorMessage)); + + stopService(); + } + }); + } + + private void submitCrosspost() { + SubmitPost.submitCrosspost(mOauthRetrofit, mAccessToken, getResources().getConfiguration().locale, + subredditName, title, content, flair, isSpoiler, isNSFW, APIUtils.KIND_CROSSPOST, new SubmitPost.SubmitPostListener() { + @Override + public void submitSuccessful(Post post) { + EventBus.getDefault().post(new SubmitCrosspostEvent(true, post, null)); + + stopService(); + } + + @Override + public void submitFailed(@Nullable String errorMessage) { + EventBus.getDefault().post(new SubmitCrosspostEvent(false, null, errorMessage)); + + stopService(); + } + }); + } + + private void submitImagePost() { + Glide.with(this) + .asBitmap() + .load(mediaUri) + .into(new CustomTarget() { + + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + SubmitPost.submitImagePost(mOauthRetrofit, mUploadMediaRetrofit, mAccessToken, + getResources().getConfiguration().locale, subredditName, title, resource, + flair, isSpoiler, isNSFW, new SubmitPost.SubmitPostListener() { + @Override + public void submitSuccessful(Post post) { + EventBus.getDefault().post(new SubmitImagePostEvent(true, null)); + Toast.makeText(SubmitPostService.this, R.string.image_is_processing, Toast.LENGTH_SHORT).show(); + + stopService(); + } + + @Override + public void submitFailed(@Nullable String errorMessage) { + EventBus.getDefault().post(new SubmitImagePostEvent(false, errorMessage)); + + stopService(); + } + }); + } + + @Override + public void onLoadFailed(@Nullable Drawable errorDrawable) { + EventBus.getDefault().post(new SubmitImagePostEvent(false, getString(R.string.error_processing_image))); + + stopService(); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + } + + private void submitVideoPost() { + try { + InputStream in = getContentResolver().openInputStream(mediaUri); + String type = getContentResolver().getType(mediaUri); + String cacheFilePath; + if (type != null && type.contains("gif")) { + cacheFilePath = getExternalCacheDir() + "/" + mediaUri.getLastPathSegment() + ".gif"; + } else { + cacheFilePath = getExternalCacheDir() + "/" + mediaUri.getLastPathSegment() + ".mp4"; + } + + new CopyFileToCacheAsyncTask(in, cacheFilePath, + new CopyFileToCacheAsyncTask.CopyFileToCacheAsyncTaskListener() { + @Override + public void success() { + Glide.with(SubmitPostService.this) + .asBitmap() + .load(mediaUri) + .into(new CustomTarget() { + @Override + public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition transition) { + if (type != null) { + SubmitPost.submitVideoPost(mOauthRetrofit, mUploadMediaRetrofit, mUploadVideoRetrofit, + mAccessToken, getResources().getConfiguration().locale, subredditName, title, + new File(cacheFilePath), type, resource, flair, isSpoiler, isNSFW, + new SubmitPost.SubmitPostListener() { + @Override + public void submitSuccessful(Post post) { + EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(true, false, null)); + if (type.contains("gif")) { + Toast.makeText(SubmitPostService.this, R.string.gif_is_processing, Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(SubmitPostService.this, R.string.video_is_processing, Toast.LENGTH_SHORT).show(); + } + + stopService(); + } + + @Override + public void submitFailed(@Nullable String errorMessage) { + EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, false, errorMessage)); + + stopService(); + } + }); + } else { + EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); + } + } + + @Override + public void onLoadFailed(@Nullable Drawable errorDrawable) { + EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); + + stopService(); + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholder) { + + } + }); + } + + @Override + public void failed() { + EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); + + stopService(); + } + }).execute(); + } catch (IOException e) { + e.printStackTrace(); + EventBus.getDefault().post(new SubmitVideoOrGifPostEvent(false, true, null)); + + stopService(); + } + } + + private static class CopyFileToCacheAsyncTask extends AsyncTask { + + private InputStream fileInputStream; + private String destinationFilePath; + private CopyFileToCacheAsyncTaskListener copyFileToCacheAsyncTaskListener; + private boolean parseFailed = false; + + interface CopyFileToCacheAsyncTaskListener { + void success(); + void failed(); + } + + public CopyFileToCacheAsyncTask(InputStream fileInputStream, String destinationFilePath, CopyFileToCacheAsyncTaskListener copyFileToCacheAsyncTaskListener) { + this.fileInputStream = fileInputStream; + this.destinationFilePath = destinationFilePath; + this.copyFileToCacheAsyncTaskListener = copyFileToCacheAsyncTaskListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try (OutputStream out = new FileOutputStream(destinationFilePath)) { + byte[] buf = new byte[2048]; + int len; + while ((len = fileInputStream.read(buf)) > 0) { + out.write(buf, 0, len); + } + } catch (IOException e) { + e.printStackTrace(); + parseFailed = true; + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (parseFailed) { + copyFileToCacheAsyncTaskListener.failed(); + } else { + copyFileToCacheAsyncTaskListener.success(); + } + } + } + + private void stopService() { + stopForeground(true); + stopSelf(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AboutPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AboutPreferenceFragment.java new file mode 100644 index 00000000..8e30fc11 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AboutPreferenceFragment.java @@ -0,0 +1,143 @@ +package ml.docilealligator.infinityforreddit.settings; + + +import android.app.Activity; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.BuildConfig; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +/** + * A simple {@link PreferenceFragmentCompat} subclass. + */ +public class AboutPreferenceFragment extends PreferenceFragmentCompat { + + private Activity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.about_preferences, rootKey); + + Preference openSourcePreference = findPreference(SharedPreferencesUtils.OPEN_SOURCE_KEY); + Preference ratePreference = findPreference(SharedPreferencesUtils.RATE_KEY); + Preference fDroidPreference = findPreference(SharedPreferencesUtils.F_DROID_KEY); + Preference emailPreference = findPreference(SharedPreferencesUtils.EMAIL_KEY); + Preference redditAccountPreference = findPreference(SharedPreferencesUtils.REDDIT_ACCOUNT_KEY); + Preference subredditPreference = findPreference(SharedPreferencesUtils.SUBREDDIT_KEY); + Preference sharePreference = findPreference(SharedPreferencesUtils.SHARE_KEY); + Preference versionPreference = findPreference(SharedPreferencesUtils.VERSION_KEY); + + if (openSourcePreference != null) { + openSourcePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://github.com/Docile-Alligator/Infinity-For-Reddit")); + startActivity(intent); + return true; + }); + } + + if (ratePreference != null) { + ratePreference.setOnPreferenceClickListener(preference -> { + Intent playStoreIntent = new Intent(Intent.ACTION_VIEW); + playStoreIntent.setData(Uri.parse("market://details?id=ml.docilealligator.infinityforreddit")); + if (playStoreIntent.resolveActivity(activity.getPackageManager()) != null) { + activity.startActivity(playStoreIntent); + } else { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://play.google.com/store/apps/details?id=ml.docilealligator.infinityforreddit")); + startActivity(intent); + } + return true; + }); + } + + if (fDroidPreference != null) { + fDroidPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.reddit.com/r/Infinity_For_Reddit/comments/f23o0y/for_anyone_who_wants_to_use_fdroid/")); + startActivity(intent); + return true; + }); + } + + if (emailPreference != null) { + emailPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(Intent.ACTION_SENDTO); + intent.setData(Uri.parse("mailto:docilealligator.app@gmail.com")); + try { + startActivity(intent); + } catch (ActivityNotFoundException e) { + Toast.makeText(activity, R.string.no_email_client, Toast.LENGTH_SHORT).show(); + } + return true; + }); + } + + if (redditAccountPreference != null) { + redditAccountPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.reddit.com/user/Hostilenemy")); + startActivity(intent); + return true; + }); + } + + if (subredditPreference != null) { + subredditPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.reddit.com/r/Infinity_For_Reddit")); + startActivity(intent); + return true; + }); + } + + if (sharePreference != null) { + sharePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(Intent.ACTION_SEND); + intent.setType("text/plain"); + intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_this_app)); + if (intent.resolveActivity(activity.getPackageManager()) != null) { + startActivity(intent); + } else { + Toast.makeText(activity, R.string.no_app, Toast.LENGTH_SHORT).show(); + } + return true; + }); + } + + if (versionPreference != null) { + versionPreference.setSummary(getString(R.string.settings_version_summary, BuildConfig.VERSION_NAME)); + + versionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + int clickedTimes = 0; + + @Override + public boolean onPreferenceClick(Preference preference) { + clickedTimes++; + if (clickedTimes > 6) { + Toast.makeText(activity, R.string.no_developer_easter_egg, Toast.LENGTH_SHORT).show(); + clickedTimes = 0; + } + return true; + } + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Acknowledgement.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Acknowledgement.java new file mode 100644 index 00000000..d11f368f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Acknowledgement.java @@ -0,0 +1,27 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.net.Uri; + +public class Acknowledgement { + private String name; + private String introduction; + private Uri link; + + Acknowledgement(String name, String introduction, Uri link) { + this.name = name; + this.introduction = introduction; + this.link = link; + } + + public String getName() { + return name; + } + + public String getIntroduction() { + return introduction; + } + + public Uri getLink() { + return link; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java new file mode 100644 index 00000000..4864d4cb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AcknowledgementFragment.java @@ -0,0 +1,138 @@ +package ml.docilealligator.infinityforreddit.settings; + + +import android.app.Activity; +import android.content.Context; +import android.net.Uri; +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 androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.AcknowledgementRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.R; + +/** + * A simple {@link Fragment} subclass. + */ +public class AcknowledgementFragment extends Fragment { + + @BindView(R.id.recycler_view_acknowledgement_fragment) + RecyclerView recyclerView; + private Activity activity; + + public AcknowledgementFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_acknowledgement, container, false); + ButterKnife.bind(this, rootView); + + ArrayList acknowledgements = new ArrayList<>(); + acknowledgements.add(new Acknowledgement("ExoPlayer", + "An application level media player for Android", + Uri.parse("https://github.com/google/ExoPlayer"))); + acknowledgements.add(new Acknowledgement("GestureViews", + "ImageView and FrameLayout with gestures control and position animation", + Uri.parse("https://github.com/alexvasilkov/GestureViews"))); + acknowledgements.add(new Acknowledgement("Glide", + "A fast and efficient open source media management and image loading framework for Android", + Uri.parse("https://github.com/bumptech/glide"))); + acknowledgements.add(new Acknowledgement("RxAndroid", + "Android specific bindings for RxJava 2", + Uri.parse("https://github.com/ReactiveX/RxAndroid"))); + acknowledgements.add(new Acknowledgement("RxJava", + "Reactive extensions for the JVM", + Uri.parse("https://github.com/ReactiveX/RxJava"))); + acknowledgements.add(new Acknowledgement("Retrofit", + "Type-safe HTTP client for Android and Java by Square, Inc.", + Uri.parse("https://github.com/square/retrofit"))); + acknowledgements.add(new Acknowledgement("Dagger", + "A fast dependency injector for Java and Android.", + Uri.parse("https://github.com/google/dagger"))); + acknowledgements.add(new Acknowledgement("Butter Knife", + "Field and method binding for Android views", + Uri.parse("https://github.com/JakeWharton/butterknife"))); + acknowledgements.add(new Acknowledgement("Aspect Ratio ImageView", + "A simple imageview which scales the width or height aspect with the given ratio", + Uri.parse("https://github.com/santalu/aspect-ratio-imageview"))); + acknowledgements.add(new Acknowledgement("MaterialLoadingProgressBar", + "A styled ProgressBar", + Uri.parse("https://github.com/lsjwzh/MaterialLoadingProgressBar"))); + acknowledgements.add(new Acknowledgement("Markwon", + "A markdown library for Android", + Uri.parse("https://github.com/noties/Markwon"))); + acknowledgements.add(new Acknowledgement("android-gif-drawable", + "Views and Drawable for animated GIFs in Android.", + Uri.parse("https://github.com/koral--/android-gif-drawable"))); + acknowledgements.add(new Acknowledgement("SimpleSearchView", + "A simple SearchView for Android based on Material Design", + Uri.parse("https://github.com/Ferfalk/SimpleSearchView"))); + acknowledgements.add(new Acknowledgement("EventBus", + "A publish/subscribe event bus for Android and Java", + Uri.parse("https://github.com/greenrobot/EventBus"))); + acknowledgements.add(new Acknowledgement("Customized and Expandable TextView", + "Simple library to change the Textview as rectangle, circle and square shapes", + Uri.parse("https://github.com/Rajagopalr3/CustomizedTextView"))); + acknowledgements.add(new Acknowledgement("Rounded Bottom Sheet", + "Bottom sheet with rounded corners", + Uri.parse("https://github.com/Deishelon/RoundedBottomSheet"))); + acknowledgements.add(new Acknowledgement("Bridge", + "A library for avoiding TransactionTooLargeException during state saving and restoration", + Uri.parse("https://github.com/livefront/bridge"))); + acknowledgements.add(new Acknowledgement("Android-State", + "A utility library for Android to save objects in a Bundle without any boilerplate", + Uri.parse("https://github.com/evernote/android-state"))); + acknowledgements.add(new Acknowledgement("FlowLayout", + "A FlowLayout for Android, which allows child views flow to next row when there is no enough space.", + Uri.parse("https://github.com/nex3z/FlowLayout"))); + acknowledgements.add(new Acknowledgement("Gson", + "Gson is a Java library that can be used to convert Java Objects into their JSON representation.", + Uri.parse("https://github.com/google/gson"))); + acknowledgements.add(new Acknowledgement("Hauler", + "Hauler is an Android library containing custom layout which enables to easily create swipe to dismiss Activity.", + Uri.parse("https://github.com/futuredapp/hauler"))); + acknowledgements.add(new Acknowledgement("Slidr", + "Easily add slide to dismiss functionality to an Activity", + Uri.parse("https://github.com/r0adkll/Slidr"))); + acknowledgements.add(new Acknowledgement("commonmark-java", + "Java library for parsing and rendering Markdown text according to the CommonMark specification (and some extensions).", + Uri.parse("https://github.com/atlassian/commonmark-java"))); + acknowledgements.add(new Acknowledgement("AndroidFastScroll", + "Fast scroll for Android RecyclerView and more.", + Uri.parse("https://github.com/zhanghai/AndroidFastScroll"))); + acknowledgements.add(new Acknowledgement("Subsampling Scale Image View", + "A custom image view for Android, designed for photo galleries and displaying " + + "huge images (e.g. maps and building plans) without OutOfMemoryErrors.", + Uri.parse("https://github.com/davemorrissey/subsampling-scale-image-view"))); + acknowledgements.add(new Acknowledgement("BigImageViewer", + "Big image viewer supporting pan and zoom, with very little memory " + + "usage and full featured image loading choices. Powered by Subsampling Scale " + + "Image View, Fresco, Glide, and Picasso. Even with gif and webp support!", + Uri.parse("https://github.com/Piasy/BigImageViewer"))); + + AcknowledgementRecyclerViewAdapter adapter = new AcknowledgementRecyclerViewAdapter(activity, acknowledgements); + recyclerView.setLayoutManager(new LinearLayoutManager(activity)); + recyclerView.setAdapter(adapter); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java new file mode 100644 index 00000000..4c3e602e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java @@ -0,0 +1,237 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import org.greenrobot.eventbus.EventBus; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllPostLayoutsAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllSortTypesAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllSubredditsAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllThemesAsyncTask; +import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllUsersAsyncTask; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +/** + * A simple {@link Fragment} subclass. + */ +public class AdvancedPreferenceFragment extends PreferenceFragmentCompat { + + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("sort_type") + SharedPreferences mSortTypeSharedPreferences; + @Inject + @Named("post_layout") + SharedPreferences mPostLayoutSharedPreferences; + @Inject + @Named("light_theme") + SharedPreferences lightThemeSharedPreferences; + @Inject + @Named("dark_theme") + SharedPreferences darkThemeSharedPreferences; + @Inject + @Named("post_feed_scrolled_position_cache") + SharedPreferences postFeedScrolledPositionSharedPreferences; + @Inject + @Named("amoled_theme") + SharedPreferences amoledThemeSharedPreferences; + @Inject + @Named("main_activity_tabs") + SharedPreferences mainActivityTabsSharedPreferences; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences nsfwAndBlurringSharedPreferences; + private Activity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.advanced_preferences, rootKey); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + Preference deleteSubredditsPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_SUBREDDITS_DATA_IN_DATABASE); + Preference deleteUsersPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_USERS_DATA_IN_DATABASE); + Preference deleteSortTypePreference = findPreference(SharedPreferencesUtils.DELETE_ALL_SORT_TYPE_DATA_IN_DATABASE); + Preference deletePostLaoutPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_POST_LAYOUT_DATA_IN_DATABASE); + Preference deleteAllThemesPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_THEMES_IN_DATABASE); + Preference deletePostFeedScrolledPositionsPreference = findPreference(SharedPreferencesUtils.DELETE_FRONT_PAGE_SCROLLED_POSITIONS_IN_DATABASE); + Preference deleteAllLegacySettingsPreference = findPreference(SharedPreferencesUtils.DELETE_ALL_LEGACY_SETTINGS); + Preference resetAllSettingsPreference = findPreference(SharedPreferencesUtils.RESET_ALL_SETTINGS); + + if (deleteSubredditsPreference != null) { + deleteSubredditsPreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> new DeleteAllSubredditsAsyncTask(mRedditDataRoomDatabase, + () -> Toast.makeText(activity, R.string.delete_all_subreddits_success, Toast.LENGTH_SHORT).show()).execute()) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + + if (deleteUsersPreference != null) { + deleteUsersPreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> new DeleteAllUsersAsyncTask(mRedditDataRoomDatabase, + () -> Toast.makeText(activity, R.string.delete_all_users_success, Toast.LENGTH_SHORT).show()).execute()) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + + if (deleteSortTypePreference != null) { + deleteSortTypePreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> new DeleteAllSortTypesAsyncTask(mSharedPreferences, mSortTypeSharedPreferences, () -> { + Toast.makeText(activity, R.string.delete_all_sort_types_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new RecreateActivityEvent()); + }).execute()) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + + if (deletePostLaoutPreference != null) { + deletePostLaoutPreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> new DeleteAllPostLayoutsAsyncTask(mSharedPreferences, mPostLayoutSharedPreferences, () -> { + Toast.makeText(activity, R.string.delete_all_post_layouts_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new RecreateActivityEvent()); + }).execute()) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + + if (deleteAllThemesPreference != null) { + deleteAllThemesPreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> new DeleteAllThemesAsyncTask(mRedditDataRoomDatabase, lightThemeSharedPreferences, + darkThemeSharedPreferences, amoledThemeSharedPreferences, () -> { + Toast.makeText(activity, R.string.delete_all_themes_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new RecreateActivityEvent()); + }).execute()) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + + if (deletePostFeedScrolledPositionsPreference != null) { + deletePostFeedScrolledPositionsPreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> { + postFeedScrolledPositionSharedPreferences.edit().clear().apply(); + Toast.makeText(activity, R.string.delete_all_front_page_scrolled_positions_success, Toast.LENGTH_SHORT).show(); + }) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + + if (deleteAllLegacySettingsPreference != null) { + deleteAllLegacySettingsPreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> { + SharedPreferences.Editor editor = mSharedPreferences.edit(); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME_LEGACY); + editor.remove(SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME_LEGACY); + editor.remove(SharedPreferencesUtils.NSFW_KEY_LEGACY); + editor.remove(SharedPreferencesUtils.BLUR_NSFW_KEY_LEGACY); + editor.remove(SharedPreferencesUtils.BLUR_SPOILER_KEY_LEGACY); + + SharedPreferences.Editor sortTypeEditor = mSortTypeSharedPreferences.edit(); + sortTypeEditor.remove(SharedPreferencesUtils.SORT_TYPE_ALL_POST_LEGACY); + sortTypeEditor.remove(SharedPreferencesUtils.SORT_TIME_ALL_POST_LEGACY); + sortTypeEditor.remove(SharedPreferencesUtils.SORT_TYPE_POPULAR_POST_LEGACY); + sortTypeEditor.remove(SharedPreferencesUtils.SORT_TIME_POPULAR_POST_LEGACY); + + SharedPreferences.Editor postLayoutEditor = mPostLayoutSharedPreferences.edit(); + postLayoutEditor.remove(SharedPreferencesUtils.POST_LAYOUT_ALL_POST_LEGACY); + postLayoutEditor.remove(SharedPreferencesUtils.POST_LAYOUT_POPULAR_POST_LEGACY); + + editor.apply(); + sortTypeEditor.apply(); + postLayoutEditor.apply(); + Toast.makeText(activity, R.string.delete_all_legacy_settings_success, Toast.LENGTH_SHORT).show(); + }) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + + if (resetAllSettingsPreference != null) { + resetAllSettingsPreference.setOnPreferenceClickListener(preference -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.are_you_sure) + .setPositiveButton(R.string.yes, (dialogInterface, i) + -> { + mSharedPreferences.edit().clear().apply(); + mainActivityTabsSharedPreferences.edit().clear().apply(); + nsfwAndBlurringSharedPreferences.edit().clear().apply(); + + Toast.makeText(activity, R.string.reset_all_settings_success, Toast.LENGTH_SHORT).show(); + EventBus.getDefault().post(new RecreateActivityEvent()); + }) + .setNegativeButton(R.string.no, null) + .show(); + return true; + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (AppCompatActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CreditsPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CreditsPreferenceFragment.java new file mode 100644 index 00000000..5c62f438 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CreditsPreferenceFragment.java @@ -0,0 +1,136 @@ +package ml.docilealligator.infinityforreddit.settings; + + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import ml.docilealligator.infinityforreddit.activities.LinkResolverActivity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +/** + * A simple {@link PreferenceFragmentCompat} subclass. + */ +public class CreditsPreferenceFragment extends PreferenceFragmentCompat { + + private Activity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.credits_preferences, rootKey); + + Preference iconForegroundPreference = findPreference(SharedPreferencesUtils.ICON_FOREGROUND_KEY); + Preference iconBackgroundPreference = findPreference(SharedPreferencesUtils.ICON_BACKGROUND_KEY); + Preference errorImagePreference = findPreference(SharedPreferencesUtils.ERROR_IMAGE_KEY); + Preference gildedIconPreference = findPreference(SharedPreferencesUtils.GILDED_ICON_KEY); + Preference crosspostIconPreference = findPreference(SharedPreferencesUtils.CROSSPOST_ICON_KEY); + Preference thumbtackIconPreference = findPreference(SharedPreferencesUtils.THUMBTACK_ICON_KEY); + Preference bestRocketIconPreference = findPreference(SharedPreferencesUtils.BEST_ROCKET_ICON_KEY); + Preference materialIconsPreference = findPreference(SharedPreferencesUtils.MATERIAL_ICONS_KEY); + Preference nationalFlagsPreference = findPreference(SharedPreferencesUtils.NATIONAL_FLAGS); + Preference ufoAndCowPreference = findPreference(SharedPreferencesUtils.UFO_CAPTURING_ANIMATION); + + if (iconForegroundPreference != null) { + iconForegroundPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.freepik.com/free-photos-vectors/technology")); + startActivity(intent); + return true; + }); + } + + if (iconBackgroundPreference != null) { + iconBackgroundPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.freepik.com/free-photos-vectors/background")); + startActivity(intent); + return true; + }); + } + + if (errorImagePreference != null) { + errorImagePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.freepik.com/free-photos-vectors/technology")); + startActivity(intent); + return true; + }); + } + + if (gildedIconPreference != null) { + gildedIconPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://br.flaticon.com/icone-gratis/medalha_1007239")); + startActivity(intent); + return true; + }); + } + + if (crosspostIconPreference != null) { + crosspostIconPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.flaticon.com/free-icon/crossed-arrows_2291")); + startActivity(intent); + return true; + }); + } + + if (thumbtackIconPreference != null) { + thumbtackIconPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.flaticon.com/free-icon/tack-save-button_61845#term=thumbtack&page=1&position=3")); + startActivity(intent); + return true; + }); + } + + if (bestRocketIconPreference != null) { + bestRocketIconPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.flaticon.com/free-icon/spring-swing-rocket_2929322?term=space%20ship&page=1&position=18")); + startActivity(intent); + return true; + }); + } + + if (materialIconsPreference != null) { + materialIconsPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://material.io/resources/icons/")); + startActivity(intent); + return true; + }); + } + + if (nationalFlagsPreference != null) { + nationalFlagsPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://www.flaticon.com/packs/countrys-flags")); + startActivity(intent); + return true; + }); + } + + if (ufoAndCowPreference != null) { + ufoAndCowPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, LinkResolverActivity.class); + intent.setData(Uri.parse("https://lottiefiles.com/33858-ufo-capturing-animation")); + startActivity(intent); + return true; + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeBottomAppBarFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeBottomAppBarFragment.java new file mode 100644 index 00000000..a025cccc --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeBottomAppBarFragment.java @@ -0,0 +1,330 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class CustomizeBottomAppBarFragment extends Fragment { + + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + + @BindView(R.id.info_text_view_customize_bottom_app_bar_fragment) + TextView infoTextView; + @BindView(R.id.divider_1_customize_bottom_app_bar_fragment) + View divider1; + @BindView(R.id.main_activity_group_summary_customize_bottom_app_bar_fragment) + TextView mainActivityGroupSummaryTextView; + @BindView(R.id.main_activity_option_count_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout mainActivityOptionCountLinearLayout; + @BindView(R.id.main_activity_option_count_text_view_customize_bottom_app_bar_fragment) + TextView mainActivityOptionCountTextView; + @BindView(R.id.main_activity_option_1_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout mainActivityOption1LinearLayout; + @BindView(R.id.main_activity_option_1_text_view_customize_bottom_app_bar_fragment) + TextView mainActivityOption1TextView; + @BindView(R.id.main_activity_option_2_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout mainActivityOption2LinearLayout; + @BindView(R.id.main_activity_option_2_text_view_customize_bottom_app_bar_fragment) + TextView mainActivityOption2TextView; + @BindView(R.id.main_activity_option_3_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout mainActivityOption3LinearLayout; + @BindView(R.id.main_activity_option_3_text_view_customize_bottom_app_bar_fragment) + TextView mainActivityOption3TextView; + @BindView(R.id.main_activity_option_4_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout mainActivityOption4LinearLayout; + @BindView(R.id.main_activity_option_4_text_view_customize_bottom_app_bar_fragment) + TextView mainActivityOption4TextView; + @BindView(R.id.main_activity_fab_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout mainActivityFABLinearLayout; + @BindView(R.id.main_activity_fab_text_view_customize_bottom_app_bar_fragment) + TextView mainActivityFABTextView; + + @BindView(R.id.divider_2_customize_bottom_app_bar_fragment) + View divider2; + @BindView(R.id.other_activities_group_summary_customize_bottom_app_bar_fragment) + TextView otherActivitiesGroupSummaryTextView; + @BindView(R.id.other_activities_option_count_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout otherActivitiesOptionCountLinearLayout; + @BindView(R.id.other_activities_option_count_text_view_customize_bottom_app_bar_fragment) + TextView otherActivitiesOptionCountTextView; + @BindView(R.id.other_activities_option_1_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout otherActivitiesOption1LinearLayout; + @BindView(R.id.other_activities_option_1_text_view_customize_bottom_app_bar_fragment) + TextView otherActivitiesOption1TextView; + @BindView(R.id.other_activities_option_2_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout otherActivitiesOption2LinearLayout; + @BindView(R.id.other_activities_option_2_text_view_customize_bottom_app_bar_fragment) + TextView otherActivitiesOption2TextView; + @BindView(R.id.other_activities_option_3_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout otherActivitiesOption3LinearLayout; + @BindView(R.id.other_activities_option_3_text_view_customize_bottom_app_bar_fragment) + TextView otherActivitiesOption3TextView; + @BindView(R.id.other_activities_option_4_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout otherActivitiesOption4LinearLayout; + @BindView(R.id.other_activities_option_4_text_view_customize_bottom_app_bar_fragment) + TextView otherActivitiesOption4TextView; + @BindView(R.id.other_activities_fab_linear_layout_customize_bottom_app_bar_fragment) + LinearLayout otherActivitiesFABLinearLayout; + @BindView(R.id.other_activities_fab_text_view_customize_bottom_app_bar_fragment) + TextView otherActivitiesFABTextView; + @Inject + @Named("bottom_app_bar") + SharedPreferences sharedPreferences; + private Activity activity; + private int mainActivityOptionCount; + private int mainActivityOption1; + private int mainActivityOption2; + private int mainActivityOption3; + private int mainActivityOption4; + private int mainActivityFAB; + private int otherActivitiesOptionCount; + private int otherActivitiesOption1; + private int otherActivitiesOption2; + private int otherActivitiesOption3; + private int otherActivitiesOption4; + private int otherActivitiesFAB; + + public CustomizeBottomAppBarFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_customize_bottom_app_bar, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + + if (accountName == null) { + infoTextView.setText(R.string.only_for_logged_in_user); + divider1.setVisibility(View.GONE); + mainActivityGroupSummaryTextView.setVisibility(View.GONE); + mainActivityOptionCountLinearLayout.setVisibility(View.GONE); + mainActivityOption1LinearLayout.setVisibility(View.GONE); + mainActivityOption2LinearLayout.setVisibility(View.GONE); + mainActivityOption3LinearLayout.setVisibility(View.GONE); + mainActivityOption4LinearLayout.setVisibility(View.GONE); + mainActivityFABLinearLayout.setVisibility(View.GONE); + divider2.setVisibility(View.GONE); + otherActivitiesGroupSummaryTextView.setVisibility(View.GONE); + otherActivitiesOptionCountLinearLayout.setVisibility(View.GONE); + otherActivitiesOption1LinearLayout.setVisibility(View.GONE); + otherActivitiesOption2LinearLayout.setVisibility(View.GONE); + otherActivitiesOption3LinearLayout.setVisibility(View.GONE); + otherActivitiesOption4LinearLayout.setVisibility(View.GONE); + otherActivitiesFABLinearLayout.setVisibility(View.GONE); + + return rootView; + } + + Resources resources = activity.getResources(); + String[] mainActivityOptions = resources.getStringArray(R.array.settings_main_activity_bottom_app_bar_options); + String[] fabOptions = resources.getStringArray(R.array.settings_bottom_app_bar_fab_options); + mainActivityOptionCount = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT, 4); + mainActivityOption1 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1, 0); + mainActivityOption2 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2, 1); + mainActivityOption3 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3, 2); + mainActivityOption4 = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4, 3); + mainActivityFAB = sharedPreferences.getInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB, 0); + + mainActivityOptionCountTextView.setText(Integer.toString(mainActivityOptionCount)); + mainActivityOption1TextView.setText(mainActivityOptions[mainActivityOption1]); + mainActivityOption2TextView.setText(mainActivityOptions[mainActivityOption2]); + mainActivityOption3TextView.setText(mainActivityOptions[mainActivityOption3]); + mainActivityOption4TextView.setText(mainActivityOptions[mainActivityOption4]); + mainActivityFABTextView.setText(fabOptions[mainActivityFAB]); + + mainActivityOptionCountLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_count) + .setSingleChoiceItems(R.array.settings_bottom_app_bar_option_count_options, mainActivityOptionCount / 2 - 1, (dialogInterface, i) -> { + mainActivityOptionCount = (i + 1) * 2; + sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT, mainActivityOptionCount).apply(); + mainActivityOptionCountTextView.setText(Integer.toString(mainActivityOptionCount)); + dialogInterface.dismiss(); + }) + .show(); + }); + + mainActivityOption1LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_1) + .setSingleChoiceItems(mainActivityOptions, mainActivityOption1, (dialogInterface, i) -> { + mainActivityOption1 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1, mainActivityOption1).apply(); + mainActivityOption1TextView.setText(mainActivityOptions[mainActivityOption1]); + dialogInterface.dismiss(); + }) + .show(); + }); + + mainActivityOption2LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_2) + .setSingleChoiceItems(mainActivityOptions, mainActivityOption2, (dialogInterface, i) -> { + mainActivityOption2 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2, mainActivityOption2).apply(); + mainActivityOption2TextView.setText(mainActivityOptions[mainActivityOption2]); + dialogInterface.dismiss(); + }) + .show(); + }); + + mainActivityOption3LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_3) + .setSingleChoiceItems(mainActivityOptions, mainActivityOption3, (dialogInterface, i) -> { + mainActivityOption3 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3, mainActivityOption3).apply(); + mainActivityOption3TextView.setText(mainActivityOptions[mainActivityOption3]); + dialogInterface.dismiss(); + }) + .show(); + }); + + mainActivityOption4LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_4) + .setSingleChoiceItems(mainActivityOptions, mainActivityOption4, (dialogInterface, i) -> { + mainActivityOption4 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4, mainActivityOption4).apply(); + mainActivityOption4TextView.setText(mainActivityOptions[mainActivityOption4]); + dialogInterface.dismiss(); + }) + .show(); + }); + + mainActivityFABLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_fab) + .setSingleChoiceItems(fabOptions, mainActivityFAB, (dialogInterface, i) -> { + mainActivityFAB = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB, mainActivityFAB).apply(); + mainActivityFABTextView.setText(fabOptions[mainActivityFAB]); + dialogInterface.dismiss(); + }) + .show(); + }); + + String[] otherActivitiesOptions = resources.getStringArray(R.array.settings_other_activities_bottom_app_bar_options); + otherActivitiesOptionCount = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT, 4); + otherActivitiesOption1 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1, 0); + otherActivitiesOption2 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2, 1); + otherActivitiesOption3 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3, 2); + otherActivitiesOption4 = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4, 3); + otherActivitiesFAB = sharedPreferences.getInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB, 0); + + otherActivitiesOptionCountTextView.setText(Integer.toString(otherActivitiesOptionCount)); + otherActivitiesOption1TextView.setText(otherActivitiesOptions[otherActivitiesOption1]); + otherActivitiesOption2TextView.setText(otherActivitiesOptions[otherActivitiesOption2]); + otherActivitiesOption3TextView.setText(otherActivitiesOptions[otherActivitiesOption3]); + otherActivitiesOption4TextView.setText(otherActivitiesOptions[otherActivitiesOption4]); + otherActivitiesFABTextView.setText(fabOptions[otherActivitiesFAB]); + + otherActivitiesOptionCountLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_count) + .setSingleChoiceItems(R.array.settings_bottom_app_bar_option_count_options, otherActivitiesOptionCount / 2 - 1, (dialogInterface, i) -> { + otherActivitiesOptionCount = (i + 1) * 2; + sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT, otherActivitiesOptionCount).apply(); + otherActivitiesOptionCountTextView.setText(Integer.toString(otherActivitiesOptionCount)); + dialogInterface.dismiss(); + }) + .show(); + }); + + otherActivitiesOption1LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_1) + .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption1, (dialogInterface, i) -> { + otherActivitiesOption1 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1, otherActivitiesOption1).apply(); + otherActivitiesOption1TextView.setText(otherActivitiesOptions[otherActivitiesOption1]); + dialogInterface.dismiss(); + }) + .show(); + }); + + otherActivitiesOption2LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_2) + .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption2, (dialogInterface, i) -> { + otherActivitiesOption2 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2, otherActivitiesOption2).apply(); + otherActivitiesOption2TextView.setText(otherActivitiesOptions[otherActivitiesOption2]); + dialogInterface.dismiss(); + }) + .show(); + }); + + otherActivitiesOption3LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_3) + .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption3, (dialogInterface, i) -> { + otherActivitiesOption3 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3, otherActivitiesOption3).apply(); + otherActivitiesOption3TextView.setText(otherActivitiesOptions[otherActivitiesOption3]); + dialogInterface.dismiss(); + }) + .show(); + }); + + otherActivitiesOption4LinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_option_4) + .setSingleChoiceItems(otherActivitiesOptions, otherActivitiesOption4, (dialogInterface, i) -> { + otherActivitiesOption4 = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4, otherActivitiesOption4).apply(); + otherActivitiesOption4TextView.setText(otherActivitiesOptions[otherActivitiesOption4]); + dialogInterface.dismiss(); + }) + .show(); + }); + + otherActivitiesFABLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_bottom_app_bar_fab) + .setSingleChoiceItems(fabOptions, otherActivitiesFAB, (dialogInterface, i) -> { + otherActivitiesFAB = i; + sharedPreferences.edit().putInt(SharedPreferencesUtils.OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB, otherActivitiesFAB).apply(); + otherActivitiesFABTextView.setText(fabOptions[otherActivitiesFAB]); + dialogInterface.dismiss(); + }) + .show(); + }); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java new file mode 100644 index 00000000..7a2cca00 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/CustomizeMainPageTabsFragment.java @@ -0,0 +1,563 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.switchmaterial.SwitchMaterial; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class CustomizeMainPageTabsFragment extends Fragment { + + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + + @BindView(R.id.info_text_view_customize_main_page_tabs_fragment) + TextView infoTextView; + @BindView(R.id.tab_count_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tabCountLinearLayout; + @BindView(R.id.tab_count_text_view_customize_main_page_tabs_fragment) + TextView tabCountTextView; + @BindView(R.id.show_tab_names_linear_layout_customize_main_page_tabs_fragment) + LinearLayout showTabNamesLinearLayout; + @BindView(R.id.show_tab_names_switch_material_customize_main_page_tabs_fragment) + SwitchMaterial showTabNamesSwitch; + @BindView(R.id.divider_1_customize_main_page_tabs_fragment) + View divider1; + @BindView(R.id.tab_1_group_summary_customize_main_page_tabs_fragment) + TextView tab1GroupSummaryTextView; + @BindView(R.id.tab_1_title_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab1TitleLinearLayout; + @BindView(R.id.tab_1_title_summary_text_view_customize_main_page_tabs_fragment) + TextView tab1TitleSummaryTextView; + @BindView(R.id.tab_1_type_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab1TypeLinearLayout; + @BindView(R.id.tab_1_type_summary_text_view_customize_main_page_tabs_fragment) + TextView tab1TypeSummaryTextView; + @BindView(R.id.tab_1_name_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab1NameLinearLayout; + @BindView(R.id.tab_1_name_title_text_view_customize_main_page_tabs_fragment) + TextView tab1NameTitleTextView; + @BindView(R.id.tab_1_name_summary_text_view_customize_main_page_tabs_fragment) + TextView tab1NameSummaryTextView; + @BindView(R.id.divider_2_customize_main_page_tabs_fragment) + View divider2; + @BindView(R.id.tab_2_group_summary_customize_main_page_tabs_fragment) + TextView tab2GroupSummaryTextView; + @BindView(R.id.tab_2_title_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab2TitleLinearLayout; + @BindView(R.id.tab_2_title_summary_text_view_customize_main_page_tabs_fragment) + TextView tab2TitleSummaryTextView; + @BindView(R.id.tab_2_type_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab2TypeLinearLayout; + @BindView(R.id.tab_2_type_summary_text_view_customize_main_page_tabs_fragment) + TextView tab2TypeSummaryTextView; + @BindView(R.id.tab_2_name_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab2NameLinearLayout; + @BindView(R.id.tab_2_name_title_text_view_customize_main_page_tabs_fragment) + TextView tab2NameTitleTextView; + @BindView(R.id.tab_2_name_summary_text_view_customize_main_page_tabs_fragment) + TextView tab2NameSummaryTextView; + @BindView(R.id.divider_3_customize_main_page_tabs_fragment) + View divider3; + @BindView(R.id.tab_3_group_summary_customize_main_page_tabs_fragment) + TextView tab3GroupSummaryTextView; + @BindView(R.id.tab_3_title_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab3TitleLinearLayout; + @BindView(R.id.tab_3_title_summary_text_view_customize_main_page_tabs_fragment) + TextView tab3TitleSummaryTextView; + @BindView(R.id.tab_3_type_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab3TypeLinearLayout; + @BindView(R.id.tab_3_type_summary_text_view_customize_main_page_tabs_fragment) + TextView tab3TypeSummaryTextView; + @BindView(R.id.tab_3_name_linear_layout_customize_main_page_tabs_fragment) + LinearLayout tab3NameLinearLayout; + @BindView(R.id.tab_3_name_title_text_view_customize_main_page_tabs_fragment) + TextView tab3NameTitleTextView; + @BindView(R.id.tab_3_name_summary_text_view_customize_main_page_tabs_fragment) + TextView tab3NameSummaryTextView; + @BindView(R.id.divider_4_customize_main_page_tabs_fragment) + View divider4; + @BindView(R.id.more_tabs_group_summary_customize_main_page_tabs_fragment) + TextView moreTabsGroupSummaryTextView; + @BindView(R.id.more_tabs_info_text_view_customize_main_page_tabs_fragment) + TextView moreTabsInfoTextView; + @BindView(R.id.show_subscribed_subreddits_linear_layout_customize_main_page_tabs_fragment) + LinearLayout showSubscribedSubredditsLinearLayout; + @BindView(R.id.show_subscribed_subreddits_switch_material_customize_main_page_tabs_fragment) + SwitchMaterial showSubscribedSubredditsSwitchMaterial; + @BindView(R.id.show_favorite_subscribed_subreddits_linear_layout_customize_main_page_tabs_fragment) + LinearLayout showFavoriteSubscribedSubredditsLinearLayout; + @BindView(R.id.show_favorite_subscribed_subreddits_switch_material_customize_main_page_tabs_fragment) + SwitchMaterial showFavoriteSubscribedSubredditsSwitchMaterial; + @Inject + @Named("main_activity_tabs") + SharedPreferences sharedPreferences; + private Activity activity; + private int tabCount; + private String tab1CurrentTitle; + private int tab1CurrentPostType; + private String tab1CurrentName; + private String tab2CurrentTitle; + private int tab2CurrentPostType; + private String tab2CurrentName; + private String tab3CurrentTitle; + private int tab3CurrentPostType; + private String tab3CurrentName; + + public CustomizeMainPageTabsFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_customize_main_page_tabs, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + + if (accountName == null) { + infoTextView.setText(R.string.only_for_logged_in_user); + divider1.setVisibility(View.GONE); + tabCountLinearLayout.setVisibility(View.GONE); + showTabNamesLinearLayout.setVisibility(View.GONE); + tab1GroupSummaryTextView.setVisibility(View.GONE); + tab1TitleLinearLayout.setVisibility(View.GONE); + tab1TypeLinearLayout.setVisibility(View.GONE); + divider2.setVisibility(View.GONE); + tab2GroupSummaryTextView.setVisibility(View.GONE); + tab2TitleLinearLayout.setVisibility(View.GONE); + tab2TypeLinearLayout.setVisibility(View.GONE); + divider3.setVisibility(View.GONE); + tab3GroupSummaryTextView.setVisibility(View.GONE); + tab3TitleLinearLayout.setVisibility(View.GONE); + tab3TypeLinearLayout.setVisibility(View.GONE); + divider4.setVisibility(View.GONE); + moreTabsGroupSummaryTextView.setVisibility(View.GONE); + moreTabsInfoTextView.setVisibility(View.GONE); + showSubscribedSubredditsLinearLayout.setVisibility(View.GONE); + showFavoriteSubscribedSubredditsLinearLayout.setVisibility(View.GONE); + + return rootView; + } + + tabCount = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_COUNT, 3); + tabCountTextView.setText(Integer.toString(tabCount)); + tabCountLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_count) + .setSingleChoiceItems(R.array.settings_main_page_tab_count, tabCount - 1, (dialogInterface, i) -> { + tabCount = i + 1; + sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_COUNT, tabCount).apply(); + tabCountTextView.setText(Integer.toString(tabCount)); + dialogInterface.dismiss(); + }) + .show(); + }); + + boolean showTabNames = sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, true); + showTabNamesSwitch.setChecked(showTabNames); + showTabNamesSwitch.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_TAB_NAMES, b).apply()); + showTabNamesLinearLayout.setOnClickListener(view -> showTabNamesSwitch.performClick()); + + String[] typeValues = activity.getResources().getStringArray(R.array.settings_tab_post_type); + + tab1CurrentTitle = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, getString(R.string.home)); + tab1CurrentPostType = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_HOME); + tab1CurrentName = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME, ""); + tab1TypeSummaryTextView.setText(typeValues[tab1CurrentPostType]); + tab1TitleSummaryTextView.setText(tab1CurrentTitle); + tab1NameSummaryTextView.setText(tab1CurrentName); + applyTab1NameView(tab1NameLinearLayout, tab1NameTitleTextView, tab1CurrentPostType); + + View dialogView = activity.getLayoutInflater().inflate(R.layout.dialog_edit_text, null); + EditText editText = dialogView.findViewById(R.id.edit_text_edit_text_dialog); + + tab1TitleLinearLayout.setOnClickListener(view -> { + editText.setHint(R.string.settings_tab_title); + editText.setText(tab1CurrentTitle); + editText.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + if (dialogView.getParent() != null) { + ((ViewGroup) dialogView.getParent()).removeView(dialogView); + } + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_title) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + tab1CurrentTitle = editText.getText().toString(); + sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_TITLE, tab1CurrentTitle).apply(); + tab1TitleSummaryTextView.setText(tab1CurrentTitle); + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .show(); + }); + + tab1TypeLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_title) + .setSingleChoiceItems(typeValues, tab1CurrentPostType, (dialogInterface, i) -> { + tab1CurrentPostType = i; + sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_POST_TYPE, i).apply(); + tab1TypeSummaryTextView.setText(typeValues[i]); + applyTab1NameView(tab1NameLinearLayout, tab1NameTitleTextView, i); + dialogInterface.dismiss(); + }) + .setNegativeButton(R.string.cancel, null) + .show(); + }); + + tab1NameLinearLayout.setOnClickListener(view -> { + int titleId; + switch (tab1CurrentPostType) { + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: + titleId = R.string.settings_tab_subreddit_name; + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: + titleId = R.string.settings_tab_multi_reddit_name; + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: + titleId = R.string.settings_tab_username; + break; + default: + return; + } + editText.setText(tab1CurrentName); + editText.setHint(titleId); + editText.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + if (dialogView.getParent() != null) { + ((ViewGroup) dialogView.getParent()).removeView(dialogView); + } + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(titleId) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + tab1CurrentName = editText.getText().toString(); + sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_1_NAME, tab1CurrentName).apply(); + tab1NameSummaryTextView.setText(tab1CurrentName); + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .show(); + }); + + tab2CurrentTitle = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, getString(R.string.popular)); + tab2CurrentPostType = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_POPULAR); + tab2CurrentName = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME, ""); + tab2TypeSummaryTextView.setText(typeValues[tab2CurrentPostType]); + tab2TitleSummaryTextView.setText(tab2CurrentTitle); + tab2NameSummaryTextView.setText(tab2CurrentName); + applyTab2NameView(tab2NameLinearLayout, tab2NameTitleTextView, tab2CurrentPostType); + + tab2TitleLinearLayout.setOnClickListener(view -> { + editText.setHint(R.string.settings_tab_title); + editText.setText(tab2CurrentTitle); + editText.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + if (dialogView.getParent() != null) { + ((ViewGroup) dialogView.getParent()).removeView(dialogView); + } + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_title) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + tab2CurrentTitle = editText.getText().toString(); + sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_TITLE, tab2CurrentTitle).apply(); + tab2TitleSummaryTextView.setText(tab2CurrentTitle); + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .show(); + }); + + tab2TypeLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_title) + .setSingleChoiceItems(typeValues, tab2CurrentPostType, (dialogInterface, i) -> { + tab2CurrentPostType = i; + sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_POST_TYPE, i).apply(); + tab2TypeSummaryTextView.setText(typeValues[i]); + applyTab2NameView(tab2NameLinearLayout, tab2NameTitleTextView, i); + dialogInterface.dismiss(); + }) + .setNegativeButton(R.string.cancel, null) + .show(); + }); + + tab2NameLinearLayout.setOnClickListener(view -> { + int titleId; + switch (tab2CurrentPostType) { + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: + titleId = R.string.settings_tab_subreddit_name; + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: + titleId = R.string.settings_tab_multi_reddit_name; + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: + titleId = R.string.settings_tab_username; + break; + default: + return; + } + editText.setText(tab2CurrentName); + editText.setHint(titleId); + editText.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + if (dialogView.getParent() != null) { + ((ViewGroup) dialogView.getParent()).removeView(dialogView); + } + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(titleId) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + tab2CurrentName = editText.getText().toString(); + sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_2_NAME, tab2CurrentName).apply(); + tab2NameSummaryTextView.setText(tab2CurrentName); + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .show(); + }); + + tab3CurrentTitle = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE, getString(R.string.all)); + tab3CurrentPostType = sharedPreferences.getInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE, SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_ALL); + tab3CurrentName = sharedPreferences.getString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME, ""); + tab3TypeSummaryTextView.setText(typeValues[tab3CurrentPostType]); + tab3TitleSummaryTextView.setText(tab3CurrentTitle); + tab3NameSummaryTextView.setText(tab3CurrentName); + applyTab3NameView(tab3NameLinearLayout, tab3NameTitleTextView, tab3CurrentPostType); + + tab3TitleLinearLayout.setOnClickListener(view -> { + editText.setHint(R.string.settings_tab_title); + editText.setText(tab3CurrentTitle); + editText.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + if (dialogView.getParent() != null) { + ((ViewGroup) dialogView.getParent()).removeView(dialogView); + } + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_title) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + tab3CurrentTitle = editText.getText().toString(); + sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_TITLE, tab3CurrentTitle).apply(); + tab3TitleSummaryTextView.setText(tab3CurrentTitle); + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .show(); + }); + + tab3TypeLinearLayout.setOnClickListener(view -> { + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.settings_tab_title) + .setSingleChoiceItems(typeValues, tab3CurrentPostType, (dialogInterface, i) -> { + tab3CurrentPostType = i; + sharedPreferences.edit().putInt((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_POST_TYPE, i).apply(); + tab3TypeSummaryTextView.setText(typeValues[i]); + applyTab3NameView(tab3NameLinearLayout, tab3NameTitleTextView, i); + dialogInterface.dismiss(); + }) + .setNegativeButton(R.string.cancel, null) + .show(); + }); + + tab3NameLinearLayout.setOnClickListener(view -> { + int titleId; + switch (tab3CurrentPostType) { + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: + titleId = R.string.settings_tab_subreddit_name; + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: + titleId = R.string.settings_tab_multi_reddit_name; + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: + titleId = R.string.settings_tab_username; + break; + default: + return; + } + editText.setText(tab3CurrentName); + editText.setHint(titleId); + editText.requestFocus(); + InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + if (dialogView.getParent() != null) { + ((ViewGroup) dialogView.getParent()).removeView(dialogView); + } + new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) + .setTitle(titleId) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + tab3CurrentName = editText.getText().toString(); + sharedPreferences.edit().putString((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_TAB_3_NAME, tab3CurrentName).apply(); + tab3NameSummaryTextView.setText(tab3CurrentName); + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); + } + }) + .show(); + }); + + showSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, false)); + showSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS, b).apply()); + showSubscribedSubredditsLinearLayout.setOnClickListener(view -> { + showSubscribedSubredditsSwitchMaterial.performClick(); + }); + + showFavoriteSubscribedSubredditsSwitchMaterial.setChecked(sharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, false)); + showFavoriteSubscribedSubredditsSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> sharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS, b).apply()); + showFavoriteSubscribedSubredditsLinearLayout.setOnClickListener(view -> { + showFavoriteSubscribedSubredditsSwitchMaterial.performClick(); + }); + + return rootView; + } + + private void applyTab1NameView(LinearLayout linearLayout, TextView titleTextView, int postType) { + switch (postType) { + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_subreddit_name); + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_multi_reddit_name); + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_username); + break; + default: + linearLayout.setVisibility(View.GONE); + } + } + + private void applyTab2NameView(LinearLayout linearLayout, TextView titleTextView, int postType) { + switch (postType) { + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_subreddit_name); + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_multi_reddit_name); + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_username); + break; + default: + linearLayout.setVisibility(View.GONE); + } + } + + private void applyTab3NameView(LinearLayout linearLayout, TextView titleTextView, int postType) { + switch (postType) { + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_subreddit_name); + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_multi_reddit_name); + break; + case SharedPreferencesUtils.MAIN_PAGE_TAB_POST_TYPE_USER: + linearLayout.setVisibility(View.VISIBLE); + titleTextView.setText(R.string.settings_tab_username); + break; + default: + linearLayout.setVisibility(View.GONE); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/DataSavingModePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/DataSavingModePreferenceFragment.java new file mode 100644 index 00000000..652e737f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/DataSavingModePreferenceFragment.java @@ -0,0 +1,39 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.os.Bundle; + +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import ml.docilealligator.infinityforreddit.events.ChangeDataSavingModeEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDisableImagePreviewEvent; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class DataSavingModePreferenceFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.data_saving_mode_preferences, rootKey); + + ListPreference dataSavingModeListPreference = findPreference(SharedPreferencesUtils.DATA_SAVING_MODE); + SwitchPreference disableImagePreviewPreference = findPreference(SharedPreferencesUtils.DISABLE_IMAGE_PREVIEW); + + if (dataSavingModeListPreference != null) { + dataSavingModeListPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeDataSavingModeEvent((String) newValue)); + return true; + }); + } + + if (disableImagePreviewPreference != null) { + disableImagePreviewPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeDisableImagePreviewEvent((Boolean) newValue)); + return true; + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/DownloadLocationPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/DownloadLocationPreferenceFragment.java new file mode 100644 index 00000000..633cd581 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/DownloadLocationPreferenceFragment.java @@ -0,0 +1,118 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE; + +public class DownloadLocationPreferenceFragment extends PreferenceFragmentCompat { + private static final int IMAGE_DOWNLOAD_LOCATION_REQUEST_CODE = 10; + private static final int GIF_DOWNLOAD_LOCATION_REQUEST_CODE = 11; + private static final int VIDEO_DOWNLOAD_LOCATION_REQUEST_CODE = 12; + + Preference imageDownloadLocationPreference; + Preference gifDownloadLocationPreference; + Preference videoDownloadLocationPreference; + private Activity activity; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + setPreferencesFromResource(R.xml.download_location_preferences, rootKey); + imageDownloadLocationPreference = findPreference(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION); + gifDownloadLocationPreference = findPreference(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION); + videoDownloadLocationPreference = findPreference(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION); + + if (imageDownloadLocationPreference != null) { + String downloadLocation = sharedPreferences.getString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, ""); + if (!downloadLocation.equals("")) { + imageDownloadLocationPreference.setSummary(downloadLocation); + } + + imageDownloadLocationPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(ACTION_OPEN_DOCUMENT_TREE); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + startActivityForResult(intent, IMAGE_DOWNLOAD_LOCATION_REQUEST_CODE); + return true; + }); + } + + if (gifDownloadLocationPreference != null) { + String downloadLocation = sharedPreferences.getString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, ""); + if (!downloadLocation.equals("")) { + gifDownloadLocationPreference.setSummary(downloadLocation); + } + + gifDownloadLocationPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(ACTION_OPEN_DOCUMENT_TREE); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + startActivityForResult(intent, GIF_DOWNLOAD_LOCATION_REQUEST_CODE); + return true; + }); + } + + if (videoDownloadLocationPreference != null) { + String downloadLocation = sharedPreferences.getString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, ""); + if (!downloadLocation.equals("")) { + videoDownloadLocationPreference.setSummary(downloadLocation); + } + + videoDownloadLocationPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(ACTION_OPEN_DOCUMENT_TREE); + intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + startActivityForResult(intent, VIDEO_DOWNLOAD_LOCATION_REQUEST_CODE); + return true; + }); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (resultCode == Activity.RESULT_OK && data != null && data.getData() != null) { + if (requestCode == IMAGE_DOWNLOAD_LOCATION_REQUEST_CODE) { + activity.getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + sharedPreferences.edit().putString(SharedPreferencesUtils.IMAGE_DOWNLOAD_LOCATION, data.getDataString()).apply(); + if (imageDownloadLocationPreference != null) { + imageDownloadLocationPreference.setSummary(data.getDataString()); + } + } else if (requestCode == GIF_DOWNLOAD_LOCATION_REQUEST_CODE) { + activity.getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + sharedPreferences.edit().putString(SharedPreferencesUtils.GIF_DOWNLOAD_LOCATION, data.getDataString()).apply(); + if (gifDownloadLocationPreference != null) { + gifDownloadLocationPreference.setSummary(data.getDataString()); + } + } else if (requestCode == VIDEO_DOWNLOAD_LOCATION_REQUEST_CODE) { + activity.getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + sharedPreferences.edit().putString(SharedPreferencesUtils.VIDEO_DOWNLOAD_LOCATION, data.getDataString()).apply(); + if (videoDownloadLocationPreference != null) { + videoDownloadLocationPreference.setSummary(data.getDataString()); + } + } + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FilterPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FilterPreferenceFragment.java new file mode 100644 index 00000000..91f40c98 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FilterPreferenceFragment.java @@ -0,0 +1,38 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import ml.docilealligator.infinityforreddit.activities.SubredditFilterPopularAndAllActivity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class FilterPreferenceFragment extends PreferenceFragmentCompat { + + private Activity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.filter_preferences, rootKey); + + Preference subredditFilterPopularAndAllPreference = findPreference(SharedPreferencesUtils.SUBREDDIT_FILTER_POPULAR_AND_ALL); + + subredditFilterPopularAndAllPreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, SubredditFilterPopularAndAllActivity.class); + activity.startActivity(intent); + return true; + }); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java new file mode 100644 index 00000000..2d608ca5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreferenceFragment.java @@ -0,0 +1,80 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; + +import org.greenrobot.eventbus.EventBus; + +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class FontPreferenceFragment extends PreferenceFragmentCompat { + private Activity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.font_preferences, rootKey); + ListPreference fontFamilyPreference = findPreference(SharedPreferencesUtils.FONT_FAMILY_KEY); + ListPreference titleFontFamilyPreference = findPreference(SharedPreferencesUtils.TITLE_FONT_FAMILY_KEY); + ListPreference contentFontFamilyPreference = findPreference(SharedPreferencesUtils.CONTENT_FONT_FAMILY_KEY); + ListPreference fontSizePreference = findPreference(SharedPreferencesUtils.FONT_SIZE_KEY); + ListPreference titleFontSizePreference = findPreference(SharedPreferencesUtils.TITLE_FONT_SIZE_KEY); + ListPreference contentFontSizePreference = findPreference(SharedPreferencesUtils.CONTENT_FONT_SIZE_KEY); + + if (fontFamilyPreference != null) { + fontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + activity.recreate(); + return true; + }); + } + + if (titleFontFamilyPreference != null) { + titleFontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + } + + if (contentFontFamilyPreference != null) { + contentFontFamilyPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + } + + if (fontSizePreference != null) { + fontSizePreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + activity.recreate(); + return true; + }); + } + + if (titleFontSizePreference != null) { + titleFontSizePreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + } + + if (contentFontSizePreference != null) { + contentFontSizePreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreviewFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreviewFragment.java new file mode 100644 index 00000000..ef4b96eb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/FontPreviewFragment.java @@ -0,0 +1,29 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.fragment.app.Fragment; + +import ml.docilealligator.infinityforreddit.R; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link FontPreviewFragment#newInstance} factory method to + * create an instance of this fragment. + */ +public class FontPreviewFragment extends Fragment { + + public FontPreviewFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_font_preview, container, false); + return rootView; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java new file mode 100644 index 00000000..cd151ad3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/GesturesAndButtonsPreferenceFragment.java @@ -0,0 +1,88 @@ +package ml.docilealligator.infinityforreddit.settings; + + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.events.ChangeLockBottomAppBarEvent; +import ml.docilealligator.infinityforreddit.fragments.ChangePullToRefreshEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +/** + * A simple {@link Fragment} subclass. + */ +public class GesturesAndButtonsPreferenceFragment extends PreferenceFragmentCompat { + + @Inject + @Named("default") + SharedPreferences sharedPreferences; + private Activity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.gestures_and_buttons_preference, rootKey); + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + SwitchPreference lockJumpToNextTopLevelCommentButtonSwitch = + findPreference(SharedPreferencesUtils.LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON); + SwitchPreference lockBottomAppBarSwitch = findPreference(SharedPreferencesUtils.LOCK_BOTTOM_APP_BAR); + SwitchPreference swipeUpToHideJumpToNextTopLevelCommentButtonSwitch = + findPreference(SharedPreferencesUtils.SWIPE_UP_TO_HIDE_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON); + SwitchPreference pullToRefreshSwitch = findPreference(SharedPreferencesUtils.PULL_TO_REFRESH); + + if (lockJumpToNextTopLevelCommentButtonSwitch != null && lockBottomAppBarSwitch != null && + swipeUpToHideJumpToNextTopLevelCommentButtonSwitch != null) { + lockJumpToNextTopLevelCommentButtonSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + if ((Boolean) newValue) { + swipeUpToHideJumpToNextTopLevelCommentButtonSwitch.setVisible(false); + } else { + swipeUpToHideJumpToNextTopLevelCommentButtonSwitch.setVisible(true); + } + return true; + }); + + if (sharedPreferences.getBoolean(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY, false)) { + lockBottomAppBarSwitch.setVisible(true); + lockBottomAppBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeLockBottomAppBarEvent((Boolean) newValue)); + return true; + }); + } + + if (!sharedPreferences.getBoolean(SharedPreferencesUtils.LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON, false)) { + swipeUpToHideJumpToNextTopLevelCommentButtonSwitch.setVisible(true); + } + } + + if (pullToRefreshSwitch != null) { + pullToRefreshSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + EventBus.getDefault().post(new ChangePullToRefreshEvent((Boolean) newValue)); + return true; + } + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ImmersiveInterfacePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ImmersiveInterfacePreferenceFragment.java new file mode 100644 index 00000000..785721cb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ImmersiveInterfacePreferenceFragment.java @@ -0,0 +1,46 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.os.Bundle; + +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class ImmersiveInterfacePreferenceFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.immersive_interface_preferences, rootKey); + + SwitchPreference immersiveInterfaceSwitch = findPreference(SharedPreferencesUtils.IMMERSIVE_INTERFACE_KEY); + SwitchPreference immersiveInterfaceIgnoreNavBarSwitch = findPreference(SharedPreferencesUtils.IMMERSIVE_INTERFACE_IGNORE_NAV_BAR_KEY); + + if (immersiveInterfaceSwitch != null && immersiveInterfaceIgnoreNavBarSwitch != null) { + immersiveInterfaceSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + if ((Boolean) newValue) { + immersiveInterfaceIgnoreNavBarSwitch.setVisible(true); + } else { + immersiveInterfaceIgnoreNavBarSwitch.setVisible(false); + } + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + + if (immersiveInterfaceSwitch.isChecked()) { + immersiveInterfaceIgnoreNavBarSwitch.setVisible(true); + } else { + immersiveInterfaceIgnoreNavBarSwitch.setVisible(false); + } + + immersiveInterfaceIgnoreNavBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/InterfacePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/InterfacePreferenceFragment.java new file mode 100644 index 00000000..e873f8ba --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/InterfacePreferenceFragment.java @@ -0,0 +1,101 @@ +package ml.docilealligator.infinityforreddit.settings; + + +import android.os.Build; +import android.os.Bundle; + +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import ml.docilealligator.infinityforreddit.events.ChangeCompactLayoutToolbarHiddenByDefaultEvent; +import ml.docilealligator.infinityforreddit.events.ChangeDefaultPostLayoutEvent; +import ml.docilealligator.infinityforreddit.events.ChangeLongPressToHideToolbarInCompactLayoutEvent; +import ml.docilealligator.infinityforreddit.events.ChangeShowAbsoluteNumberOfVotesEvent; +import ml.docilealligator.infinityforreddit.events.ChangeVoteButtonsPositionEvent; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.events.ShowDividerInCompactLayoutPreferenceEvent; +import ml.docilealligator.infinityforreddit.events.ShowThumbnailOnTheRightInCompactLayoutEvent; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class InterfacePreferenceFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.interface_preference, rootKey); + + Preference immersiveInterfaceEntryPreference = findPreference(SharedPreferencesUtils.IMMERSIVE_INTERFACE_ENTRY_KEY); + SwitchPreference bottomAppBarSwitch = findPreference(SharedPreferencesUtils.BOTTOM_APP_BAR_KEY); + SwitchPreference voteButtonsOnTheRightSwitch = findPreference(SharedPreferencesUtils.VOTE_BUTTONS_ON_THE_RIGHT_KEY); + ListPreference defaultPostLayoutSwitch = findPreference(SharedPreferencesUtils.DEFAULT_POST_LAYOUT_KEY); + SwitchPreference showDividerInCompactLayout = findPreference(SharedPreferencesUtils.SHOW_DIVIDER_IN_COMPACT_LAYOUT); + SwitchPreference showThumbnailOnTheRightInCompactLayout = findPreference(SharedPreferencesUtils.SHOW_THUMBNAIL_ON_THE_LEFT_IN_COMPACT_LAYOUT); + SwitchPreference showAbsoluteNumberOfVotes = findPreference(SharedPreferencesUtils.SHOW_ABSOLUTE_NUMBER_OF_VOTES); + SwitchPreference longPressToHideToolbarInCompactLayoutSwitch = findPreference(SharedPreferencesUtils.LONG_PRESS_TO_HIDE_TOOLBAR_IN_COMPACT_LAYOUT); + SwitchPreference postCompactLayoutToolbarHiddenByDefaultSwitch = findPreference(SharedPreferencesUtils.POST_COMPACT_LAYOUT_TOOLBAR_HIDDEN_BY_DEFAULT); + + if (immersiveInterfaceEntryPreference != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + immersiveInterfaceEntryPreference.setVisible(true); + } + + if (bottomAppBarSwitch != null) { + bottomAppBarSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + } + + if (voteButtonsOnTheRightSwitch != null) { + voteButtonsOnTheRightSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeVoteButtonsPositionEvent((Boolean) newValue)); + return true; + }); + } + + if (defaultPostLayoutSwitch != null) { + defaultPostLayoutSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeDefaultPostLayoutEvent(Integer.parseInt((String) newValue))); + return true; + }); + } + + if (showDividerInCompactLayout != null) { + showDividerInCompactLayout.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ShowDividerInCompactLayoutPreferenceEvent((Boolean) newValue)); + return true; + }); + } + + if (showThumbnailOnTheRightInCompactLayout != null) { + showThumbnailOnTheRightInCompactLayout.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ShowThumbnailOnTheRightInCompactLayoutEvent((Boolean) newValue)); + return true; + }); + } + + if (showAbsoluteNumberOfVotes != null) { + showAbsoluteNumberOfVotes.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeShowAbsoluteNumberOfVotesEvent((Boolean) newValue)); + return true; + }); + } + + if (longPressToHideToolbarInCompactLayoutSwitch != null) { + longPressToHideToolbarInCompactLayoutSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeLongPressToHideToolbarInCompactLayoutEvent((Boolean) newValue)); + return true; + }); + } + + if (postCompactLayoutToolbarHiddenByDefaultSwitch != null) { + postCompactLayoutToolbarHiddenByDefaultSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeCompactLayoutToolbarHiddenByDefaultEvent((Boolean) newValue)); + return true; + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/MainPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/MainPreferenceFragment.java new file mode 100644 index 00000000..e9adbe8b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/MainPreferenceFragment.java @@ -0,0 +1,51 @@ +package ml.docilealligator.infinityforreddit.settings; + + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.biometric.BiometricManager; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; +import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; + +public class MainPreferenceFragment extends PreferenceFragmentCompat { + + @Inject + @Named("default") + SharedPreferences sharedPreferences; + private AppCompatActivity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.main_preferences, rootKey); + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + Preference securityPreference = findPreference(SharedPreferencesUtils.SECURITY); + + BiometricManager biometricManager = BiometricManager.from(activity); + if (biometricManager.canAuthenticate(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) != BiometricManager.BIOMETRIC_SUCCESS) { + if (securityPreference != null) { + securityPreference.setVisible(false); + } + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (AppCompatActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/MiscellaneousPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/MiscellaneousPreferenceFragment.java new file mode 100644 index 00000000..c27e7eec --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/MiscellaneousPreferenceFragment.java @@ -0,0 +1,67 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.events.ChangeSavePostFeedScrolledPositionEvent; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class MiscellaneousPreferenceFragment extends PreferenceFragmentCompat { + + @Inject + @Named("post_feed_scrolled_position_cache") + SharedPreferences cache; + private Activity activity; + + public MiscellaneousPreferenceFragment() { + // Required empty public constructor + } + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.miscellaneous_preferences, rootKey); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + SwitchPreference confirmToExitSwitch = findPreference(SharedPreferencesUtils.CONFIRM_TO_EXIT); + SwitchPreference savePostFeedScrolledPositionSwitch = findPreference(SharedPreferencesUtils.SAVE_FRONT_PAGE_SCROLLED_POSITION); + + if (confirmToExitSwitch != null) { + confirmToExitSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new RecreateActivityEvent()); + return true; + }); + } + + if (savePostFeedScrolledPositionSwitch != null) { + savePostFeedScrolledPositionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + if (!(Boolean) newValue) { + cache.edit().clear().apply(); + } + EventBus.getDefault().post(new ChangeSavePostFeedScrolledPositionEvent((Boolean) newValue)); + return true; + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (AppCompatActivity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java new file mode 100644 index 00000000..cf014c49 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NotificationPreferenceFragment.java @@ -0,0 +1,127 @@ +package ml.docilealligator.infinityforreddit.settings; + + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; +import androidx.work.Constraints; +import androidx.work.ExistingPeriodicWorkPolicy; +import androidx.work.NetworkType; +import androidx.work.PeriodicWorkRequest; +import androidx.work.WorkManager; + +import java.util.concurrent.TimeUnit; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.PullNotificationWorker; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +/** + * A simple {@link Fragment} subclass. + */ +public class NotificationPreferenceFragment extends PreferenceFragmentCompat { + + @Inject + @Named("default") + SharedPreferences sharedPreferences; + private boolean enableNotification; + private long notificationInterval; + private WorkManager workManager; + private Activity activity; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.notification_preferences, rootKey); + + workManager = WorkManager.getInstance(activity); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + SwitchPreference enableNotificationSwitchPreference = findPreference(SharedPreferencesUtils.ENABLE_NOTIFICATION_KEY); + ListPreference notificationIntervalListPreference = findPreference(SharedPreferencesUtils.NOTIFICATION_INTERVAL_KEY); + + enableNotification = sharedPreferences.getBoolean(SharedPreferencesUtils.ENABLE_NOTIFICATION_KEY, true); + notificationInterval = Long.parseLong(sharedPreferences.getString(SharedPreferencesUtils.NOTIFICATION_INTERVAL_KEY, "1")); + + if (enableNotification) { + if (notificationIntervalListPreference != null) { + notificationIntervalListPreference.setVisible(true); + } + } + + if (enableNotificationSwitchPreference != null) { + enableNotificationSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { + enableNotification = ((Boolean) newValue); + if (notificationIntervalListPreference != null) { + notificationIntervalListPreference.setVisible(enableNotification); + } + + if (enableNotification) { + TimeUnit timeUnit = (notificationInterval == 15 || notificationInterval == 30) ? TimeUnit.MINUTES : TimeUnit.HOURS; + + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + PeriodicWorkRequest pullNotificationRequest = + new PeriodicWorkRequest.Builder(PullNotificationWorker.class, + notificationInterval, timeUnit) + .setConstraints(constraints) + .setInitialDelay(notificationInterval, timeUnit) + .build(); + + workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, + ExistingPeriodicWorkPolicy.REPLACE, pullNotificationRequest); + } else { + workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); + } + return true; + }); + } + + if (notificationIntervalListPreference != null) { + notificationIntervalListPreference.setOnPreferenceChangeListener((preference, newValue) -> { + notificationInterval = Long.parseLong((String) newValue); + + if (enableNotification) { + TimeUnit timeUnit = (notificationInterval == 15 || notificationInterval == 30) ? TimeUnit.MINUTES : TimeUnit.HOURS; + + Constraints constraints = new Constraints.Builder() + .setRequiredNetworkType(NetworkType.CONNECTED) + .build(); + + PeriodicWorkRequest pullNotificationRequest = + new PeriodicWorkRequest.Builder(PullNotificationWorker.class, + notificationInterval, timeUnit) + .setConstraints(constraints) + .setInitialDelay(notificationInterval, timeUnit) + .build(); + + workManager.enqueueUniquePeriodicWork(PullNotificationWorker.UNIQUE_WORKER_NAME, + ExistingPeriodicWorkPolicy.REPLACE, pullNotificationRequest); + } else { + workManager.cancelUniqueWork(PullNotificationWorker.UNIQUE_WORKER_NAME); + } + + return true; + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NsfwAndBlurringFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NsfwAndBlurringFragment.java new file mode 100644 index 00000000..a4373a70 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NsfwAndBlurringFragment.java @@ -0,0 +1,112 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.fragment.app.Fragment; + +import com.google.android.material.switchmaterial.SwitchMaterial; + +import org.greenrobot.eventbus.EventBus; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWBlurEvent; +import ml.docilealligator.infinityforreddit.events.ChangeNSFWEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSpoilerBlurEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class NsfwAndBlurringFragment extends Fragment { + + public static final String EXTRA_ACCOUNT_NAME = "EAN"; + + @BindView(R.id.enable_nsfw_linear_layout_nsfw_and_spoiler_fragment) + LinearLayout enableNsfwLinearLayout; + @BindView(R.id.enable_nsfw_switch_nsfw_and_spoiler_fragment) + SwitchMaterial enableNsfwSwitchMaterial; + @BindView(R.id.blur_nsfw_linear_layout_nsfw_and_spoiler_fragment) + LinearLayout blurNsfwLinearLayout; + @BindView(R.id.blur_nsfw_switch_nsfw_and_spoiler_fragment) + SwitchMaterial blurNsfwSwitchMaterial; + @BindView(R.id.blur_spoiler_linear_layout_nsfw_and_spoiler_fragment) + LinearLayout blurSpoilerLinearLayout; + @BindView(R.id.blur_spoiler_switch_nsfw_and_spoiler_fragment) + SwitchMaterial blurSpoilerSwitchMaterial; + @Inject + @Named("nsfw_and_spoiler") + SharedPreferences nsfwAndBlurringSharedPreferences; + + private Activity activity; + + public NsfwAndBlurringFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_nsfw_and_spoiler, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + String accountName = getArguments().getString(EXTRA_ACCOUNT_NAME); + + boolean enableNsfw = nsfwAndBlurringSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, false); + boolean blurNsfw = nsfwAndBlurringSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, true); + boolean blurSpoiler = nsfwAndBlurringSharedPreferences.getBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_SPOILER_BASE, false); + + if (enableNsfw) { + blurNsfwLinearLayout.setVisibility(View.VISIBLE); + } + + enableNsfwSwitchMaterial.setChecked(enableNsfw); + blurNsfwSwitchMaterial.setChecked(blurNsfw); + blurSpoilerSwitchMaterial.setChecked(blurSpoiler); + + enableNsfwLinearLayout.setOnClickListener(view -> enableNsfwSwitchMaterial.performClick()); + enableNsfwSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> { + nsfwAndBlurringSharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.NSFW_BASE, b).apply(); + if (b) { + blurNsfwLinearLayout.setVisibility(View.VISIBLE); + } else { + blurNsfwLinearLayout.setVisibility(View.GONE); + } + EventBus.getDefault().post(new ChangeNSFWEvent(b)); + }); + + blurNsfwLinearLayout.setOnClickListener(view -> blurNsfwSwitchMaterial.performClick()); + blurNsfwSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> { + nsfwAndBlurringSharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_NSFW_BASE, b).apply(); + EventBus.getDefault().post(new ChangeNSFWBlurEvent(b)); + }); + + blurSpoilerLinearLayout.setOnClickListener(view -> blurSpoilerSwitchMaterial.performClick()); + blurSpoilerSwitchMaterial.setOnCheckedChangeListener((compoundButton, b) -> { + nsfwAndBlurringSharedPreferences.edit().putBoolean((accountName == null ? "" : accountName) + SharedPreferencesUtils.BLUR_SPOILER_BASE, b).apply(); + EventBus.getDefault().post(new ChangeSpoilerBlurEvent(b)); + }); + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (AppCompatActivity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NumberOfColumnsInPostFeedPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NumberOfColumnsInPostFeedPreferenceFragment.java new file mode 100644 index 00000000..dfb991dd --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/NumberOfColumnsInPostFeedPreferenceFragment.java @@ -0,0 +1,14 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.os.Bundle; + +import androidx.preference.PreferenceFragmentCompat; + +import ml.docilealligator.infinityforreddit.R; + +public class NumberOfColumnsInPostFeedPreferenceFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.number_of_columns_in_post_feed_preferences, rootKey); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java new file mode 100644 index 00000000..cb6917c8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SecurityPreferenceFragment.java @@ -0,0 +1,77 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.biometric.BiometricPrompt; +import androidx.core.content.ContextCompat; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.events.ChangeRequireAuthToAccountSectionEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; +import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; + +public class SecurityPreferenceFragment extends PreferenceFragmentCompat { + + private AppCompatActivity activity; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.security_preferences, rootKey); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + SwitchPreference requireAuthToAccountSectionSwitch = findPreference(SharedPreferencesUtils.REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER); + + if (requireAuthToAccountSectionSwitch != null) { + requireAuthToAccountSectionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeRequireAuthToAccountSectionEvent((Boolean) newValue)); + return true; + }); + } + } + + @Override + public void onResume() { + super.onResume(); + Executor executor = ContextCompat.getMainExecutor(activity); + BiometricPrompt biometricPrompt = new BiometricPrompt(SecurityPreferenceFragment.this, + executor, new BiometricPrompt.AuthenticationCallback() { + @Override + public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) { + activity.onBackPressed(); + } + }); + + BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder() + .setTitle(activity.getString(R.string.unlock)) + .setAllowedAuthenticators(BIOMETRIC_STRONG | DEVICE_CREDENTIAL) + .build(); + + biometricPrompt.authenticate(promptInfo); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (AppCompatActivity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SwipeActionPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SwipeActionPreferenceFragment.java new file mode 100644 index 00000000..de7860b5 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/SwipeActionPreferenceFragment.java @@ -0,0 +1,82 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.os.Bundle; + +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import ml.docilealligator.infinityforreddit.events.ChangeDisableSwipingBetweenTabsEvent; +import ml.docilealligator.infinityforreddit.events.ChangeEnableSwipeActionSwitchEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSwipeActionEvent; +import ml.docilealligator.infinityforreddit.events.ChangeSwipeActionThresholdEvent; +import ml.docilealligator.infinityforreddit.events.ChangeVibrateWhenActionTriggeredEvent; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class SwipeActionPreferenceFragment extends PreferenceFragmentCompat { + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.swipe_action_preferences, rootKey); + + SwitchPreference enableSwipeActionSwitch = findPreference(SharedPreferencesUtils.ENABLE_SWIPE_ACTION); + ListPreference swipeLeftActionListPreference = findPreference(SharedPreferencesUtils.SWIPE_LEFT_ACTION); + ListPreference swipeRightActionListPreference = findPreference(SharedPreferencesUtils.SWIPE_RIGHT_ACTION); + SwitchPreference vibrateWhenActionTriggeredSwitch = findPreference(SharedPreferencesUtils.VIBRATE_WHEN_ACTION_TRIGGERED); + SwitchPreference disableSwipingBetweenTabsSwitch = findPreference(SharedPreferencesUtils.DISABLE_SWIPING_BETWEEN_TABS); + ListPreference swipeActionThresholdListPreference = findPreference(SharedPreferencesUtils.SWIPE_ACTION_THRESHOLD); + + if (enableSwipeActionSwitch != null) { + enableSwipeActionSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeEnableSwipeActionSwitchEvent((Boolean) newValue)); + return true; + }); + } + + if (swipeLeftActionListPreference != null) { + swipeLeftActionListPreference.setOnPreferenceChangeListener((preference, newValue) -> { + if (swipeRightActionListPreference != null) { + EventBus.getDefault().post(new ChangeSwipeActionEvent(Integer.parseInt((String) newValue), Integer.parseInt(swipeRightActionListPreference.getValue()))); + } else { + EventBus.getDefault().post(new ChangeSwipeActionEvent(Integer.parseInt((String) newValue), -1)); + } + return true; + }); + } + + if (swipeRightActionListPreference != null) { + swipeRightActionListPreference.setOnPreferenceChangeListener((preference, newValue) -> { + if (swipeLeftActionListPreference != null) { + EventBus.getDefault().post(new ChangeSwipeActionEvent(Integer.parseInt(swipeLeftActionListPreference.getValue()), Integer.parseInt((String) newValue))); + } else { + EventBus.getDefault().post(new ChangeSwipeActionEvent(-1, Integer.parseInt((String) newValue))); + } + return true; + }); + } + + if (vibrateWhenActionTriggeredSwitch != null) { + vibrateWhenActionTriggeredSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeVibrateWhenActionTriggeredEvent((Boolean) newValue)); + return true; + }); + } + + if (disableSwipingBetweenTabsSwitch != null) { + disableSwipingBetweenTabsSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeDisableSwipingBetweenTabsEvent((Boolean) newValue)); + return true; + }); + } + + if (swipeActionThresholdListPreference != null) { + swipeActionThresholdListPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeSwipeActionThresholdEvent(Float.parseFloat((String) newValue))); + return true; + }); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java new file mode 100644 index 00000000..e28cd52f --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/ThemePreferenceFragment.java @@ -0,0 +1,193 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; +import androidx.fragment.app.Fragment; +import androidx.lifecycle.ViewModelProvider; +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import javax.inject.Inject; + +import ml.docilealligator.infinityforreddit.activities.CustomThemeListingActivity; +import ml.docilealligator.infinityforreddit.activities.CustomizeThemeActivity; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeViewModel; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.utils.CustomThemeSharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_BATTERY; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; +import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES; + +/** + * A simple {@link Fragment} subclass. + */ +public class ThemePreferenceFragment extends PreferenceFragmentCompat { + + private AppCompatActivity activity; + @Inject + RedditDataRoomDatabase redditDataRoomDatabase; + @Inject + CustomThemeWrapper customThemeWrapper; + public CustomThemeViewModel customThemeViewModel; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.theme_preferences, rootKey); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ListPreference themePreference = findPreference(SharedPreferencesUtils.THEME_KEY); + SwitchPreference amoledDarkSwitch = findPreference(SharedPreferencesUtils.AMOLED_DARK_KEY); + Preference customizeLightThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_LIGHT_THEME); + Preference customizeDarkThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_DARK_THEME); + Preference customizeAmoledThemePreference = findPreference(SharedPreferencesUtils.CUSTOMIZE_AMOLED_THEME); + Preference selectAndCustomizeThemePreference = findPreference(SharedPreferencesUtils.MANAGE_THEMES); + + boolean systemDefault = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q; + if (themePreference != null && amoledDarkSwitch != null) { + if (systemDefault) { + themePreference.setEntries(R.array.settings_theme_q); + } else { + themePreference.setEntries(R.array.settings_theme); + } + + themePreference.setOnPreferenceChangeListener((preference, newValue) -> { + int option = Integer.parseInt((String) newValue); + switch (option) { + case 0: + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO); + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); + break; + case 1: + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES); + if (amoledDarkSwitch.isChecked()) { + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); + } else { + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); + } + break; + case 2: + if (systemDefault) { + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_FOLLOW_SYSTEM); + } else { + AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_AUTO_BATTERY); + } + + if((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_NO) { + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.LIGHT); + } else { + if (amoledDarkSwitch.isChecked()) { + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.AMOLED); + } else { + customThemeWrapper.setThemeType(CustomThemeSharedPreferencesUtils.DARK); + } + } + } + return true; + }); + } + + if (amoledDarkSwitch != null) { + amoledDarkSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + if ((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_NO) { + EventBus.getDefault().post(new RecreateActivityEvent()); + activity.recreate(); + } + return true; + }); + } + + if (customizeLightThemePreference != null) { + customizeLightThemePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_TYPE, CustomizeThemeActivity.EXTRA_LIGHT_THEME); + startActivity(intent); + return true; + }); + } + + if (customizeDarkThemePreference != null) { + customizeDarkThemePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_TYPE, CustomizeThemeActivity.EXTRA_DARK_THEME); + startActivity(intent); + return true; + }); + } + + if (customizeAmoledThemePreference != null) { + customizeAmoledThemePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, CustomizeThemeActivity.class); + intent.putExtra(CustomizeThemeActivity.EXTRA_THEME_TYPE, CustomizeThemeActivity.EXTRA_AMOLED_THEME); + startActivity(intent); + return true; + }); + } + + if (selectAndCustomizeThemePreference != null) { + selectAndCustomizeThemePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(activity, CustomThemeListingActivity.class); + startActivity(intent); + return true; + }); + } + + customThemeViewModel = new ViewModelProvider(this, + new CustomThemeViewModel.Factory(redditDataRoomDatabase)) + .get(CustomThemeViewModel.class); + customThemeViewModel.getCurrentLightThemeLiveData().observe(this, customTheme -> { + if (customizeLightThemePreference != null) { + if (customTheme != null) { + customizeLightThemePreference.setVisible(true); + customizeLightThemePreference.setSummary(customTheme.name); + } else { + customizeLightThemePreference.setVisible(false); + } + } + }); + customThemeViewModel.getCurrentDarkThemeLiveData().observe(this, customTheme -> { + if (customizeDarkThemePreference != null) { + if (customTheme != null) { + customizeDarkThemePreference.setVisible(true); + customizeDarkThemePreference.setSummary(customTheme.name); + } else { + customizeDarkThemePreference.setVisible(false); + } + } + }); + customThemeViewModel.getCurrentAmoledThemeLiveData().observe(this, customTheme -> { + if (customizeAmoledThemePreference != null) { + if (customTheme != null) { + customizeAmoledThemePreference.setVisible(true); + customizeAmoledThemePreference.setSummary(customTheme.name); + } else { + customizeAmoledThemePreference.setVisible(false); + } + } + }); + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (AppCompatActivity) context; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TimeFormatPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TimeFormatPreferenceFragment.java new file mode 100644 index 00000000..42ced176 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TimeFormatPreferenceFragment.java @@ -0,0 +1,38 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.os.Bundle; + +import androidx.preference.ListPreference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import ml.docilealligator.infinityforreddit.events.ChangeShowElapsedTimeEvent; +import ml.docilealligator.infinityforreddit.events.ChangeTimeFormatEvent; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class TimeFormatPreferenceFragment extends PreferenceFragmentCompat { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.time_format_preferences, rootKey); + + SwitchPreference showElapsedTimeSwitch = findPreference(SharedPreferencesUtils.SHOW_ELAPSED_TIME_KEY); + ListPreference timeFormatList = findPreference(SharedPreferencesUtils.TIME_FORMAT_KEY); + + if (showElapsedTimeSwitch != null) { + showElapsedTimeSwitch.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeShowElapsedTimeEvent((Boolean) newValue)); + return true; + }); + } + + if (timeFormatList != null) { + timeFormatList.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeTimeFormatEvent((String) newValue)); + return true; + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java new file mode 100644 index 00000000..d01c59b0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/Translation.java @@ -0,0 +1,44 @@ +package ml.docilealligator.infinityforreddit.settings; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.R; + +public class Translation { + public String language; + public String contributors; + public int flagDrawableId; + + public Translation(String language, String contributors, int flagDrawableId) { + this.language = language; + this.contributors = contributors; + this.flagDrawableId = flagDrawableId; + } + + public static ArrayList getTranslationContributors() { + ArrayList translationContributors = new ArrayList<>(); + translationContributors.add(new Translation("български", "Кристиян", R.drawable.flag_bulgaria)); + translationContributors.add(new Translation("简体中文", "cdggqa, Gloria, Justin, Steps", R.drawable.flag_china)); + translationContributors.add(new Translation("繁體中文", "", R.drawable.flag_china)); + translationContributors.add(new Translation("Hrvatski", "Josip", R.drawable.flag_croatia)); + translationContributors.add(new Translation("Nederlands", "Khawkfist", R.drawable.flag_netherlands)); + translationContributors.add(new Translation("Française", "367, Finn Olmsted, oursonbleu, Owen, pinembour", R.drawable.flag_france)); + translationContributors.add(new Translation("Deutsche", "Jorge, Netto Hikari, Nikodiamond3, translatewingman, translatorwiz", R.drawable.flag_germany)); + translationContributors.add(new Translation("Ελληνικά", "Marios, Viktor", R.drawable.flag_greece)); + translationContributors.add(new Translation("हिंदी", "a, Arya, charu, Mrigendra Bhandari, raghav, Sachin, Ved", R.drawable.flag_india)); + translationContributors.add(new Translation("Magyar", "Zoltan", R.drawable.flag_hungary)); + translationContributors.add(new Translation("Italiana", "Daniele Basso, DanOlivaw, Gianni00palmieri, Gillauino, Matisse, Simoneg. work, ztiaa", R.drawable.flag_italy)); + translationContributors.add(new Translation("日本語", "Hira, Issa, Mrigendra Bhandari, Ryan", R.drawable.flag_japan)); + translationContributors.add(new Translation("한국어", "noname", R.drawable.flag_south_korea)); + translationContributors.add(new Translation("norsk", "", R.drawable.flag_norway)); + translationContributors.add(new Translation("Português", "Bruno Guerreiro, Lucas, Ricky", R.drawable.flag_portugal)); + translationContributors.add(new Translation("Português (BR)", "Laura Vasconcellos Pereira Felippe, Ricky, Super_Iguanna", R.drawable.flag_brazil)); + translationContributors.add(new Translation("Română", "", R.drawable.flag_romania)); + translationContributors.add(new Translation("русский язык", "aveblazer, flexagoon, Georgiy, Vova", R.drawable.flag_russia)); + translationContributors.add(new Translation("Español", "Alejandro, Jorge, Miguel, mvstermoe, Nana Snixx, Sofia Flores", R.drawable.flag_spain)); + translationContributors.add(new Translation("svenska", "Marcus Nordberg", R.drawable.flag_sweden)); + translationContributors.add(new Translation("Türk", "Emir481, Faoiltiarna, Mehmet Yavuz, Serif", R.drawable.flag_turkey)); + translationContributors.add(new Translation("Tiếng Việt", "Kai, Laezzy, Lmao, Ryan, viecdet69", R.drawable.flag_vietnam)); + return translationContributors; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java new file mode 100644 index 00000000..a0f9cd1e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/TranslationFragment.java @@ -0,0 +1,58 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import javax.inject.Inject; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.adapters.TranslationFragmentRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; + +public class TranslationFragment extends Fragment { + + @BindView(R.id.recycler_view_translation_fragment) + RecyclerView recyclerView; + @Inject + CustomThemeWrapper customThemeWrapper; + private Activity activity; + + public TranslationFragment() { + // Required empty public constructor + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + View rootView = inflater.inflate(R.layout.fragment_translation, container, false); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ButterKnife.bind(this, rootView); + + TranslationFragmentRecyclerViewAdapter adapter = new TranslationFragmentRecyclerViewAdapter(activity, customThemeWrapper); + recyclerView.setLayoutManager(new LinearLayoutManager(activity)); + recyclerView.setAdapter(adapter); + + return rootView; + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + activity = (Activity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java new file mode 100644 index 00000000..f7941534 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/VideoPreferenceFragment.java @@ -0,0 +1,113 @@ +package ml.docilealligator.infinityforreddit.settings; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.os.Bundle; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.preference.ListPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SeekBarPreference; +import androidx.preference.SwitchPreference; + +import org.greenrobot.eventbus.EventBus; + +import javax.inject.Inject; +import javax.inject.Named; + +import ml.docilealligator.infinityforreddit.events.ChangeAutoplayNsfwVideosEvent; +import ml.docilealligator.infinityforreddit.events.ChangeMuteAutoplayingVideosEvent; +import ml.docilealligator.infinityforreddit.events.ChangeMuteNSFWVideoEvent; +import ml.docilealligator.infinityforreddit.events.ChangeStartAutoplayVisibleAreaOffsetEvent; +import ml.docilealligator.infinityforreddit.events.ChangeVideoAutoplayEvent; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class VideoPreferenceFragment extends PreferenceFragmentCompat { + + private Activity activity; + @Inject + @Named("default") + SharedPreferences sharedPreferences; + + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.video_preferences, rootKey); + + ((Infinity) activity.getApplication()).getAppComponent().inject(this); + + ListPreference videoAutoplayListPreference = findPreference(SharedPreferencesUtils.VIDEO_AUTOPLAY); + SwitchPreference muteAutoplayingVideosSwitchPreference = findPreference(SharedPreferencesUtils.MUTE_AUTOPLAYING_VIDEOS); + SwitchPreference muteNSFWVideosSwitchPreference = findPreference(SharedPreferencesUtils.MUTE_NSFW_VIDEO); + SwitchPreference autoplayNsfwVideosSwitchPreference = findPreference(SharedPreferencesUtils.AUTOPLAY_NSFW_VIDEOS); + SeekBarPreference startAutoplayVisibleAreaOffsetPortrait = findPreference(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT); + SeekBarPreference startAutoplayVisibleAreaOffsetLandscape = findPreference(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_LANDSCAPE); + + if (videoAutoplayListPreference != null && autoplayNsfwVideosSwitchPreference != null) { + videoAutoplayListPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeVideoAutoplayEvent((String) newValue)); + return true; + }); + + autoplayNsfwVideosSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeAutoplayNsfwVideosEvent((Boolean) newValue)); + return true; + }); + } + + if (muteNSFWVideosSwitchPreference != null) { + muteNSFWVideosSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeMuteNSFWVideoEvent((Boolean) newValue)); + return true; + }); + } + + if (muteAutoplayingVideosSwitchPreference != null) { + muteAutoplayingVideosSwitchPreference.setOnPreferenceChangeListener((preference, newValue) -> { + EventBus.getDefault().post(new ChangeMuteAutoplayingVideosEvent((Boolean) newValue)); + return true; + }); + } + + int orientation = getResources().getConfiguration().orientation; + + if (startAutoplayVisibleAreaOffsetPortrait != null) { + startAutoplayVisibleAreaOffsetPortrait.setSummary( + getString(R.string.settings_start_autoplay_visible_area_offset_portrait_summary, + sharedPreferences.getInt(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT, 75))); + startAutoplayVisibleAreaOffsetPortrait.setOnPreferenceChangeListener((Preference.OnPreferenceChangeListener) (preference, newValue) -> { + if (orientation == Configuration.ORIENTATION_PORTRAIT) { + EventBus.getDefault().post(new ChangeStartAutoplayVisibleAreaOffsetEvent((Integer) newValue)); + } + startAutoplayVisibleAreaOffsetPortrait.setSummary( + getString(R.string.settings_start_autoplay_visible_area_offset_portrait_summary, (Integer) newValue)); + return true; + }); + } + + if (startAutoplayVisibleAreaOffsetLandscape != null) { + startAutoplayVisibleAreaOffsetLandscape.setSummary( + getString(R.string.settings_start_autoplay_visible_area_offset_portrait_summary, + sharedPreferences.getInt(SharedPreferencesUtils.START_AUTOPLAY_VISIBLE_AREA_OFFSET_LANDSCAPE, 50))); + startAutoplayVisibleAreaOffsetLandscape.setOnPreferenceChangeListener((Preference.OnPreferenceChangeListener) (preference, newValue) -> { + if (orientation == Configuration.ORIENTATION_LANDSCAPE) { + EventBus.getDefault().post(new ChangeStartAutoplayVisibleAreaOffsetEvent((Integer) newValue)); + } + startAutoplayVisibleAreaOffsetLandscape.setSummary( + getString(R.string.settings_start_autoplay_visible_area_offset_landscape_summary, (Integer) newValue)); + return true; + }); + } + } + + @Override + public void onAttach(@NonNull Context context) { + super.onAttach(context); + this.activity = (AppCompatActivity) context; + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/FetchSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/FetchSubredditData.java new file mode 100644 index 00000000..a7a9eb21 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/FetchSubredditData.java @@ -0,0 +1,94 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import androidx.annotation.NonNull; + +import com.facebook.common.internal.ImmutableMap; + +import java.util.ArrayList; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchSubredditData { + public static void fetchSubredditData(Retrofit retrofit, String subredditName, final FetchSubredditDataListener fetchSubredditDataListener) { + RedditAPI api = retrofit.create(RedditAPI.class); + + Call subredditData = api.getSubredditData(subredditName); + subredditData.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseSubredditData.parseSubredditData(response.body(), new ParseSubredditData.ParseSubredditDataListener() { + @Override + public void onParseSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { + fetchSubredditDataListener.onFetchSubredditDataSuccess(subredditData, nCurrentOnlineSubscribers); + } + + @Override + public void onParseSubredditDataFail() { + fetchSubredditDataListener.onFetchSubredditDataFail(); + } + }); + } else { + fetchSubredditDataListener.onFetchSubredditDataFail(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchSubredditDataListener.onFetchSubredditDataFail(); + } + }); + } + + static void fetchSubredditListingData(Retrofit retrofit, String query, String after, String sortType, String accessToken, + boolean nsfw, final FetchSubredditListingDataListener fetchSubredditListingDataListener) { + RedditAPI api = retrofit.create(RedditAPI.class); + + Map headers = accessToken != null ? APIUtils.getOAuthHeader(accessToken) : ImmutableMap.of(); + Call subredditDataCall = api.searchSubreddits(query, after, sortType, nsfw ? 1 : 0, headers); + subredditDataCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + ParseSubredditData.parseSubredditListingData(response.body(), nsfw, + new ParseSubredditData.ParseSubredditListingDataListener() { + @Override + public void onParseSubredditListingDataSuccess(ArrayList subredditData, String after) { + fetchSubredditListingDataListener.onFetchSubredditListingDataSuccess(subredditData, after); + } + + @Override + public void onParseSubredditListingDataFail() { + fetchSubredditListingDataListener.onFetchSubredditListingDataFail(); + } + }); + } else { + fetchSubredditListingDataListener.onFetchSubredditListingDataFail(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchSubredditListingDataListener.onFetchSubredditListingDataFail(); + } + }); + } + + public interface FetchSubredditDataListener { + void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers); + + void onFetchSubredditDataFail(); + } + + interface FetchSubredditListingDataListener { + void onFetchSubredditListingDataSuccess(ArrayList subredditData, String after); + + void onFetchSubredditListingDataFail(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java new file mode 100644 index 00000000..d673647d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/ParseSubredditData.java @@ -0,0 +1,173 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import android.os.AsyncTask; + +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.utils.JSONUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; + +class ParseSubredditData { + static void parseSubredditData(String response, ParseSubredditDataListener parseSubredditDataListener) { + new ParseSubredditDataAsyncTask(response, parseSubredditDataListener).execute(); + } + + static void parseSubredditListingData(String response, boolean nsfw, ParseSubredditListingDataListener parseSubredditListingDataListener) { + new ParseSubredditListingDataAsyncTask(response, nsfw, parseSubredditListingDataListener).execute(); + } + + @Nullable + private static SubredditData parseSubredditData(JSONObject subredditDataJsonObject, boolean nsfw) throws JSONException { + boolean isNSFW = !subredditDataJsonObject.isNull(JSONUtils.OVER18_KEY) && subredditDataJsonObject.getBoolean(JSONUtils.OVER18_KEY); + if (!nsfw && isNSFW) { + return null; + } + String id = subredditDataJsonObject.getString(JSONUtils.NAME_KEY); + String subredditFullName = subredditDataJsonObject.getString(JSONUtils.DISPLAY_NAME_KEY); + String description = subredditDataJsonObject.getString(JSONUtils.PUBLIC_DESCRIPTION_KEY).trim(); + String sidebarDescription = Utils.modifyMarkdown(subredditDataJsonObject.getString(JSONUtils.DESCRIPTION_KEY).trim()); + long createdUTC = subredditDataJsonObject.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; + String suggestedCommentSort = subredditDataJsonObject.getString(JSONUtils.SUGGESTED_COMMENT_SORT_KEY); + + String bannerImageUrl; + if (subredditDataJsonObject.isNull(JSONUtils.BANNER_BACKGROUND_IMAGE_KEY)) { + bannerImageUrl = ""; + } else { + bannerImageUrl = subredditDataJsonObject.getString(JSONUtils.BANNER_BACKGROUND_IMAGE_KEY); + } + if (bannerImageUrl.equals("") && !subredditDataJsonObject.isNull(JSONUtils.BANNER_IMG_KEY)) { + bannerImageUrl = subredditDataJsonObject.getString(JSONUtils.BANNER_IMG_KEY); + } + + String iconUrl; + if (subredditDataJsonObject.isNull(JSONUtils.COMMUNITY_ICON_KEY)) { + iconUrl = ""; + } else { + iconUrl = subredditDataJsonObject.getString(JSONUtils.COMMUNITY_ICON_KEY); + } + if (iconUrl.equals("") && !subredditDataJsonObject.isNull(JSONUtils.ICON_IMG_KEY)) { + iconUrl = subredditDataJsonObject.getString(JSONUtils.ICON_IMG_KEY); + } + + int nSubscribers = 0; + if (!subredditDataJsonObject.isNull(JSONUtils.SUBSCRIBERS_KEY)) { + nSubscribers = subredditDataJsonObject.getInt(JSONUtils.SUBSCRIBERS_KEY); + } + + return new SubredditData(id, subredditFullName, iconUrl, bannerImageUrl, description, + sidebarDescription, nSubscribers, createdUTC, suggestedCommentSort, isNSFW); + } + + interface ParseSubredditDataListener { + void onParseSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers); + + void onParseSubredditDataFail(); + } + + interface ParseSubredditListingDataListener { + void onParseSubredditListingDataSuccess(ArrayList subredditData, String after); + + void onParseSubredditListingDataFail(); + } + + private static class ParseSubredditDataAsyncTask extends AsyncTask { + private JSONObject jsonResponse; + private boolean parseFailed; + private ParseSubredditDataListener parseSubredditDataListener; + private SubredditData subredditData; + private int mNCurrentOnlineSubscribers; + + ParseSubredditDataAsyncTask(String response, ParseSubredditDataListener parseSubredditDataListener) { + this.parseSubredditDataListener = parseSubredditDataListener; + try { + jsonResponse = new JSONObject(response); + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseSubredditDataListener.onParseSubredditDataFail(); + } + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject data = jsonResponse.getJSONObject(JSONUtils.DATA_KEY); + mNCurrentOnlineSubscribers = data.getInt(JSONUtils.ACTIVE_USER_COUNT_KEY); + subredditData = parseSubredditData(data, true); + } catch (JSONException e) { + parseFailed = true; + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!parseFailed) { + parseSubredditDataListener.onParseSubredditDataSuccess(subredditData, mNCurrentOnlineSubscribers); + } else { + parseSubredditDataListener.onParseSubredditDataFail(); + } + } + } + + private static class ParseSubredditListingDataAsyncTask extends AsyncTask { + private JSONObject jsonResponse; + private boolean nsfw; + private boolean parseFailed; + private ParseSubredditListingDataListener parseSubredditListingDataListener; + private ArrayList subredditListingData; + private String after; + + ParseSubredditListingDataAsyncTask(String response, boolean nsfw, ParseSubredditListingDataListener parseSubredditListingDataListener) { + this.parseSubredditListingDataListener = parseSubredditListingDataListener; + try { + jsonResponse = new JSONObject(response); + this.nsfw = nsfw; + parseFailed = false; + subredditListingData = new ArrayList<>(); + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + @Override + protected Void doInBackground(Void... voids) { + try { + if (!parseFailed) { + JSONArray children = jsonResponse.getJSONObject(JSONUtils.DATA_KEY) + .getJSONArray(JSONUtils.CHILDREN_KEY); + for (int i = 0; i < children.length(); i++) { + JSONObject data = children.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + SubredditData subredditData = parseSubredditData(data, nsfw); + if (subredditData != null) { + subredditListingData.add(subredditData); + } + } + after = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + } + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + parseSubredditListingDataListener.onParseSubredditListingDataFail(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!parseFailed) { + parseSubredditListingDataListener.onParseSubredditListingDataSuccess(subredditListingData, after); + } else { + parseSubredditListingDataListener.onParseSubredditListingDataFail(); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditDao.java new file mode 100644 index 00000000..1ae2a1e0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditDao.java @@ -0,0 +1,22 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +@Dao +public interface SubredditDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(SubredditData SubredditData); + + @Query("DELETE FROM subreddits") + void deleteAllSubreddits(); + + @Query("SELECT * from subreddits WHERE name = :namePrefixed COLLATE NOCASE LIMIT 1") + LiveData getSubredditLiveDataByName(String namePrefixed); + + @Query("SELECT * from subreddits WHERE name = :namePrefixed COLLATE NOCASE LIMIT 1") + SubredditData getSubredditData(String namePrefixed); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditData.java new file mode 100644 index 00000000..21d5d130 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditData.java @@ -0,0 +1,88 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "subreddits") +public class SubredditData { + @PrimaryKey + @NonNull + @ColumnInfo(name = "id") + private String id; + @ColumnInfo(name = "name") + private String name; + @ColumnInfo(name = "icon") + private String iconUrl; + @ColumnInfo(name = "banner") + private String bannerUrl; + @ColumnInfo(name = "description") + private String description; + @ColumnInfo(name = "sidebar_description") + private String sidebarDescription; + @ColumnInfo(name = "subscribers_count") + private int nSubscribers; + @ColumnInfo(name = "created_utc") + private long createdUTC; + @ColumnInfo(name = "suggested_comment_sort") + private String suggestedCommentSort; + @ColumnInfo(name = "over18") + private boolean isNSFW; + + public SubredditData(@NonNull String id, String name, String iconUrl, String bannerUrl, + String description, String sidebarDescription, int nSubscribers, long createdUTC, + String suggestedCommentSort, boolean isNSFW) { + this.id = id; + this.name = name; + this.iconUrl = iconUrl; + this.bannerUrl = bannerUrl; + this.description = description; + this.sidebarDescription = sidebarDescription; + this.nSubscribers = nSubscribers; + this.createdUTC = createdUTC; + this.suggestedCommentSort = suggestedCommentSort; + this.isNSFW = isNSFW; + } + + @NonNull + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getIconUrl() { + return iconUrl; + } + + public String getBannerUrl() { + return bannerUrl; + } + + public String getDescription() { + return description; + } + + public String getSidebarDescription() { + return sidebarDescription; + } + + public int getNSubscribers() { + return nSubscribers; + } + + public long getCreatedUTC() { + return createdUTC; + } + + public String getSuggestedCommentSort() { + return suggestedCommentSort; + } + + public boolean isNSFW() { + return isNSFW; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSource.java new file mode 100644 index 00000000..3757cde9 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSource.java @@ -0,0 +1,108 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.PageKeyedDataSource; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +public class SubredditListingDataSource extends PageKeyedDataSource { + + private Retrofit retrofit; + private String query; + private SortType sortType; + private String accessToken; + private boolean nsfw; + + private MutableLiveData paginationNetworkStateLiveData; + private MutableLiveData initialLoadStateLiveData; + private MutableLiveData hasSubredditLiveData; + + private LoadParams params; + private LoadCallback callback; + + SubredditListingDataSource(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { + this.retrofit = retrofit; + this.query = query; + this.sortType = sortType; + this.accessToken = accessToken; + this.nsfw = nsfw; + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasSubredditLiveData = new MutableLiveData<>(); + } + + MutableLiveData getPaginationNetworkStateLiveData() { + return paginationNetworkStateLiveData; + } + + MutableLiveData getInitialLoadStateLiveData() { + return initialLoadStateLiveData; + } + + MutableLiveData hasSubredditLiveData() { + return hasSubredditLiveData; + } + + @Override + public void loadInitial(@NonNull LoadInitialParams params, @NonNull LoadInitialCallback callback) { + initialLoadStateLiveData.postValue(NetworkState.LOADING); + + FetchSubredditData.fetchSubredditListingData(retrofit, query, null, sortType.getType().value, accessToken, nsfw, + new FetchSubredditData.FetchSubredditListingDataListener() { + @Override + public void onFetchSubredditListingDataSuccess(ArrayList subredditData, String after) { + if (subredditData.size() == 0) { + hasSubredditLiveData.postValue(false); + } else { + hasSubredditLiveData.postValue(true); + } + + callback.onResult(subredditData, null, after); + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onFetchSubredditListingDataFail() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving subreddit list")); + } + }); + } + + @Override + public void loadBefore(@NonNull LoadParams params, @NonNull LoadCallback callback) { + + } + + @Override + public void loadAfter(@NonNull LoadParams params, @NonNull LoadCallback callback) { + this.params = params; + this.callback = callback; + + if (params.key.equals("") || params.key.equals("null")) { + return; + } + + FetchSubredditData.fetchSubredditListingData(retrofit, query, params.key, sortType.getType().value, accessToken, nsfw, + new FetchSubredditData.FetchSubredditListingDataListener() { + @Override + public void onFetchSubredditListingDataSuccess(ArrayList subredditData, String after) { + callback.onResult(subredditData, after); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onFetchSubredditListingDataFail() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving subreddit list")); + } + }); + } + + void retryLoadingMore() { + loadAfter(params, callback); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSourceFactory.java new file mode 100644 index 00000000..0252b2a0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingDataSourceFactory.java @@ -0,0 +1,48 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.DataSource; + +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +public class SubredditListingDataSourceFactory extends DataSource.Factory { + private Retrofit retrofit; + private String query; + private SortType sortType; + private String accessToken; + private boolean nsfw; + + private SubredditListingDataSource subredditListingDataSource; + private MutableLiveData subredditListingDataSourceMutableLiveData; + + SubredditListingDataSourceFactory(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { + this.retrofit = retrofit; + this.query = query; + this.sortType = sortType; + this.accessToken = accessToken; + this.nsfw = nsfw; + subredditListingDataSourceMutableLiveData = new MutableLiveData<>(); + } + + @NonNull + @Override + public DataSource create() { + subredditListingDataSource = new SubredditListingDataSource(retrofit, query, sortType, accessToken, nsfw); + subredditListingDataSourceMutableLiveData.postValue(subredditListingDataSource); + return subredditListingDataSource; + } + + public MutableLiveData getSubredditListingDataSourceMutableLiveData() { + return subredditListingDataSourceMutableLiveData; + } + + SubredditListingDataSource getSubredditListingDataSource() { + return subredditListingDataSource; + } + + void changeSortType(SortType sortType) { + this.sortType = sortType; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingViewModel.java new file mode 100644 index 00000000..a559aee2 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditListingViewModel.java @@ -0,0 +1,98 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Transformations; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.LivePagedListBuilder; +import androidx.paging.PagedList; + +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +public class SubredditListingViewModel extends ViewModel { + private SubredditListingDataSourceFactory subredditListingDataSourceFactory; + private LiveData paginationNetworkState; + private LiveData initialLoadingState; + private LiveData hasSubredditLiveData; + private LiveData> subreddits; + private MutableLiveData sortTypeLiveData; + + public SubredditListingViewModel(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { + subredditListingDataSourceFactory = new SubredditListingDataSourceFactory(retrofit, query, sortType, accessToken, nsfw); + + initialLoadingState = Transformations.switchMap(subredditListingDataSourceFactory.getSubredditListingDataSourceMutableLiveData(), + SubredditListingDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(subredditListingDataSourceFactory.getSubredditListingDataSourceMutableLiveData(), + SubredditListingDataSource::getPaginationNetworkStateLiveData); + hasSubredditLiveData = Transformations.switchMap(subredditListingDataSourceFactory.getSubredditListingDataSourceMutableLiveData(), + SubredditListingDataSource::hasSubredditLiveData); + + sortTypeLiveData = new MutableLiveData<>(); + sortTypeLiveData.postValue(sortType); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + subreddits = Transformations.switchMap(sortTypeLiveData, sort -> { + subredditListingDataSourceFactory.changeSortType(sortTypeLiveData.getValue()); + return new LivePagedListBuilder(subredditListingDataSourceFactory, pagedListConfig).build(); + }); + } + + public LiveData> getSubreddits() { + return subreddits; + } + + public LiveData getPaginationNetworkState() { + return paginationNetworkState; + } + + public LiveData getInitialLoadingState() { + return initialLoadingState; + } + + public LiveData hasSubredditLiveData() { + return hasSubredditLiveData; + } + + public void refresh() { + subredditListingDataSourceFactory.getSubredditListingDataSource().invalidate(); + } + + public void retryLoadingMore() { + subredditListingDataSourceFactory.getSubredditListingDataSource().retryLoadingMore(); + } + + public void changeSortType(SortType sortType) { + sortTypeLiveData.postValue(sortType); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Retrofit retrofit; + private String query; + private SortType sortType; + private String accessToken; + private boolean nsfw; + + public Factory(Retrofit retrofit, String query, SortType sortType, String accessToken, boolean nsfw) { + this.retrofit = retrofit; + this.query = query; + this.sortType = sortType; + this.accessToken = accessToken; + this.nsfw = nsfw; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new SubredditListingViewModel(retrofit, query, sortType, accessToken, nsfw); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditRepository.java new file mode 100644 index 00000000..649b4ee0 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditRepository.java @@ -0,0 +1,40 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import android.os.AsyncTask; + +import androidx.lifecycle.LiveData; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SubredditRepository { + private SubredditDao mSubredditDao; + private LiveData mSubredditLiveData; + + SubredditRepository(RedditDataRoomDatabase redditDataRoomDatabase, String subredditName) { + mSubredditDao = redditDataRoomDatabase.subredditDao(); + mSubredditLiveData = mSubredditDao.getSubredditLiveDataByName(subredditName); + } + + LiveData getSubredditLiveData() { + return mSubredditLiveData; + } + + public void insert(SubredditData subredditData) { + new InsertAsyncTask(mSubredditDao).execute(subredditData); + } + + private static class InsertAsyncTask extends AsyncTask { + + private SubredditDao mAsyncTaskDao; + + InsertAsyncTask(SubredditDao dao) { + mAsyncTaskDao = dao; + } + + @Override + protected Void doInBackground(final SubredditData... params) { + mAsyncTaskDao.insert(params[0]); + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java new file mode 100644 index 00000000..52664234 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditSubscription.java @@ -0,0 +1,120 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import android.os.AsyncTask; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; + +public class SubredditSubscription { + public static void subscribeToSubreddit(Retrofit oauthRetrofit, Retrofit retrofit, + String accessToken, String subredditName, String accountName, + RedditDataRoomDatabase redditDataRoomDatabase, + SubredditSubscriptionListener subredditSubscriptionListener) { + subredditSubscription(oauthRetrofit, retrofit, accessToken, subredditName, accountName, "sub", + redditDataRoomDatabase, subredditSubscriptionListener); + } + + public static void unsubscribeToSubreddit(Retrofit oauthRetrofit, String accessToken, + String subredditName, String accountName, + RedditDataRoomDatabase redditDataRoomDatabase, + SubredditSubscriptionListener subredditSubscriptionListener) { + subredditSubscription(oauthRetrofit, null, accessToken, subredditName, accountName, "unsub", + redditDataRoomDatabase, subredditSubscriptionListener); + } + + private static void subredditSubscription(Retrofit oauthRetrofit, Retrofit retrofit, String accessToken, + String subredditName, String accountName, String action, + RedditDataRoomDatabase redditDataRoomDatabase, + SubredditSubscriptionListener subredditSubscriptionListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Map params = new HashMap<>(); + params.put(APIUtils.ACTION_KEY, action); + params.put(APIUtils.SR_NAME_KEY, subredditName); + + Call subredditSubscriptionCall = api.subredditSubscription(APIUtils.getOAuthHeader(accessToken), params); + subredditSubscriptionCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + if (action.equals("sub")) { + FetchSubredditData.fetchSubredditData(retrofit, subredditName, new FetchSubredditData.FetchSubredditDataListener() { + @Override + public void onFetchSubredditDataSuccess(SubredditData subredditData, int nCurrentOnlineSubscribers) { + new UpdateSubscriptionAsyncTask(redditDataRoomDatabase, + subredditData, accountName, true).execute(); + } + + @Override + public void onFetchSubredditDataFail() { + + } + }); + } else { + new UpdateSubscriptionAsyncTask(redditDataRoomDatabase, subredditName, accountName, false).execute(); + } + subredditSubscriptionListener.onSubredditSubscriptionSuccess(); + } else { + subredditSubscriptionListener.onSubredditSubscriptionFail(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + subredditSubscriptionListener.onSubredditSubscriptionFail(); + } + }); + } + + public interface SubredditSubscriptionListener { + void onSubredditSubscriptionSuccess(); + + void onSubredditSubscriptionFail(); + } + + private static class UpdateSubscriptionAsyncTask extends AsyncTask { + + private RedditDataRoomDatabase redditDataRoomDatabase; + private String subredditName; + private String accountName; + private SubscribedSubredditData subscribedSubredditData; + private boolean isSubscribing; + + UpdateSubscriptionAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, String subredditName, + String accountName, boolean isSubscribing) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.subredditName = subredditName; + this.accountName = accountName; + this.isSubscribing = isSubscribing; + } + + UpdateSubscriptionAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, SubredditData subredditData, + String accountName, boolean isSubscribing) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.subscribedSubredditData = new SubscribedSubredditData(subredditData.getId(), subredditData.getName(), + subredditData.getIconUrl(), accountName, false); + this.accountName = accountName; + this.isSubscribing = isSubscribing; + } + + @Override + protected Void doInBackground(Void... voids) { + if (isSubscribing) { + redditDataRoomDatabase.subscribedSubredditDao().insert(subscribedSubredditData); + } else { + redditDataRoomDatabase.subscribedSubredditDao().deleteSubscribedSubreddit(subredditName, accountName); + } + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditViewModel.java new file mode 100644 index 00000000..debbbf36 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditViewModel.java @@ -0,0 +1,51 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SubredditViewModel extends AndroidViewModel { + private SubredditRepository mSubredditRepository; + private LiveData mSubredditLiveData; + + public SubredditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String id) { + super(application); + mSubredditRepository = new SubredditRepository(redditDataRoomDatabase, id); + mSubredditLiveData = mSubredditRepository.getSubredditLiveData(); + } + + public LiveData getSubredditLiveData() { + return mSubredditLiveData; + } + + public void insert(SubredditData subredditData) { + mSubredditRepository.insert(subredditData); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + + @NonNull + private final Application mApplication; + private final RedditDataRoomDatabase mRedditDataRoomDatabase; + private final String mSubredditName; + + public Factory(@NonNull Application application, RedditDataRoomDatabase redditDataRoomDatabase, String subredditname) { + mApplication = application; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mSubredditName = subredditname; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + //noinspection unchecked + return (T) new SubredditViewModel(mApplication, mRedditDataRoomDatabase, mSubredditName); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditWithSelection.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditWithSelection.java new file mode 100644 index 00000000..68eddfa1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subreddit/SubredditWithSelection.java @@ -0,0 +1,101 @@ +package ml.docilealligator.infinityforreddit.subreddit; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; + +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; + +public class SubredditWithSelection implements Parcelable { + private String name; + private String iconUrl; + private boolean selected; + + public SubredditWithSelection(String name, String iconUrl) { + this.name = name; + this.iconUrl = iconUrl; + selected = false; + } + + protected SubredditWithSelection(Parcel in) { + super(); + name = in.readString(); + iconUrl = in.readString(); + selected = in.readByte() != 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public SubredditWithSelection createFromParcel(Parcel in) { + return new SubredditWithSelection(in); + } + + @Override + public SubredditWithSelection[] newArray(int size) { + return new SubredditWithSelection[size]; + } + }; + + public String getName() { + return name; + } + + public String getIconUrl() { + return iconUrl; + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + + public static ArrayList convertSubscribedSubreddits( + List subscribedSubredditData) { + ArrayList subredditWithSelections = new ArrayList<>(); + for (SubscribedSubredditData s : subscribedSubredditData) { + subredditWithSelections.add(new SubredditWithSelection(s.getName(), s.getIconUrl())); + } + + return subredditWithSelections; + } + + public static SubredditWithSelection convertSubreddit(SubredditData subreddit) { + return new SubredditWithSelection(subreddit.getName(), subreddit.getIconUrl()); + } + + public int compareName(SubredditWithSelection subredditWithSelection) { + if (subredditWithSelection != null) { + return name.compareToIgnoreCase(subredditWithSelection.getName()); + } else { + return -1; + } + } + + @Override + public boolean equals(@Nullable Object obj) { + if (!(obj instanceof SubredditWithSelection)) { + return false; + } else { + return this.getName().compareToIgnoreCase(((SubredditWithSelection) obj).getName()) == 0; + } + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(name); + parcel.writeString(iconUrl); + parcel.writeByte((byte) (selected ? 1 : 0)); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/DeleteSubredditFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/DeleteSubredditFilter.java new file mode 100644 index 00000000..051d247a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/DeleteSubredditFilter.java @@ -0,0 +1,41 @@ +package ml.docilealligator.infinityforreddit.subredditfilter; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class DeleteSubredditFilter { + public interface DeleteSubredditFilterListener { + void success(); + } + + public static void deleteSubredditFilter(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, + DeleteSubredditFilterListener deleteSubredditFilterListener) { + new DeleteSubredditFilterAsyncTask(redditDataRoomDatabase, subredditFilter, deleteSubredditFilterListener).execute(); + } + + private static class DeleteSubredditFilterAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private SubredditFilter subredditFilter; + private DeleteSubredditFilterListener deleteSubredditFilterListener; + + DeleteSubredditFilterAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, + DeleteSubredditFilterListener deleteSubredditFilterListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.subredditFilter = subredditFilter; + this.deleteSubredditFilterListener = deleteSubredditFilterListener; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.subredditFilterDao().deleteSubredditFilter(subredditFilter); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + deleteSubredditFilterListener.success(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/FetchSubredditFilters.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/FetchSubredditFilters.java new file mode 100644 index 00000000..e9c6f406 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/FetchSubredditFilters.java @@ -0,0 +1,42 @@ +package ml.docilealligator.infinityforreddit.subredditfilter; + +import android.os.AsyncTask; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class FetchSubredditFilters { + public interface FetchSubredditFiltersListener { + void success(ArrayListsubredditFilters); + } + + public static void fetchSubredditFilters(RedditDataRoomDatabase redditDataRoomDatabase, + FetchSubredditFiltersListener fetchSubredditFiltersListener) { + new FetchSubredditFiltersAsyncTask(redditDataRoomDatabase, fetchSubredditFiltersListener).execute(); + } + + private static class FetchSubredditFiltersAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private ArrayList subredditFilters; + private FetchSubredditFiltersListener fetchSubredditFiltersListener; + + FetchSubredditFiltersAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, + FetchSubredditFiltersListener fetchSubredditFiltersListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.fetchSubredditFiltersListener = fetchSubredditFiltersListener; + } + + @Override + protected Void doInBackground(Void... voids) { + subredditFilters = (ArrayList) redditDataRoomDatabase.subredditFilterDao().getAllSubredditFilters(); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + fetchSubredditFiltersListener.success(subredditFilters); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/InsertSubredditFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/InsertSubredditFilter.java new file mode 100644 index 00000000..eb26a964 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/InsertSubredditFilter.java @@ -0,0 +1,41 @@ +package ml.docilealligator.infinityforreddit.subredditfilter; + +import android.os.AsyncTask; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class InsertSubredditFilter { + public interface InsertSubredditFilterListener { + void success(); + } + + public static void insertSubredditFilter(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, + InsertSubredditFilterListener insertSubredditFilterListener) { + new InsertSubredditFilterAsyncTask(redditDataRoomDatabase, subredditFilter, insertSubredditFilterListener).execute(); + } + + private static class InsertSubredditFilterAsyncTask extends AsyncTask { + private RedditDataRoomDatabase redditDataRoomDatabase; + private SubredditFilter subredditFilter; + private InsertSubredditFilterListener insertSubredditFilterListener; + + InsertSubredditFilterAsyncTask(RedditDataRoomDatabase redditDataRoomDatabase, SubredditFilter subredditFilter, + InsertSubredditFilterListener insertSubredditFilterListener) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + this.subredditFilter = subredditFilter; + this.insertSubredditFilterListener = insertSubredditFilterListener; + } + + @Override + protected Void doInBackground(Void... voids) { + redditDataRoomDatabase.subredditFilterDao().insert(subredditFilter); + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + insertSubredditFilterListener.success(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilter.java new file mode 100644 index 00000000..337ebab4 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilter.java @@ -0,0 +1,68 @@ +package ml.docilealligator.infinityforreddit.subredditfilter; + +import android.os.Parcel; +import android.os.Parcelable; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; + +@Entity(tableName = "subreddit_filter", primaryKeys = {"subreddit_name", "type"}) +public class SubredditFilter implements Parcelable { + public static int TYPE_POPULAR_AND_ALL = 0; + @NonNull + @ColumnInfo(name = "subreddit_name") + private String subredditName; + @ColumnInfo(name = "type") + private int type; + + public SubredditFilter(@NonNull String subredditName, int type) { + this.subredditName = subredditName; + this.type = type; + } + + protected SubredditFilter(Parcel in) { + subredditName = in.readString(); + type = in.readInt(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public SubredditFilter createFromParcel(Parcel in) { + return new SubredditFilter(in); + } + + @Override + public SubredditFilter[] newArray(int size) { + return new SubredditFilter[size]; + } + }; + + @NonNull + public String getSubredditName() { + return subredditName; + } + + public void setSubredditName(@NonNull String subredditName) { + this.subredditName = subredditName; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(subredditName); + parcel.writeInt(type); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterDao.java new file mode 100644 index 00000000..1cdcd22b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterDao.java @@ -0,0 +1,25 @@ +package ml.docilealligator.infinityforreddit.subredditfilter; + +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 SubredditFilterDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(SubredditFilter subredditFilter); + + @Query("SELECT * FROM subreddit_filter") + LiveData> getAllSubredditFiltersLiveData(); + + @Query("SELECT * FROM subreddit_filter") + List getAllSubredditFilters(); + + @Delete + void deleteSubredditFilter(SubredditFilter subredditFilter); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterViewModel.java new file mode 100644 index 00000000..9f571f30 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subredditfilter/SubredditFilterViewModel.java @@ -0,0 +1,36 @@ +package ml.docilealligator.infinityforreddit.subredditfilter; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SubredditFilterViewModel extends ViewModel { + private LiveData> subredditFilterLiveData; + + public SubredditFilterViewModel(RedditDataRoomDatabase redditDataRoomDatabase) { + subredditFilterLiveData = redditDataRoomDatabase.subredditFilterDao().getAllSubredditFiltersLiveData(); + } + + public LiveData> getSubredditFilterLiveData() { + return subredditFilterLiveData; + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private RedditDataRoomDatabase redditDataRoomDatabase; + + public Factory(RedditDataRoomDatabase redditDataRoomDatabase) { + this.redditDataRoomDatabase = redditDataRoomDatabase; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new SubredditFilterViewModel(redditDataRoomDatabase); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditDao.java new file mode 100644 index 00000000..f7452100 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditDao.java @@ -0,0 +1,33 @@ +package ml.docilealligator.infinityforreddit.subscribedsubreddit; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface SubscribedSubredditDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(SubscribedSubredditData subscribedSubredditData); + + @Query("DELETE FROM subscribed_subreddits") + void deleteAllSubscribedSubreddits(); + + @Query("SELECT * from subscribed_subreddits WHERE username = :accountName ORDER BY name COLLATE NOCASE ASC") + LiveData> getAllSubscribedSubreddits(String accountName); + + @Query("SELECT * from subscribed_subreddits WHERE username = :accountName COLLATE NOCASE ORDER BY name COLLATE NOCASE ASC") + List getAllSubscribedSubredditsList(String accountName); + + @Query("SELECT * from subscribed_subreddits WHERE username = :accountName COLLATE NOCASE AND is_favorite = 1 ORDER BY name COLLATE NOCASE ASC") + LiveData> getAllFavoriteSubscribedSubreddits(String accountName); + + @Query("SELECT * from subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE LIMIT 1") + SubscribedSubredditData getSubscribedSubreddit(String subredditName, String accountName); + + @Query("DELETE FROM subscribed_subreddits WHERE name = :subredditName COLLATE NOCASE AND username = :accountName COLLATE NOCASE") + void deleteSubscribedSubreddit(String subredditName, String accountName); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditData.java new file mode 100644 index 00000000..a5c42381 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditData.java @@ -0,0 +1,65 @@ +package ml.docilealligator.infinityforreddit.subscribedsubreddit; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.ForeignKey; + +import ml.docilealligator.infinityforreddit.account.Account; + +@Entity(tableName = "subscribed_subreddits", primaryKeys = {"id", "username"}, + foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", + childColumns = "username", onDelete = ForeignKey.CASCADE)) +public class SubscribedSubredditData { + @NonNull + @ColumnInfo(name = "id") + private String id; + @ColumnInfo(name = "name") + private String name; + @ColumnInfo(name = "icon") + private String iconUrl; + @NonNull + @ColumnInfo(name = "username") + private String username; + @ColumnInfo(name = "is_favorite") + private boolean favorite; + + public SubscribedSubredditData(@NonNull String id, String name, String iconUrl, @NonNull String username, + boolean favorite) { + this.id = id; + this.name = name; + this.iconUrl = iconUrl; + this.username = username; + this.favorite = favorite; + } + + @NonNull + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public String getIconUrl() { + return iconUrl; + } + + @NonNull + public String getUsername() { + return username; + } + + public void setUsername(@NonNull String username) { + this.username = username; + } + + public boolean isFavorite() { + return favorite; + } + + public void setFavorite(boolean favorite) { + this.favorite = favorite; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditRepository.java new file mode 100644 index 00000000..053ae1ed --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditRepository.java @@ -0,0 +1,48 @@ +package ml.docilealligator.infinityforreddit.subscribedsubreddit; + +import android.os.AsyncTask; + +import androidx.lifecycle.LiveData; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SubscribedSubredditRepository { + private SubscribedSubredditDao mSubscribedSubredditDao; + private LiveData> mAllSubscribedSubreddits; + private LiveData> mAllFavoriteSubscribedSubreddits; + + SubscribedSubredditRepository(RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + mSubscribedSubredditDao = redditDataRoomDatabase.subscribedSubredditDao(); + mAllSubscribedSubreddits = mSubscribedSubredditDao.getAllSubscribedSubreddits(accountName); + mAllFavoriteSubscribedSubreddits = mSubscribedSubredditDao.getAllFavoriteSubscribedSubreddits(accountName); + } + + LiveData> getAllSubscribedSubreddits() { + return mAllSubscribedSubreddits; + } + + public LiveData> getAllFavoriteSubscribedSubreddits() { + return mAllFavoriteSubscribedSubreddits; + } + + public void insert(SubscribedSubredditData subscribedSubredditData) { + new insertAsyncTask(mSubscribedSubredditDao).execute(subscribedSubredditData); + } + + private static class insertAsyncTask extends AsyncTask { + + private SubscribedSubredditDao mAsyncTaskDao; + + insertAsyncTask(SubscribedSubredditDao dao) { + mAsyncTaskDao = dao; + } + + @Override + protected Void doInBackground(final SubscribedSubredditData... params) { + mAsyncTaskDao.insert(params[0]); + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditViewModel.java new file mode 100644 index 00000000..fa38fcac --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribedsubreddit/SubscribedSubredditViewModel.java @@ -0,0 +1,56 @@ +package ml.docilealligator.infinityforreddit.subscribedsubreddit; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SubscribedSubredditViewModel extends AndroidViewModel { + private SubscribedSubredditRepository mSubscribedSubredditRepository; + private LiveData> mAllSubscribedSubreddits; + private LiveData> mAllFavoriteSubscribedSubreddits; + + public SubscribedSubredditViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + super(application); + mSubscribedSubredditRepository = new SubscribedSubredditRepository(redditDataRoomDatabase, accountName); + mAllSubscribedSubreddits = mSubscribedSubredditRepository.getAllSubscribedSubreddits(); + mAllFavoriteSubscribedSubreddits = mSubscribedSubredditRepository.getAllFavoriteSubscribedSubreddits(); + } + + public LiveData> getAllSubscribedSubreddits() { + return mAllSubscribedSubreddits; + } + + public LiveData> getAllFavoriteSubscribedSubreddits() { + return mAllFavoriteSubscribedSubreddits; + } + + public void insert(SubscribedSubredditData subscribedSubredditData) { + mSubscribedSubredditRepository.insert(subscribedSubredditData); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Application mApplication; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private String mAccountName; + + public Factory(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + this.mApplication = application; + this.mRedditDataRoomDatabase = redditDataRoomDatabase; + this.mAccountName = accountName; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new SubscribedSubredditViewModel(mApplication, mRedditDataRoomDatabase, mAccountName); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserDao.java new file mode 100644 index 00000000..9ae7c895 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserDao.java @@ -0,0 +1,30 @@ +package ml.docilealligator.infinityforreddit.subscribeduser; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +import java.util.List; + +@Dao +public interface SubscribedUserDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(SubscribedUserData subscribedUserData); + + @Query("SELECT * FROM subscribed_users WHERE username = :accountName COLLATE NOCASE ORDER BY name COLLATE NOCASE ASC") + LiveData> getAllSubscribedUsers(String accountName); + + @Query("SELECT * FROM subscribed_users WHERE username = :accountName COLLATE NOCASE ORDER BY name COLLATE NOCASE ASC") + List getAllSubscribedUsersList(String accountName); + + @Query("SELECT * FROM subscribed_users WHERE username = :accountName COLLATE NOCASE AND is_favorite = 1 ORDER BY name COLLATE NOCASE ASC") + LiveData> getAllFavoriteSubscribedUsers(String accountName); + + @Query("SELECT * FROM subscribed_users WHERE name = :name COLLATE NOCASE AND username = :accountName COLLATE NOCASE LIMIT 1") + SubscribedUserData getSubscribedUser(String name, String accountName); + + @Query("DELETE FROM subscribed_users WHERE name = :name COLLATE NOCASE AND username = :accountName COLLATE NOCASE") + void deleteSubscribedUser(String name, String accountName); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserData.java new file mode 100644 index 00000000..0f9c0059 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserData.java @@ -0,0 +1,57 @@ +package ml.docilealligator.infinityforreddit.subscribeduser; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.ForeignKey; + +import ml.docilealligator.infinityforreddit.account.Account; + +@Entity(tableName = "subscribed_users", primaryKeys = {"name", "username"}, + foreignKeys = @ForeignKey(entity = Account.class, parentColumns = "username", + childColumns = "username", onDelete = ForeignKey.CASCADE)) +public class SubscribedUserData { + @NonNull + @ColumnInfo(name = "name") + private String name; + @ColumnInfo(name = "icon") + private String iconUrl; + @NonNull + @ColumnInfo(name = "username") + private String username; + @ColumnInfo(name = "is_favorite") + private boolean favorite; + + public SubscribedUserData(@NonNull String name, String iconUrl, @NonNull String username, boolean favorite) { + this.name = name; + this.iconUrl = iconUrl; + this.username = username; + this.favorite = favorite; + } + + @NonNull + public String getName() { + return name; + } + + public String getIconUrl() { + return iconUrl; + } + + @NonNull + public String getUsername() { + return username; + } + + public void setUsername(@NonNull String username) { + this.username = username; + } + + public boolean isFavorite() { + return favorite; + } + + public void setFavorite(boolean favorite) { + this.favorite = favorite; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserRepository.java new file mode 100644 index 00000000..1bd0aa71 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserRepository.java @@ -0,0 +1,48 @@ +package ml.docilealligator.infinityforreddit.subscribeduser; + +import android.os.AsyncTask; + +import androidx.lifecycle.LiveData; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SubscribedUserRepository { + private SubscribedUserDao mSubscribedUserDao; + private LiveData> mAllSubscribedUsers; + private LiveData> mAllFavoriteSubscribedUsers; + + SubscribedUserRepository(RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + mSubscribedUserDao = redditDataRoomDatabase.subscribedUserDao(); + mAllSubscribedUsers = mSubscribedUserDao.getAllSubscribedUsers(accountName); + mAllFavoriteSubscribedUsers = mSubscribedUserDao.getAllFavoriteSubscribedUsers(accountName); + } + + LiveData> getAllSubscribedSubreddits() { + return mAllSubscribedUsers; + } + + LiveData> getAllFavoriteSubscribedSubreddits() { + return mAllFavoriteSubscribedUsers; + } + + public void insert(SubscribedUserData subscribedUserData) { + new SubscribedUserRepository.insertAsyncTask(mSubscribedUserDao).execute(subscribedUserData); + } + + private static class insertAsyncTask extends AsyncTask { + + private SubscribedUserDao mAsyncTaskDao; + + insertAsyncTask(SubscribedUserDao dao) { + mAsyncTaskDao = dao; + } + + @Override + protected Void doInBackground(final SubscribedUserData... params) { + mAsyncTaskDao.insert(params[0]); + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserViewModel.java new file mode 100644 index 00000000..b19e5906 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/subscribeduser/SubscribedUserViewModel.java @@ -0,0 +1,56 @@ +package ml.docilealligator.infinityforreddit.subscribeduser; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import java.util.List; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class SubscribedUserViewModel extends AndroidViewModel { + private SubscribedUserRepository mSubscribedUserRepository; + private LiveData> mAllSubscribedUsers; + private LiveData> mAllFavoriteSubscribedUsers; + + public SubscribedUserViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + super(application); + mSubscribedUserRepository = new SubscribedUserRepository(redditDataRoomDatabase, accountName); + mAllSubscribedUsers = mSubscribedUserRepository.getAllSubscribedSubreddits(); + mAllFavoriteSubscribedUsers = mSubscribedUserRepository.getAllFavoriteSubscribedSubreddits(); + } + + public LiveData> getAllSubscribedUsers() { + return mAllSubscribedUsers; + } + + public LiveData> getAllFavoriteSubscribedUsers() { + return mAllFavoriteSubscribedUsers; + } + + public void insert(SubscribedUserData subscribedUserData) { + mSubscribedUserRepository.insert(subscribedUserData); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Application mApplication; + private RedditDataRoomDatabase mRedditDataRoomDatabase; + private String mAccountName; + + public Factory(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String accountName) { + mApplication = application; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mAccountName = accountName; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new SubscribedUserViewModel(mApplication, mRedditDataRoomDatabase, mAccountName); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/BlockUser.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/BlockUser.java new file mode 100644 index 00000000..c7a7207e --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/BlockUser.java @@ -0,0 +1,40 @@ +package ml.docilealligator.infinityforreddit.user; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class BlockUser { + public interface BlockUserListener { + void success(); + void failed(); + } + + public static void blockUser(Retrofit oauthRetrofit, String accessToken, String username, BlockUserListener blockUserListener) { + Map params = new HashMap<>(); + params.put(APIUtils.NAME_KEY, username); + oauthRetrofit.create(RedditAPI.class).blockUser(APIUtils.getOAuthHeader(accessToken), params).enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + blockUserListener.success(); + } else { + blockUserListener.failed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + blockUserListener.failed(); + } + }); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/FetchUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/FetchUserData.java new file mode 100644 index 00000000..60b20f55 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/FetchUserData.java @@ -0,0 +1,87 @@ +package ml.docilealligator.infinityforreddit.user; + +import androidx.annotation.NonNull; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; + +public class FetchUserData { + public static void fetchUserData(Retrofit retrofit, String userName, FetchUserDataListener fetchUserDataListener) { + RedditAPI api = retrofit.create(RedditAPI.class); + + Call userInfo = api.getUserData(userName); + userInfo.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParseUserData.parseUserData(response.body(), new ParseUserData.ParseUserDataListener() { + @Override + public void onParseUserDataSuccess(UserData userData) { + fetchUserDataListener.onFetchUserDataSuccess(userData); + } + + @Override + public void onParseUserDataFailed() { + fetchUserDataListener.onFetchUserDataFailed(); + } + }); + } else { + fetchUserDataListener.onFetchUserDataFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchUserDataListener.onFetchUserDataFailed(); + } + }); + } + + public static void fetchUserListingData(Retrofit retrofit, String query, String after, String sortType, boolean nsfw, + FetchUserListingDataListener fetchUserListingDataListener) { + RedditAPI api = retrofit.create(RedditAPI.class); + + Call userInfo = api.searchUsers(query, after, sortType, nsfw ? 1 : 0); + userInfo.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + ParseUserData.parseUserListingData(response.body(), new ParseUserData.ParseUserListingDataListener() { + @Override + public void onParseUserListingDataSuccess(ArrayList userData, String after) { + fetchUserListingDataListener.onFetchUserListingDataSuccess(userData, after); + } + + @Override + public void onParseUserListingDataFailed() { + fetchUserListingDataListener.onFetchUserListingDataFailed(); + } + }); + } else { + fetchUserListingDataListener.onFetchUserListingDataFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchUserListingDataListener.onFetchUserListingDataFailed(); + } + }); + } + + public interface FetchUserDataListener { + void onFetchUserDataSuccess(UserData userData); + + void onFetchUserDataFailed(); + } + + public interface FetchUserListingDataListener { + void onFetchUserListingDataSuccess(ArrayList userData, String after); + + void onFetchUserListingDataFailed(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/ParseUserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/ParseUserData.java new file mode 100644 index 00000000..bc0f1966 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/ParseUserData.java @@ -0,0 +1,156 @@ +package ml.docilealligator.infinityforreddit.user; + +import android.os.AsyncTask; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.utils.JSONUtils; + +public class ParseUserData { + static void parseUserData(String response, ParseUserDataListener parseUserDataListener) { + new ParseUserDataAsyncTask(response, parseUserDataListener).execute(); + } + + static void parseUserListingData(String response, ParseUserListingDataListener parseUserListingDataListener) { + new ParseUserListingDataAsyncTask(response, parseUserListingDataListener).execute(); + } + + private static UserData parseUserDataBase(JSONObject userDataJson) throws JSONException { + if(userDataJson == null) { + return null; + } + + userDataJson = userDataJson.getJSONObject(JSONUtils.DATA_KEY); + String userName = userDataJson.getString(JSONUtils.NAME_KEY); + String iconImageUrl = userDataJson.getString(JSONUtils.ICON_IMG_KEY); + String bannerImageUrl = ""; + boolean canBeFollowed; + if (userDataJson.has(JSONUtils.SUBREDDIT_KEY) && !userDataJson.isNull(JSONUtils.SUBREDDIT_KEY)) { + bannerImageUrl = userDataJson.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.BANNER_IMG_KEY); + canBeFollowed = true; + } else { + canBeFollowed = false; + } + int linkKarma = userDataJson.getInt(JSONUtils.LINK_KARMA_KEY); + int commentKarma = userDataJson.getInt(JSONUtils.COMMENT_KARMA_KEY); + int awarderKarma = userDataJson.getInt(JSONUtils.AWARDER_KARMA_KEY); + int awardeeKarma = userDataJson.getInt(JSONUtils.AWARDEE_KARMA_KEY); + int totalKarma = userDataJson.getInt(JSONUtils.TOTAL_KARMA_KEY); + long cakeday = userDataJson.getLong(JSONUtils.CREATED_UTC_KEY) * 1000; + boolean isGold = userDataJson.getBoolean(JSONUtils.IS_GOLD_KEY); + boolean isFriend = userDataJson.getBoolean(JSONUtils.IS_FRIEND_KEY); + boolean isNsfw = userDataJson.getJSONObject(JSONUtils.SUBREDDIT_KEY).getBoolean(JSONUtils.OVER_18_KEY); + String description = userDataJson.getJSONObject(JSONUtils.SUBREDDIT_KEY).getString(JSONUtils.PUBLIC_DESCRIPTION_KEY); + + return new UserData(userName, iconImageUrl, bannerImageUrl, linkKarma, commentKarma, awarderKarma, + awardeeKarma, totalKarma, cakeday, isGold, isFriend, canBeFollowed, isNsfw, description); + } + + interface ParseUserDataListener { + void onParseUserDataSuccess(UserData userData); + + void onParseUserDataFailed(); + } + + interface ParseUserListingDataListener { + void onParseUserListingDataSuccess(ArrayList userData, String after); + + void onParseUserListingDataFailed(); + } + + private static class ParseUserDataAsyncTask extends AsyncTask { + private JSONObject jsonResponse; + private ParseUserDataListener parseUserDataListener; + private boolean parseFailed; + + private UserData userData; + + ParseUserDataAsyncTask(String response, ParseUserDataListener parseUserDataListener) { + try { + jsonResponse = new JSONObject(response); + this.parseUserDataListener = parseUserDataListener; + parseFailed = false; + } catch (JSONException e) { + e.printStackTrace(); + parseUserDataListener.onParseUserDataFailed(); + } + } + + @Override + protected Void doInBackground(Void... voids) { + try { + userData = parseUserDataBase(jsonResponse); + } catch (JSONException e) { + parseFailed = true; + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!parseFailed) { + parseUserDataListener.onParseUserDataSuccess(userData); + } else { + parseUserDataListener.onParseUserDataFailed(); + } + } + } + + private static class ParseUserListingDataAsyncTask extends AsyncTask { + private String response; + private JSONObject jsonResponse; + private ParseUserListingDataListener parseUserListingDataListener; + private String after; + private boolean parseFailed; + + private ArrayList userDataArrayList; + + ParseUserListingDataAsyncTask(String response, ParseUserListingDataListener parseUserListingDataListener) { + this.parseUserListingDataListener = parseUserListingDataListener; + this.response = response; + try { + jsonResponse = new JSONObject(response); + parseFailed = false; + userDataArrayList = new ArrayList<>(); + } catch (JSONException e) { + e.printStackTrace(); + parseFailed = true; + } + } + + @Override + protected Void doInBackground(Void... voids) { + try { + if (!parseFailed) { + after = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.AFTER_KEY); + JSONArray children = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + for (int i = 0; i < children.length(); i++) { + userDataArrayList.add(parseUserDataBase(children.getJSONObject(i))); + } + } + } catch (JSONException e) { + parseFailed = true; + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + if (!parseFailed) { + parseUserListingDataListener.onParseUserListingDataSuccess(userDataArrayList, after); + } else { + if (response.equals("\"{}\"")) { + parseUserListingDataListener.onParseUserListingDataSuccess(new ArrayList<>(), null); + } else { + parseUserListingDataListener.onParseUserListingDataFailed(); + } + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserDao.java new file mode 100644 index 00000000..77b12821 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserDao.java @@ -0,0 +1,22 @@ +package ml.docilealligator.infinityforreddit.user; + +import androidx.lifecycle.LiveData; +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; + +@Dao +public interface UserDao { + @Insert(onConflict = OnConflictStrategy.REPLACE) + void insert(UserData userData); + + @Query("DELETE FROM users") + void deleteAllUsers(); + + @Query("SELECT * FROM users WHERE name = :userName COLLATE NOCASE LIMIT 1") + LiveData getUserLiveData(String userName); + + @Query("SELECT * FROM users WHERE name = :userName COLLATE NOCASE LIMIT 1") + UserData getUserData(String userName); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserData.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserData.java new file mode 100644 index 00000000..69b93740 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserData.java @@ -0,0 +1,116 @@ +package ml.docilealligator.infinityforreddit.user; + +import androidx.annotation.NonNull; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; + +@Entity(tableName = "users") +public class UserData { + @PrimaryKey + @NonNull + @ColumnInfo(name = "name") + private String name; + @ColumnInfo(name = "icon") + private String iconUrl; + @ColumnInfo(name = "banner") + private String banner; + @ColumnInfo(name = "link_karma") + private int linkKarma; + @ColumnInfo(name = "comment_karma") + private int commentKarma; + @ColumnInfo(name = "awarder_karma") + private int awarderKarma; + @ColumnInfo(name = "awardee_karma") + private int awardeeKarma; + @ColumnInfo(name = "total_karma") + private int totalKarma; + @ColumnInfo(name = "created_utc") + private long cakeday; + @ColumnInfo(name = "is_gold") + private boolean isGold; + @ColumnInfo(name = "is_friend") + private boolean isFriend; + @ColumnInfo(name = "can_be_followed") + private boolean canBeFollowed; + @ColumnInfo(name = "over_18") + private boolean isNSFW; + @ColumnInfo(name = "description") + private String description; + + public UserData(@NonNull String name, String iconUrl, String banner, int linkKarma, int commentKarma, + int awarderKarma, int awardeeKarma, int totalKarma, long cakeday, boolean isGold, + boolean isFriend, boolean canBeFollowed, boolean isNSFW, String description) { + this.name = name; + this.iconUrl = iconUrl; + this.banner = banner; + this.commentKarma = commentKarma; + this.linkKarma = linkKarma; + this.awarderKarma = awarderKarma; + this.awarderKarma = awardeeKarma; + this.totalKarma = totalKarma; + this.cakeday = cakeday; + this.isGold = isGold; + this.isFriend = isFriend; + this.canBeFollowed = canBeFollowed; + this.isNSFW = isNSFW; + this.description = description; + } + + @NonNull + public String getName() { + return name; + } + + public String getIconUrl() { + return iconUrl; + } + + public String getBanner() { + return banner; + } + + public int getLinkKarma() { + return linkKarma; + } + + public int getCommentKarma() { + return commentKarma; + } + + public int getAwarderKarma() { + return awarderKarma; + } + + public int getAwardeeKarma() { + return awardeeKarma; + } + + public int getTotalKarma() { + return totalKarma; + } + + public long getCakeday() { + return cakeday; + } + + public boolean isGold() { + return isGold; + } + + public boolean isFriend() { + return isFriend; + } + + public boolean isCanBeFollowed() { + return canBeFollowed; + } + + public boolean isNSFW() { + return isNSFW; + } + + public String getDescription() { + return description; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserFollowing.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserFollowing.java new file mode 100644 index 00000000..170ec7ed --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserFollowing.java @@ -0,0 +1,118 @@ +package ml.docilealligator.infinityforreddit.user; + +import android.os.AsyncTask; + +import androidx.annotation.NonNull; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.apis.RedditAPI; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserDao; +import ml.docilealligator.infinityforreddit.subscribeduser.SubscribedUserData; +import ml.docilealligator.infinityforreddit.utils.APIUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Retrofit; + +public class UserFollowing { + public static void followUser(Retrofit oauthRetrofit, Retrofit retrofit, + String accessToken, String username, String accountName, + SubscribedUserDao subscribedUserDao, + UserFollowingListener userFollowingListener) { + userFollowing(oauthRetrofit, retrofit, accessToken, username, accountName, "sub", + subscribedUserDao, userFollowingListener); + } + + public static void unfollowUser(Retrofit oauthRetrofit, Retrofit retrofit, + String accessToken, String username, String accountName, + SubscribedUserDao subscribedUserDao, + UserFollowingListener userFollowingListener) { + userFollowing(oauthRetrofit, retrofit, accessToken, username, accountName, "unsub", + subscribedUserDao, userFollowingListener); + } + + private static void userFollowing(Retrofit oauthRetrofit, Retrofit retrofit, String accessToken, + String username, String accountName, String action, SubscribedUserDao subscribedUserDao, + UserFollowingListener userFollowingListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Map params = new HashMap<>(); + params.put(APIUtils.ACTION_KEY, action); + params.put(APIUtils.SR_NAME_KEY, "u_" + username); + + Call subredditSubscriptionCall = api.subredditSubscription(APIUtils.getOAuthHeader(accessToken), params); + subredditSubscriptionCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull retrofit2.Response response) { + if (response.isSuccessful()) { + if (action.equals("sub")) { + FetchUserData.fetchUserData(retrofit, username, new FetchUserData.FetchUserDataListener() { + @Override + public void onFetchUserDataSuccess(UserData userData) { + new UpdateSubscriptionAsyncTask(subscribedUserDao, userData, accountName, true).execute(); + } + + @Override + public void onFetchUserDataFailed() { + + } + }); + } else { + new UpdateSubscriptionAsyncTask(subscribedUserDao, username, accountName, false).execute(); + } + userFollowingListener.onUserFollowingSuccess(); + } else { + userFollowingListener.onUserFollowingFail(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + userFollowingListener.onUserFollowingFail(); + } + }); + } + + public interface UserFollowingListener { + void onUserFollowingSuccess(); + + void onUserFollowingFail(); + } + + private static class UpdateSubscriptionAsyncTask extends AsyncTask { + + private SubscribedUserDao subscribedUserDao; + private String username; + private String accountName; + private SubscribedUserData subscribedUserData; + private boolean isSubscribing; + + UpdateSubscriptionAsyncTask(SubscribedUserDao subscribedUserDao, String username, + String accountName, boolean isSubscribing) { + this.subscribedUserDao = subscribedUserDao; + this.username = username; + this.accountName = accountName; + this.isSubscribing = isSubscribing; + } + + UpdateSubscriptionAsyncTask(SubscribedUserDao subscribedUserDao, UserData userData, + String accountName, boolean isSubscribing) { + this.subscribedUserDao = subscribedUserDao; + this.subscribedUserData = new SubscribedUserData(userData.getName(), userData.getIconUrl(), + accountName, false); + this.accountName = accountName; + this.isSubscribing = isSubscribing; + } + + @Override + protected Void doInBackground(Void... voids) { + if (isSubscribing) { + subscribedUserDao.insert(subscribedUserData); + } else { + subscribedUserDao.deleteSubscribedUser(username, accountName); + } + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSource.java new file mode 100644 index 00000000..614a0303 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSource.java @@ -0,0 +1,106 @@ +package ml.docilealligator.infinityforreddit.user; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.PageKeyedDataSource; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +public class UserListingDataSource extends PageKeyedDataSource { + + private Retrofit retrofit; + private String query; + private SortType sortType; + private boolean nsfw; + + private MutableLiveData paginationNetworkStateLiveData; + private MutableLiveData initialLoadStateLiveData; + private MutableLiveData hasUserLiveData; + + private PageKeyedDataSource.LoadParams params; + private PageKeyedDataSource.LoadCallback callback; + + UserListingDataSource(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { + this.retrofit = retrofit; + this.query = query; + this.sortType = sortType; + this.nsfw = nsfw; + paginationNetworkStateLiveData = new MutableLiveData<>(); + initialLoadStateLiveData = new MutableLiveData<>(); + hasUserLiveData = new MutableLiveData<>(); + } + + MutableLiveData getPaginationNetworkStateLiveData() { + return paginationNetworkStateLiveData; + } + + MutableLiveData getInitialLoadStateLiveData() { + return initialLoadStateLiveData; + } + + MutableLiveData hasUserLiveData() { + return hasUserLiveData; + } + + @Override + public void loadInitial(@NonNull PageKeyedDataSource.LoadInitialParams params, @NonNull PageKeyedDataSource.LoadInitialCallback callback) { + initialLoadStateLiveData.postValue(NetworkState.LOADING); + + FetchUserData.fetchUserListingData(retrofit, query, null, sortType.getType().value, nsfw, + new FetchUserData.FetchUserListingDataListener() { + @Override + public void onFetchUserListingDataSuccess(ArrayList UserData, String after) { + if (UserData.size() == 0) { + hasUserLiveData.postValue(false); + } else { + hasUserLiveData.postValue(true); + } + + callback.onResult(UserData, null, after); + initialLoadStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onFetchUserListingDataFailed() { + initialLoadStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving ml.docilealligator.infinityforreddit.User list")); + } + }); + } + + @Override + public void loadBefore(@NonNull PageKeyedDataSource.LoadParams params, @NonNull PageKeyedDataSource.LoadCallback callback) { + + } + + @Override + public void loadAfter(@NonNull PageKeyedDataSource.LoadParams params, @NonNull PageKeyedDataSource.LoadCallback callback) { + this.params = params; + this.callback = callback; + + if (params.key.equals("null") || params.key.equals("")) { + return; + } + + FetchUserData.fetchUserListingData(retrofit, query, params.key, sortType.getType().value, nsfw, + new FetchUserData.FetchUserListingDataListener() { + @Override + public void onFetchUserListingDataSuccess(ArrayList UserData, String after) { + callback.onResult(UserData, after); + paginationNetworkStateLiveData.postValue(NetworkState.LOADED); + } + + @Override + public void onFetchUserListingDataFailed() { + paginationNetworkStateLiveData.postValue(new NetworkState(NetworkState.Status.FAILED, "Error retrieving ml.docilealligator.infinityforreddit.User list")); + } + }); + } + + void retryLoadingMore() { + loadAfter(params, callback); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSourceFactory.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSourceFactory.java new file mode 100644 index 00000000..c764cec6 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingDataSourceFactory.java @@ -0,0 +1,46 @@ +package ml.docilealligator.infinityforreddit.user; + +import androidx.annotation.NonNull; +import androidx.lifecycle.MutableLiveData; +import androidx.paging.DataSource; + +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +public class UserListingDataSourceFactory extends DataSource.Factory { + private Retrofit retrofit; + private String query; + private SortType sortType; + private boolean nsfw; + + private UserListingDataSource userListingDataSource; + private MutableLiveData userListingDataSourceMutableLiveData; + + UserListingDataSourceFactory(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { + this.retrofit = retrofit; + this.query = query; + this.sortType = sortType; + this.nsfw = nsfw; + userListingDataSourceMutableLiveData = new MutableLiveData<>(); + } + + @NonNull + @Override + public DataSource create() { + userListingDataSource = new UserListingDataSource(retrofit, query, sortType, nsfw); + userListingDataSourceMutableLiveData.postValue(userListingDataSource); + return userListingDataSource; + } + + public MutableLiveData getUserListingDataSourceMutableLiveData() { + return userListingDataSourceMutableLiveData; + } + + UserListingDataSource getUserListingDataSource() { + return userListingDataSource; + } + + void changeSortType(SortType sortType) { + this.sortType = sortType; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingViewModel.java new file mode 100644 index 00000000..054e3dfb --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserListingViewModel.java @@ -0,0 +1,96 @@ +package ml.docilealligator.infinityforreddit.user; + +import androidx.annotation.NonNull; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.lifecycle.Transformations; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; +import androidx.paging.LivePagedListBuilder; +import androidx.paging.PagedList; + +import ml.docilealligator.infinityforreddit.NetworkState; +import ml.docilealligator.infinityforreddit.SortType; +import retrofit2.Retrofit; + +public class UserListingViewModel extends ViewModel { + private UserListingDataSourceFactory userListingDataSourceFactory; + private LiveData paginationNetworkState; + private LiveData initialLoadingState; + private LiveData hasUserLiveData; + private LiveData> users; + private MutableLiveData sortTypeLiveData; + + public UserListingViewModel(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { + userListingDataSourceFactory = new UserListingDataSourceFactory(retrofit, query, sortType, nsfw); + + initialLoadingState = Transformations.switchMap(userListingDataSourceFactory.getUserListingDataSourceMutableLiveData(), + UserListingDataSource::getInitialLoadStateLiveData); + paginationNetworkState = Transformations.switchMap(userListingDataSourceFactory.getUserListingDataSourceMutableLiveData(), + UserListingDataSource::getPaginationNetworkStateLiveData); + hasUserLiveData = Transformations.switchMap(userListingDataSourceFactory.getUserListingDataSourceMutableLiveData(), + UserListingDataSource::hasUserLiveData); + + sortTypeLiveData = new MutableLiveData<>(); + sortTypeLiveData.postValue(sortType); + + PagedList.Config pagedListConfig = + (new PagedList.Config.Builder()) + .setEnablePlaceholders(false) + .setPageSize(25) + .build(); + + users = Transformations.switchMap(sortTypeLiveData, sort -> { + userListingDataSourceFactory.changeSortType(sortTypeLiveData.getValue()); + return (new LivePagedListBuilder(userListingDataSourceFactory, pagedListConfig)).build(); + }); + } + + public LiveData> getUsers() { + return users; + } + + public LiveData getPaginationNetworkState() { + return paginationNetworkState; + } + + public LiveData getInitialLoadingState() { + return initialLoadingState; + } + + public LiveData hasUser() { + return hasUserLiveData; + } + + public void refresh() { + userListingDataSourceFactory.getUserListingDataSource().invalidate(); + } + + public void retryLoadingMore() { + userListingDataSourceFactory.getUserListingDataSource().retryLoadingMore(); + } + + public void changeSortType(SortType sortType) { + sortTypeLiveData.postValue(sortType); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + private Retrofit retrofit; + private String query; + private SortType sortType; + private boolean nsfw; + + public Factory(Retrofit retrofit, String query, SortType sortType, boolean nsfw) { + this.retrofit = retrofit; + this.query = query; + this.sortType = sortType; + this.nsfw = nsfw; + } + + @NonNull + @Override + public T create(@NonNull Class modelClass) { + return (T) new UserListingViewModel(retrofit, query, sortType, nsfw); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserRepository.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserRepository.java new file mode 100644 index 00000000..8d8101a3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserRepository.java @@ -0,0 +1,40 @@ +package ml.docilealligator.infinityforreddit.user; + +import android.os.AsyncTask; + +import androidx.lifecycle.LiveData; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class UserRepository { + private UserDao mUserDao; + private LiveData mUserLiveData; + + UserRepository(RedditDataRoomDatabase redditDataRoomDatabase, String userName) { + mUserDao = redditDataRoomDatabase.userDao(); + mUserLiveData = mUserDao.getUserLiveData(userName); + } + + LiveData getUserLiveData() { + return mUserLiveData; + } + + public void insert(UserData userData) { + new InsertAsyncTask(mUserDao).execute(userData); + } + + private static class InsertAsyncTask extends AsyncTask { + + private UserDao mAsyncTaskDao; + + InsertAsyncTask(UserDao dao) { + mAsyncTaskDao = dao; + } + + @Override + protected Void doInBackground(final UserData... params) { + mAsyncTaskDao.insert(params[0]); + return null; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserViewModel.java new file mode 100644 index 00000000..0857a42a --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/user/UserViewModel.java @@ -0,0 +1,50 @@ +package ml.docilealligator.infinityforreddit.user; + +import android.app.Application; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.ViewModel; +import androidx.lifecycle.ViewModelProvider; + +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; + +public class UserViewModel extends AndroidViewModel { + private UserRepository mSubredditRepository; + private LiveData mUserLiveData; + + public UserViewModel(Application application, RedditDataRoomDatabase redditDataRoomDatabase, String id) { + super(application); + mSubredditRepository = new UserRepository(redditDataRoomDatabase, id); + mUserLiveData = mSubredditRepository.getUserLiveData(); + } + + public LiveData getUserLiveData() { + return mUserLiveData; + } + + public void insert(UserData userData) { + mSubredditRepository.insert(userData); + } + + public static class Factory extends ViewModelProvider.NewInstanceFactory { + + @NonNull + private final Application mApplication; + private final RedditDataRoomDatabase mRedditDataRoomDatabase; + private final String mUsername; + + public Factory(@NonNull Application application, RedditDataRoomDatabase redditDataRoomDatabase, String username) { + mApplication = application; + mRedditDataRoomDatabase = redditDataRoomDatabase; + mUsername = username; + } + + @Override + public T create(Class modelClass) { + //noinspection unchecked + return (T) new UserViewModel(mApplication, mRedditDataRoomDatabase, mUsername); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java new file mode 100644 index 00000000..ae1b767c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/APIUtils.java @@ -0,0 +1,123 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.util.Base64; + +import java.util.HashMap; +import java.util.Map; + +import okhttp3.MediaType; +import okhttp3.RequestBody; + +/** + * Created by alex on 2/23/18. + */ + +public class APIUtils { + public static final String OAUTH_URL = "https://www.reddit.com/api/v1/authorize.compact"; + public static final String OAUTH_API_BASE_URI = "https://oauth.reddit.com"; + public static final String API_BASE_URI = "https://www.reddit.com"; + public static final String API_UPLOAD_MEDIA_URI = "https://reddit-uploaded-media.s3-accelerate.amazonaws.com"; + public static final String API_UPLOAD_VIDEO_URI = "https://reddit-uploaded-video.s3-accelerate.amazonaws.com"; + public static final String GFYCAT_API_BASE_URI = "https://api.gfycat.com/v1/gfycats/"; + public static final String REDGIFS_API_BASE_URI = "https://api.redgifs.com/v1/gfycats/"; + public static final String IMGUR_API_BASE_URI = "https://api.imgur.com/3/"; + public static final String PUSHSHIFT_API_BASE_URI = "https://api.pushshift.io/"; + + public static final String CLIENT_ID_KEY = "client_id"; + public static final String CLIENT_ID = "NOe2iKrPPzwscA"; + public static final String IMGUR_CLIENT_ID = "Client-ID cc671794e0ab397"; + public static final String RESPONSE_TYPE_KEY = "response_type"; + public static final String RESPONSE_TYPE = "code"; + public static final String STATE_KEY = "state"; + public static final String STATE = "23ro8xlxvzp4asqd"; + public static final String REDIRECT_URI_KEY = "redirect_uri"; + public static final String REDIRECT_URI = "infinity://localhost"; + public static final String DURATION_KEY = "duration"; + public static final String DURATION = "permanent"; + public static final String SCOPE_KEY = "scope"; + public static final String SCOPE = "identity edit flair history modconfig modflair modlog modposts modwiki mysubreddits privatemessages read report save submit subscribe vote wikiedit wikiread creddits modcontributors modmail modothers livemanage account modself"; + public static final String ACCESS_TOKEN_KEY = "access_token"; + + public static final String AUTHORIZATION_KEY = "Authorization"; + public static final String AUTHORIZATION_BASE = "bearer "; + public static final String USER_AGENT_KEY = "User-Agent"; + public static final String USER_AGENT = "android:ml.docilealligator.infinityforreddit:v4.1.0-beta5 (by /u/Hostilenemy)"; + + public static final String GRANT_TYPE_KEY = "grant_type"; + public static final String GRANT_TYPE_REFRESH_TOKEN = "refresh_token"; + public static final String REFRESH_TOKEN_KEY = "refresh_token"; + + public static final String DIR_KEY = "dir"; + public static final String ID_KEY = "id"; + public static final String RANK_KEY = "rank"; + public static final String DIR_UPVOTE = "1"; + public static final String DIR_UNVOTE = "0"; + public static final String DIR_DOWNVOTE = "-1"; + public static final String RANK = "10"; + + public static final String ACTION_KEY = "action"; + public static final String SR_NAME_KEY = "sr_name"; + + public static final String API_TYPE_KEY = "api_type"; + public static final String API_TYPE_JSON = "json"; + public static final String RETURN_RTJSON_KEY = "return_rtjson"; + public static final String TEXT_KEY = "text"; + public static final String URL_KEY = "url"; + public static final String VIDEO_POSTER_URL_KEY = "video_poster_url"; + public static final String THING_ID_KEY = "thing_id"; + + public static final String SR_KEY = "sr"; + public static final String TITLE_KEY = "title"; + public static final String FLAIR_TEXT_KEY = "flair_text"; + public static final String SPOILER_KEY = "spoiler"; + public static final String NSFW_KEY = "nsfw"; + public static final String CROSSPOST_FULLNAME_KEY = "crosspost_fullname"; + public static final String KIND_KEY = "kind"; + public static final String KIND_SELF = "self"; + public static final String KIND_LINK = "link"; + public static final String KIND_IMAGE = "image"; + public static final String KIND_VIDEO = "video"; + public static final String KIND_VIDEOGIF = "videogif"; + public static final String KIND_CROSSPOST = "crosspost"; + + public static final String FILEPATH_KEY = "filepath"; + public static final String MIMETYPE_KEY = "mimetype"; + + public static final String LINK_KEY = "link"; + public static final String FLAIR_TEMPLATE_ID_KEY = "flair_template_id"; + public static final String FLAIR_ID_KEY = "flair_id"; + + public static final String MAKE_FAVORITE_KEY = "make_favorite"; + + public static final String MULTIPATH_KEY = "multipath"; + public static final String MODEL_KEY = "model"; + + public static final String REASON_KEY = "reason"; + + public static final String SUBJECT_KEY = "subject"; + public static final String TO_KEY = "to"; + + public static final String NAME_KEY = "name"; + + public static final String GILD_TYPE = "gild_type"; + public static final String IS_ANONYMOUS = "is_anonymous"; + + public static Map getHttpBasicAuthHeader() { + Map params = new HashMap<>(); + String credentials = String.format("%s:%s", APIUtils.CLIENT_ID, ""); + String auth = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); + params.put(APIUtils.AUTHORIZATION_KEY, auth); + return params; + } + + public static Map getOAuthHeader(String accessToken) { + Map params = new HashMap<>(); + params.put(APIUtils.AUTHORIZATION_KEY, APIUtils.AUTHORIZATION_BASE + accessToken); + params.put(APIUtils.USER_AGENT_KEY, APIUtils.USER_AGENT); + return params; + } + + public static RequestBody getRequestBody(String s) { + return RequestBody.create(MediaType.parse("text/plain"), s); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/CustomThemeSharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/CustomThemeSharedPreferencesUtils.java new file mode 100644 index 00000000..0f3e991c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/CustomThemeSharedPreferencesUtils.java @@ -0,0 +1,173 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.content.SharedPreferences; + +import ml.docilealligator.infinityforreddit.customtheme.CustomTheme; + +public class CustomThemeSharedPreferencesUtils { + public static final int LIGHT = 0; + public static final int DARK = 1; + public static final int AMOLED = 2; + public static final String LIGHT_THEME_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.light_theme"; + public static final String DARK_THEME_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.dark_theme"; + public static final String AMOLED_THEME_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.amoled_theme"; + public static final String LIGHT_STATUS_BAR = "lightStatusBar"; + public static final String LIGHT_NAV_BAR = "lightNavBar"; + public static final String CHANGE_STATUS_BAR_ICON_COLOR_AFTER_TOOLBAR_COLLAPSED_IN_IMMERSIVE_INTERFACE = "changeStatusBarIconColorImmersive"; + public static final String COLOR_PRIMARY = "colorPrimary"; + public static final String COLOR_PRIMARY_DARK = "colorPrimaryDark"; + public static final String COLOR_ACCENT = "colorAccent"; + public static final String COLOR_PRIMARY_LIGHT_THEME = "colorPrimaryLightTheme"; + public static final String POST_TITLE_COLOR = "postTitleColor"; + public static final String POST_CONTENT_COLOR = "postContentColor"; + public static final String COMMENT_COLOR = "commentColor"; + public static final String PRIMARY_TEXT_COLOR = "primaryTextColor"; + public static final String SECONDARY_TEXT_COLOR = "secondaryTextColor"; + public static final String BUTTON_TEXT_COLOR = "buttonTextColor"; + public static final String BACKGROUND_COLOR = "backgroundColor"; + public static final String CARD_VIEW_BACKGROUND_COLOR = "cardViewBackgroundColor"; + 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"; + public static final String BOTTOM_APP_BAR_ICON_COLOR = "bottomAppBarIconColor"; + public static final String POST_ICON_AND_INFO_COLOR = "postIconAndInfoColor"; + public static final String COMMENT_ICON_AND_INFO_COLOR = "commentIconAndInfoColor"; + public static final String TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR = "toolbarPrimaryTextAndIconColor"; + public static final String TOOLBAR_SECONDARY_TEXT_COLOR = "toolbarSecondaryTextColor"; + public static final String CIRCULAR_PROGRESS_BAR_BACKGROUND = "circularProgressBarBackground"; + public static final String TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND = "tabLayoutWithExpandedCollapsingToolbarTabBackground"; + public static final String TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR = "tabLayoutWithExpandedCollapsingToolbarTextColor"; + public static final String TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR = "tabLayoutWithExpandedCollapsingToolbarTabIndicator"; + public static final String TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND = "tabLayoutWithCollapsedCollapsingToolbarTabBackground"; + public static final String TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR = "tabLayoutWithCollapsedCollapsingToolbarTextColor"; + public static final String TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR = "tabLayoutWithCollapsedCollapsingToolbarTabIndicator"; + public static final String NAV_BAR_COLOR = "navBarColor"; + public static final String UPVOTED = "upvoted"; + public static final String DOWNVOTED = "downvoted"; + public static final String POST_TYPE_BACKGROUND_COLOR = "postTypeBackgroundColor"; + public static final String POST_TYPE_TEXT_COLOR = "postTypeTextColor"; + public static final String SPOILER_BACKGROUND_COLOR = "spoilerBackgroundColor"; + public static final String SPOILER_TEXT_COLOR = "spoilerTextColor"; + public static final String NSFW_BACKGROUND_COLOR = "nsfwBackgroundColor"; + public static final String NSFW_TEXT_COLOR = "nsfwTextColor"; + public static final String FLAIR_BACKGROUND_COLOR = "flairBackgroundColor"; + public static final String FLAIR_TEXT_COLOR = "flairTextColor"; + public static final String AWARDS_BACKGROUND_COLOR = "awardsBackgroundColor"; + public static final String AWARDS_TEXT_COLOR = "awardsTextColor"; + public static final String ARCHIVED_ICON_TINT = "archivedIconTint"; + public static final String LOCKED_ICON_TINT = "lockedIconTint"; + public static final String CROSSPOST_ICON_TINT = "crosspostIconTint"; + public static final String STICKIED_POST_ICON_TINT = "stickiedPost"; + public static final String NO_PREVIEW_POST_TYPE_ICON_TINT = "noPreviewPostTypeIconTint"; + public static final String SUBSCRIBED = "subscribed"; + public static final String UNSUBSCRIBED = "unsubscribed"; + public static final String USERNAME = "username"; + public static final String SUBREDDIT = "subreddit"; + public static final String AUTHOR_FLAIR_TEXT_COLOR = "authorFlairTextColor"; + public static final String SUBMITTER = "submitter"; + public static final String MODERATOR = "moderator"; + public static final String SINGLE_COMMENT_THREAD_BACKGROUND_COLOR = "singleCommentThreadBackgroundColor"; + public static final String UNREAD_MESSAGE_BACKGROUND_COLOR = "unreadMessageBackgroundColor"; + public static final String DIVIDER_COLOR = "dividerColor"; + public static final String NO_PREVIEW_POST_TYPE_BACKGROUND_COLOR = "noPreviewLinkBackgroundColor"; + public static final String VOTE_AND_REPLY_UNAVAILABLE_BUTTON_COLOR = "voteAndReplyUnavailableButtonColor"; + public static final String COMMENT_VERTICAL_BAR_COLOR_1 = "commentVerticalBarColor1"; + public static final String COMMENT_VERTICAL_BAR_COLOR_2 = "commentVerticalBarColor2"; + public static final String COMMENT_VERTICAL_BAR_COLOR_3 = "commentVerticalBarColor3"; + public static final String COMMENT_VERTICAL_BAR_COLOR_4 = "commentVerticalBarColor4"; + public static final String COMMENT_VERTICAL_BAR_COLOR_5 = "commentVerticalBarColor5"; + public static final String COMMENT_VERTICAL_BAR_COLOR_6 = "commentVerticalBarColor6"; + public static final String COMMENT_VERTICAL_BAR_COLOR_7 = "commentVerticalBarColor7"; + public static final String FAB_ICON_COLOR = "fabIconColor"; + public static final String CHIP_TEXT_COLOR = "chipTextColor"; + public static final String LINK_COLOR = "linkColor"; + public static final String RECEIVED_MESSAGE_TEXT_COLOR = "receivedMessageTextColor"; + public static final String SENT_MESSAGE_TEXT_COLOR = "sentMessageTextColor"; + public static final String RECEIVED_MESSAGE_BACKROUND_COLOR = "receivedMessageBackgroundColor"; + public static final String SENT_MESSAGE_BACKGROUND_COLOR = "sentMessageBackgroundColor"; + public static final String SEND_MESSAGE_ICON_COLOR = "sentMessageIconColor"; + public static final String FULLY_COLLAPSED_COMMENT_BACKGROUND_COLOR = "fullyCollapsedCommentBackgroundColor"; + public static final String AWARDED_COMMENT_BACKGROUND_COLOR = "awardedCommentBackgroundColor"; + + public static void insertThemeToSharedPreferences(CustomTheme customTheme, SharedPreferences themeSharedPreferences) { + SharedPreferences.Editor editor = themeSharedPreferences.edit(); + editor.putInt(COLOR_PRIMARY, customTheme.colorPrimary); + editor.putInt(COLOR_PRIMARY_DARK, customTheme.colorPrimaryDark); + editor.putInt(COLOR_ACCENT, customTheme.colorAccent); + editor.putInt(COLOR_PRIMARY_LIGHT_THEME, customTheme.colorPrimaryLightTheme); + editor.putInt(PRIMARY_TEXT_COLOR, customTheme.primaryTextColor); + editor.putInt(SECONDARY_TEXT_COLOR, customTheme.secondaryTextColor); + editor.putInt(POST_TITLE_COLOR, customTheme.postTitleColor); + editor.putInt(POST_CONTENT_COLOR, customTheme.postContentColor); + editor.putInt(COMMENT_COLOR, customTheme.commentColor); + editor.putInt(BUTTON_TEXT_COLOR, customTheme.buttonTextColor); + editor.putInt(BACKGROUND_COLOR, customTheme.backgroundColor); + editor.putInt(CARD_VIEW_BACKGROUND_COLOR, customTheme.cardViewBackgroundColor); + editor.putInt(COMMENT_BACKGROUND_COLOR, customTheme.commentBackgroundColor); + editor.putInt(BOTTOM_APP_BAR_BACKGROUND_COLOR, customTheme.bottomAppBarBackgroundColor); + editor.putInt(PRIMARY_ICON_COLOR, customTheme.primaryIconColor); + editor.putInt(BOTTOM_APP_BAR_ICON_COLOR, customTheme.bottomAppBarIconColor); + editor.putInt(POST_ICON_AND_INFO_COLOR, customTheme.postIconAndInfoColor); + editor.putInt(COMMENT_ICON_AND_INFO_COLOR, customTheme.commentIconAndInfoColor); + editor.putInt(TOOLBAR_PRIMARY_TEXT_AND_ICON_COLOR, customTheme.toolbarPrimaryTextAndIconColor); + editor.putInt(TOOLBAR_SECONDARY_TEXT_COLOR, customTheme.toolbarSecondaryTextColor); + editor.putInt(CIRCULAR_PROGRESS_BAR_BACKGROUND, customTheme.circularProgressBarBackground); + editor.putInt(TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, customTheme.tabLayoutWithExpandedCollapsingToolbarTabBackground); + editor.putInt(TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TEXT_COLOR, customTheme.tabLayoutWithExpandedCollapsingToolbarTextColor); + editor.putInt(TAB_LAYOUT_WITH_EXPANDED_COLLAPSING_TOOLBAR_TAB_INDICATOR, customTheme.tabLayoutWithExpandedCollapsingToolbarTabIndicator); + editor.putInt(TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_BACKGROUND, customTheme.tabLayoutWithCollapsedCollapsingToolbarTabBackground); + editor.putInt(TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TEXT_COLOR, customTheme.tabLayoutWithCollapsedCollapsingToolbarTextColor); + editor.putInt(TAB_LAYOUT_WITH_COLLAPSED_COLLAPSING_TOOLBAR_TAB_INDICATOR, customTheme.tabLayoutWithCollapsedCollapsingToolbarTabIndicator); + editor.putInt(NAV_BAR_COLOR, customTheme.navBarColor); + editor.putInt(UPVOTED, customTheme.upvoted); + editor.putInt(DOWNVOTED, customTheme.downvoted); + editor.putInt(POST_TYPE_BACKGROUND_COLOR, customTheme.postTypeBackgroundColor); + editor.putInt(POST_TYPE_TEXT_COLOR, customTheme.postTypeTextColor); + editor.putInt(SPOILER_BACKGROUND_COLOR, customTheme.spoilerBackgroundColor); + editor.putInt(SPOILER_TEXT_COLOR, customTheme.spoilerTextColor); + editor.putInt(NSFW_BACKGROUND_COLOR, customTheme.nsfwBackgroundColor); + editor.putInt(NSFW_TEXT_COLOR, customTheme.nsfwTextColor); + editor.putInt(FLAIR_BACKGROUND_COLOR, customTheme.flairBackgroundColor); + editor.putInt(FLAIR_TEXT_COLOR, customTheme.flairTextColor); + editor.putInt(AWARDS_BACKGROUND_COLOR, customTheme.awardsBackgroundColor); + editor.putInt(AWARDS_TEXT_COLOR, customTheme.awardsTextColor); + editor.putInt(ARCHIVED_ICON_TINT, customTheme.archivedTint); + editor.putInt(LOCKED_ICON_TINT, customTheme.lockedIconTint); + editor.putInt(CROSSPOST_ICON_TINT, customTheme.crosspostIconTint); + editor.putInt(STICKIED_POST_ICON_TINT, customTheme.stickiedPostIconTint); + editor.putInt(NO_PREVIEW_POST_TYPE_ICON_TINT, customTheme.noPreviewPostTypeIconTint); + editor.putInt(SUBSCRIBED, customTheme.subscribed); + editor.putInt(UNSUBSCRIBED, customTheme.unsubscribed); + editor.putInt(USERNAME, customTheme.username); + editor.putInt(SUBREDDIT, customTheme.subreddit); + editor.putInt(AUTHOR_FLAIR_TEXT_COLOR, customTheme.authorFlairTextColor); + editor.putInt(SUBMITTER, customTheme.submitter); + editor.putInt(MODERATOR, customTheme.moderator); + editor.putInt(SINGLE_COMMENT_THREAD_BACKGROUND_COLOR, customTheme.singleCommentThreadBackgroundColor); + editor.putInt(UNREAD_MESSAGE_BACKGROUND_COLOR, customTheme.unreadMessageBackgroundColor); + editor.putInt(DIVIDER_COLOR, customTheme.dividerColor); + editor.putInt(NO_PREVIEW_POST_TYPE_BACKGROUND_COLOR, customTheme.noPreviewPostTypeBackgroundColor); + editor.putInt(VOTE_AND_REPLY_UNAVAILABLE_BUTTON_COLOR, customTheme.voteAndReplyUnavailableButtonColor); + editor.putInt(COMMENT_VERTICAL_BAR_COLOR_1, customTheme.commentVerticalBarColor1); + editor.putInt(COMMENT_VERTICAL_BAR_COLOR_2, customTheme.commentVerticalBarColor2); + editor.putInt(COMMENT_VERTICAL_BAR_COLOR_3, customTheme.commentVerticalBarColor3); + editor.putInt(COMMENT_VERTICAL_BAR_COLOR_4, customTheme.commentVerticalBarColor4); + editor.putInt(COMMENT_VERTICAL_BAR_COLOR_5, customTheme.commentVerticalBarColor5); + editor.putInt(COMMENT_VERTICAL_BAR_COLOR_6, customTheme.commentVerticalBarColor6); + editor.putInt(COMMENT_VERTICAL_BAR_COLOR_7, customTheme.commentVerticalBarColor7); + editor.putInt(FAB_ICON_COLOR, customTheme.fabIconColor); + editor.putInt(CHIP_TEXT_COLOR, customTheme.chipTextColor); + editor.putInt(LINK_COLOR, customTheme.linkColor); + editor.putInt(RECEIVED_MESSAGE_TEXT_COLOR, customTheme.receivedMessageTextColor); + editor.putInt(SENT_MESSAGE_TEXT_COLOR, customTheme.sentMessageTextColor); + editor.putInt(RECEIVED_MESSAGE_BACKROUND_COLOR, customTheme.receivedMessageBackgroundColor); + editor.putInt(SENT_MESSAGE_BACKGROUND_COLOR, customTheme.sentMessageBackgroundColor); + editor.putInt(SEND_MESSAGE_ICON_COLOR, customTheme.sendMessageIconColor); + editor.putInt(FULLY_COLLAPSED_COMMENT_BACKGROUND_COLOR, customTheme.fullyCollapsedCommentBackgroundColor); + editor.putInt(AWARDED_COMMENT_BACKGROUND_COLOR, customTheme.awardedCommentBackgroundColor); + editor.putBoolean(LIGHT_STATUS_BAR, customTheme.isLightStatusBar); + editor.putBoolean(LIGHT_NAV_BAR, customTheme.isLightNavBar); + editor.putBoolean(CHANGE_STATUS_BAR_ICON_COLOR_AFTER_TOOLBAR_COLLAPSED_IN_IMMERSIVE_INTERFACE, customTheme.isChangeStatusBarIconColorAfterToolbarCollapsedInImmersiveInterface); + editor.apply(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/GetPathUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/GetPathUtils.java new file mode 100644 index 00000000..2424b167 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/GetPathUtils.java @@ -0,0 +1,238 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.annotation.TargetApi; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +import androidx.core.content.ContextCompat; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class GetPathUtils { + + private static final String PATH_TREE = "tree"; + private static final String PRIMARY_TYPE = "primary"; + private static final String RAW_TYPE = "raw"; + + @TargetApi(Build.VERSION_CODES.KITKAT) + public static String getFilePathFromUri(final Context context, final Uri uri) { + + // DocumentProvider + if (DocumentsContract.isDocumentUri(context, uri)) { + // ExternalStorageProvider + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + //Timber.d("docId -> %s", docId); + final String[] split = docId.split(":"); + final String type = split[0]; + + if (PRIMARY_TYPE.equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } else { + // TODO handle non-primary volumes + StringBuilder path = new StringBuilder(); + String pathSegment[] = docId.split(":"); + return path.append(getRemovableStorageRootPath(context, pathSegment[0])).append(File.separator).append(pathSegment[1]).toString(); + } + } else if (isDownloadsDocument(uri)) { // DownloadsProvider + + final String id = DocumentsContract.getDocumentId(uri); + + if (id.contains("raw:")) { + return id.substring(id.indexOf(File.separator)); + } else { + Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } + + } else if (isMediaDocument(uri)) { // MediaProvider + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri = null; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{ + split[1] + }; + + return getDataColumn(context, contentUri, selection, selectionArgs); + } + } else if ("content".equalsIgnoreCase(uri.getScheme())) { // MediaStore (and general) + return getDataColumn(context, uri, null, null); + } else if ("file".equalsIgnoreCase(uri.getScheme())) { // File + return uri.getPath(); + } + + return null; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + + Cursor cursor = null; + final String column = MediaStore.MediaColumns.DATA; + final String[] projection = {column}; + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + final int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } finally { + if (cursor != null) + cursor.close(); + } + + return null; + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } + + /** + * @param uri + * @return file path of Uri + */ + public static String getDirectoryPathFromUri(Context context, Uri uri) { + + if ("file".equals(uri.getScheme())) { + return uri.getPath(); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT + && isTreeUri(uri)) { + + String treeId = getTreeDocumentId(uri); + + if (treeId != null) { + String[] paths = treeId.split(":"); + String type = paths[0]; + String subPath = paths.length == 2 ? paths[1] : ""; + + if (RAW_TYPE.equalsIgnoreCase(type)) { + return treeId.substring(treeId.indexOf(File.separator)); + } else if (PRIMARY_TYPE.equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + File.separator + subPath; + } else { + StringBuilder path = new StringBuilder(); + String[] pathSegment = treeId.split(":"); + if (pathSegment.length == 1) { + path.append(getRemovableStorageRootPath(context, paths[0])); + } else { + String rootPath = getRemovableStorageRootPath(context, paths[0]); + path.append(rootPath).append(File.separator).append(pathSegment[1]); + } + + return path.toString(); + } + } + } + return null; + } + + private static String getRemovableStorageRootPath(Context context, String storageId) { + StringBuilder rootPath = new StringBuilder(); + File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null); + for (File fileDir : externalFilesDirs) { + if (fileDir.getPath().contains(storageId)) { + String[] pathSegment = fileDir.getPath().split(File.separator); + for (String segment : pathSegment) { + if (segment.equals(storageId)) { + rootPath.append(storageId); + break; + } + rootPath.append(segment).append(File.separator); + } + //rootPath.append(fileDir.getPath().split("/Android")[0]); // faster + break; + } + } + return rootPath.toString(); + } + + @TargetApi(Build.VERSION_CODES.LOLLIPOP) + public static List getListRemovableStorage(Context context) { + + List paths = new ArrayList<>(); + + File[] externalFilesDirs = ContextCompat.getExternalFilesDirs(context, null); + for (File fileDir : externalFilesDirs) { + if (Environment.isExternalStorageRemovable(fileDir)) { + String path = fileDir.getPath(); + if (path.contains("/Android")) { + paths.add(path.substring(0, path.indexOf("/Android"))); + } + } + } + + return paths; + } + + //https://github.com/rcketscientist/DocumentActivity/blob/master/library/src/main/java/com/anthonymandra/framework/DocumentUtil.java#L56 + /** + * Extract the via {@link DocumentsContract.Document#COLUMN_DOCUMENT_ID} from the given URI. + * From {@link DocumentsContract} but return null instead of throw + */ + public static String getTreeDocumentId(Uri uri) { + final List paths = uri.getPathSegments(); + if (paths.size() >= 2 && PATH_TREE.equals(paths.get(0))) { + return paths.get(1); + } + return null; + } + + public static boolean isTreeUri(Uri uri) { + final List paths = uri.getPathSegments(); + return (paths.size() == 2 && PATH_TREE.equals(paths.get(0))); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/GlideImageGetter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/GlideImageGetter.java new file mode 100644 index 00000000..ee729d96 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/GlideImageGetter.java @@ -0,0 +1,173 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.app.Activity; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.text.Html; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.Request; +import com.bumptech.glide.request.target.SizeReadyCallback; +import com.bumptech.glide.request.target.Target; +import com.bumptech.glide.request.transition.Transition; + +import java.lang.ref.WeakReference; + +public class GlideImageGetter implements Html.ImageGetter { + + private WeakReference container; + private boolean matchParentWidth; + private boolean enlargeImage; + private HtmlImagesHandler imagesHandler; + private float density = 1.0f; + private float textSize; + + public GlideImageGetter(TextView textView, boolean enlargeImage) { + this(textView, false, false, null); + this.enlargeImage = enlargeImage; + } + + public GlideImageGetter(TextView textView, boolean matchParentWidth, HtmlImagesHandler imagesHandler) { + this(textView, matchParentWidth, false, imagesHandler); + } + + public GlideImageGetter(TextView textView, boolean matchParentWidth, boolean densityAware, + @Nullable HtmlImagesHandler imagesHandler) { + this.container = new WeakReference<>(textView); + this.matchParentWidth = matchParentWidth; + this.imagesHandler = imagesHandler; + if (densityAware) { + density = container.get().getResources().getDisplayMetrics().density; + } + textSize = container.get().getTextSize(); + } + + @Override + public Drawable getDrawable(String source) { + if (imagesHandler != null) { + imagesHandler.addImage(source); + } + + BitmapDrawablePlaceholder drawable = new BitmapDrawablePlaceholder(textSize); + + Context context = container.get().getContext(); + if (!(context instanceof Activity && (((Activity) context).isFinishing() || ((Activity) context).isDestroyed()))) { + container.get().post(() -> Glide.with(context) + .asBitmap() + .load(source) + .into(drawable)); + } + + return drawable; + } + + private class BitmapDrawablePlaceholder extends BitmapDrawable implements Target { + + protected Drawable drawable; + + BitmapDrawablePlaceholder(float textSize) { + super(container.get().getResources(), + Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888)); + } + + @Override + public void draw(final Canvas canvas) { + if (drawable != null) { + drawable.draw(canvas); + } + } + + private void setDrawable(Drawable drawable) { + this.drawable = drawable; + int drawableWidth = (int) (drawable.getIntrinsicWidth() * density); + int drawableHeight = (int) (drawable.getIntrinsicHeight() * density); + float ratio = (float) drawableWidth / (float) drawableHeight; + drawableHeight = enlargeImage ? (int) (textSize * 1.5) : (int) textSize; + drawableWidth = (int) (drawableHeight * ratio); + int maxWidth = container.get().getMeasuredWidth(); + if ((maxWidth > 0 && (drawableWidth > maxWidth)) || matchParentWidth) { + int calculatedHeight = maxWidth * drawableHeight / drawableWidth; + drawable.setBounds(0, 0, maxWidth, calculatedHeight); + setBounds(0, 0, maxWidth, calculatedHeight); + } else { + drawable.setBounds(0, 0, drawableWidth, drawableHeight); + setBounds(0, 0, drawableWidth, drawableHeight); + } + + container.get().setText(container.get().getText()); + } + + @Override + public void onLoadStarted(@Nullable Drawable placeholderDrawable) { + if(placeholderDrawable != null) { + setDrawable(placeholderDrawable); + } + } + + @Override + public void onLoadFailed(@Nullable Drawable errorDrawable) { + if (errorDrawable != null) { + setDrawable(errorDrawable); + } + } + + @Override + public void onResourceReady(@NonNull Bitmap bitmap, @Nullable Transition transition) { + if (container != null) { + TextView textView = container.get(); + if (textView != null) { + Resources resources = textView.getResources(); + if (resources != null) { + setDrawable(new BitmapDrawable(resources, bitmap)); + } + } + } + } + + @Override + public void onLoadCleared(@Nullable Drawable placeholderDrawable) { + if(placeholderDrawable != null) { + setDrawable(placeholderDrawable); + } + } + + @Override + public void getSize(@NonNull SizeReadyCallback cb) { + cb.onSizeReady(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL); + } + + @Override + public void removeCallback(@NonNull SizeReadyCallback cb) {} + + @Override + public void setRequest(@Nullable Request request) {} + + @Nullable + @Override + public Request getRequest() { + return null; + } + + @Override + public void onStart() {} + + @Override + public void onStop() {} + + @Override + public void onDestroy() {} + + } + + public interface HtmlImagesHandler { + void addImage(String uri); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java new file mode 100644 index 00000000..7832d74c --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/JSONUtils.java @@ -0,0 +1,133 @@ +package ml.docilealligator.infinityforreddit.utils; + +/** + * Created by alex on 2/25/18. + */ + +public class JSONUtils { + public static final String KIND_KEY = "kind"; + public static final String DATA_KEY = "data"; + public static final String AFTER_KEY = "after"; + public static final String CHILDREN_KEY = "children"; + public static final String COUNT_KEY = "count"; + public static final String TITLE_KEY = "title"; + public static final String NAME_KEY = "name"; + public static final String SUBREDDIT_NAME_PREFIX_KEY = "subreddit_name_prefixed"; + public static final String SELFTEXT_KEY = "selftext"; + public static final String SELFTEXT_HTML_KEY = "selftext_html"; + public static final String AUTHOR_KEY = "author"; + public static final String AUTHOR_FLAIR_RICHTEXT_KEY = "author_flair_richtext"; + public static final String AUTHOR_FLAIR_TEXT_KEY = "author_flair_text"; + public static final String E_KEY = "e"; + public static final String T_KEY = "t"; + public static final String U_KEY = "u"; + public static final String LINK_KEY = "link"; + public static final String LINK_AUTHOR_KEY = "link_author"; + public static final String LINK_FLAIR_TEXT_KEY = "link_flair_text"; + public static final String LINK_FLAIR_RICHTEXT_KEY = "link_flair_richtext"; + public static final String SCORE_KEY = "score"; + public static final String LIKES_KEY = "likes"; + public static final String NSFW_KEY = "over_18"; + public static final String PERMALINK_KEY = "permalink"; + public static final String CREATED_UTC_KEY = "created_utc"; + public static final String PREVIEW_KEY = "preview"; + public static final String IMAGES_KEY = "images"; + public static final String WIDTH_KEY = "width"; + public static final String HEIGHT_KEY = "height"; + public static final String SOURCE_KEY = "source"; + public static final String URL_KEY = "url"; + public static final String MEDIA_KEY = "media"; + public static final String REDDIT_VIDEO_KEY = "reddit_video"; + public static final String HLS_URL_KEY = "hls_url"; + public static final String FALLBACK_URL_KEY = "fallback_url"; + public static final String IS_VIDEO_KEY = "is_video"; + public static final String CROSSPOST_PARENT_LIST = "crosspost_parent_list"; + public static final String REDDIT_VIDEO_PREVIEW_KEY = "reddit_video_preview"; + public static final String STICKIED_KEY = "stickied"; + public static final String BODY_KEY = "body"; + public static final String BODY_HTML_KEY = "body_html"; + public static final String COLLAPSED_KEY = "collapsed"; + public static final String IS_SUBMITTER_KEY = "is_submitter"; + public static final String REPLIES_KEY = "replies"; + public static final String DEPTH_KEY = "depth"; + public static final String ID_KEY = "id"; + public static final String SCORE_HIDDEN_KEY = "score_hidden"; + public static final String SUBREDDIT_KEY = "subreddit"; + public static final String BANNER_IMG_KEY = "banner_img"; + public static final String BANNER_BACKGROUND_IMAGE_KEY = "banner_background_image"; + public static final String ICON_IMG_KEY = "icon_img"; + public static final String ICON_URL_KEY = "icon_url"; + public static final String COMMUNITY_ICON_KEY = "community_icon"; + public static final String LINK_KARMA_KEY = "link_karma"; + public static final String COMMENT_KARMA_KEY = "comment_karma"; + public static final String DISPLAY_NAME_KEY = "display_name"; + public static final String SUBREDDIT_TYPE_KEY = "subreddit_type"; + public static final String SUBREDDIT_TYPE_VALUE_USER = "user"; + public static final String SUBSCRIBERS_KEY = "subscribers"; + public static final String PUBLIC_DESCRIPTION_KEY = "public_description"; + public static final String ACTIVE_USER_COUNT_KEY = "active_user_count"; + public static final String IS_GOLD_KEY = "is_gold"; + public static final String IS_FRIEND_KEY = "is_friend"; + public static final String JSON_KEY = "json"; + public static final String PARENT_ID_KEY = "parent_id"; + public static final String LINK_ID_KEY = "link_id"; + public static final String LINK_TITLE_KEY = "link_title"; + public static final String ERRORS_KEY = "errors"; + public static final String ARGS_KEY = "args"; + public static final String FIELDS_KEY = "fields"; + public static final String VALUE_KEY = "value"; + public static final String TEXT_KEY = "text"; + public static final String SPOILER_KEY = "spoiler"; + public static final String RULES_KEY = "rules"; + public static final String SHORT_NAME_KEY = "short_name"; + public static final String DESCRIPTION_KEY = "description"; + public static final String DESCRIPTION_HTML_KEY = "description_html"; + public static final String DESCRIPTION_MD_KEY = "description_md"; + public static final String ARCHIVED_KEY = "archived"; + public static final String LOCKEC_KEY = "locked"; + public static final String SAVED_KEY = "saved"; + public static final String TEXT_EDITABLE_KEY = "text_editable"; + public static final String SUBJECT_KEY = "subject"; + public static final String CONTEXT_KEY = "context"; + public static final String DISTINGUISHED_KEY = "distinguished"; + public static final String WAS_COMMENT_KEY = "was_comment"; + public static final String NEW_KEY = "new"; + public static final String NUM_COMMENTS_KEY = "num_comments"; + public static final String HIDDEN_KEY = "hidden"; + public static final String USER_HAS_FAVORITED_KEY = "user_has_favorited"; + public static final String RESOLUTIONS_KEY = "resolutions"; + public static final String NUM_SUBSCRIBERS_KEY = "num_subscribers"; + public static final String COPIED_FROM_KEY = "copied_from"; + public static final String VISIBILITY_KEY = "visibility"; + public static final String OVER_18_KEY = "over_18"; + public static final String OWNER_KEY = "owner"; + public static final String IS_SUBSCRIBER_KEY = "is_subscriber"; + public static final String IS_FAVORITED_KEY = "is_favorited"; + public static final String SUBREDDITS_KEY = "subreddits"; + public static final String PATH_KEY = "path"; + public static final String ALL_AWARDINGS_KEY = "all_awardings"; + public static final String RESIZED_ICONS_KEY = "resized_icons"; + public static final String GFY_ITEM_KEY = "gfyItem"; + public static final String MP4_URL_KEY = "mp4Url"; + public static final String WEBM_URL_KEY = "webmUrl"; + public static final String TYPE_KEY = "type"; + public static final String MP4_KEY = "mp4"; + public static final String THINGS_KEY = "things"; + public static final String MEDIA_METADATA_KEY = "media_metadata"; + public static final String GALLERY_DATA_KEY = "gallery_data"; + public static final String ITEMS_KEY = "items"; + public static final String M_KEY = "m"; + public static final String MEDIA_ID_KEY = "media_id"; + public static final String S_KEY = "s"; + public static final String X_KEY = "x"; + public static final String Y_KEY = "y"; + public static final String DEST_KEY = "dest"; + public static final String GIF_KEY = "gif"; + public static final String MAX_EMOJIS_KEY = "max_emojis"; + public static final String RICHTEXT_KEY = "richtext"; + public static final String SUGGESTED_COMMENT_SORT_KEY = "suggested_comment_sort"; + public static final String OVER18_KEY = "over18"; + public static final String TOTAL_KARMA_KEY = "total_karma"; + public static final String AWARDER_KARMA_KEY = "awarder_karma"; + public static final String AWARDEE_KARMA_KEY = "awardee_karma"; +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java new file mode 100644 index 00000000..940838af --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/NotificationUtils.java @@ -0,0 +1,91 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.content.Context; + +import androidx.core.app.NotificationCompat; +import androidx.core.app.NotificationManagerCompat; + +import ml.docilealligator.infinityforreddit.R; + +public class NotificationUtils { + public static final String CHANNEL_SUBMIT_POST = "Submit Post"; + public static final String CHANNEL_ID_NEW_MESSAGES = "new_messages"; + public static final String CHANNEL_NEW_MESSAGES = "New Messages"; + public static final String CHANNEL_ID_DOWNLOAD_REDDIT_VIDEO = "download_reddit_video"; + public static final String CHANNEL_DOWNLOAD_REDDIT_VIDEO = "Download Reddit Video"; + public static final String CHANNEL_ID_DOWNLOAD_VIDEO = "download_video"; + public static final String CHANNEL_DOWNLOAD_VIDEO = "Download Video"; + public static final String CHANNEL_ID_DOWNLOAD_IMAGE = "download_image"; + public static final String CHANNEL_DOWNLOAD_IMAGE = "Download Image"; + public static final String CHANNEL_ID_DOWNLOAD_GIF = "download_gif"; + public static final String CHANNEL_DOWNLOAD_GIF = "Download Gif"; + public static final int SUBMIT_POST_SERVICE_NOTIFICATION_ID = 10000; + public static final int DOWNLOAD_REDDIT_VIDEO_NOTIFICATION_ID = 20000; + public static final int DOWNLOAD_VIDEO_NOTIFICATION_ID = 30000; + public static final int DOWNLOAD_IMAGE_NOTIFICATION_ID = 40000; + public static final int DOWNLOAD_GIF_NOTIFICATION_ID = 50000; + public static final int PULL_NOTIFICATION_ALARM_RECEIVER_REQUEST_CODE = 12; + + private static final int SUMMARY_BASE_ID_UNREAD_MESSAGE = 0; + private static final int NOTIFICATION_BASE_ID_UNREAD_MESSAGE = 1; + + private static final String GROUP_USER_BASE = "ml.docilealligator.infinityforreddit."; + + public static NotificationCompat.Builder buildNotification(NotificationManagerCompat notificationManager, + Context context, String title, String content, + String summary, String channelId, String channelName, + String group, int color) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); + notificationManager.createNotificationChannel(channel); + } + + return new NotificationCompat.Builder(context.getApplicationContext(), channelId) + .setContentTitle(title) + .setContentText(content) + .setSmallIcon(R.drawable.ic_notification) + .setColor(color) + .setStyle(new NotificationCompat.BigTextStyle() + .setSummaryText(summary) + .bigText(content)) + .setGroup(group) + .setAutoCancel(true); + } + + public static NotificationCompat.Builder buildSummaryNotification(Context context, NotificationManagerCompat notificationManager, + String title, String content, String channelId, + String channelName, String group, int color) { + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_DEFAULT); + notificationManager.createNotificationChannel(channel); + } + + return new NotificationCompat.Builder(context, channelId) + .setContentTitle(title) + //set content text to support devices running API level < 24 + .setContentText(content) + .setSmallIcon(R.drawable.ic_notification) + .setColor(color) + .setGroup(group) + .setGroupSummary(true) + .setAutoCancel(true); + } + + public static NotificationManagerCompat getNotificationManager(Context context) { + return NotificationManagerCompat.from(context); + } + + public static String getAccountGroupName(String accountName) { + return GROUP_USER_BASE + accountName; + } + + public static int getSummaryIdUnreadMessage(int accountIndex) { + return SUMMARY_BASE_ID_UNREAD_MESSAGE + accountIndex * 1000; + } + + public static int getNotificationIdUnreadMessage(int accountIndex, int messageIndex) { + return NOTIFICATION_BASE_ID_UNREAD_MESSAGE + accountIndex * 1000 + messageIndex; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java new file mode 100644 index 00000000..ebfa20fe --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java @@ -0,0 +1,235 @@ +package ml.docilealligator.infinityforreddit.utils; + +/** + * Created by alex on 2/23/18. + */ + +public class SharedPreferencesUtils { + public static final String ENABLE_NOTIFICATION_KEY = "enable_notification"; + public static final String NOTIFICATION_INTERVAL_KEY = "notificaiton_interval"; + public static final String LAZY_MODE_INTERVAL_KEY = "lazy_mode_interval"; + public static final String THEME_KEY = "theme"; + public static final String ICON_FOREGROUND_KEY = "icon_foreground"; + public static final String ICON_BACKGROUND_KEY = "icon_background"; + public static final String ERROR_IMAGE_KEY = "error_image"; + public static final String GILDED_ICON_KEY = "gilded_icon"; + public static final String CROSSPOST_ICON_KEY = "crosspost_icon"; + public static final String THUMBTACK_ICON_KEY = "thumbtack_icon"; + public static final String BEST_ROCKET_ICON_KEY = "best_rocket_icon"; + public static final String MATERIAL_ICONS_KEY = "material_icons"; + public static final String OPEN_SOURCE_KEY = "open_source"; + public static final String RATE_KEY = "rate"; + public static final String F_DROID_KEY = "f-droid"; + public static final String EMAIL_KEY = "email"; + public static final String REDDIT_ACCOUNT_KEY = "reddit_account"; + public static final String SUBREDDIT_KEY = "subreddit"; + public static final String SHARE_KEY = "share"; + public static final String VERSION_KEY = "version"; + public static final String FONT_SIZE_KEY = "font_size"; + public static final String TITLE_FONT_SIZE_KEY = "title_font_size"; + public static final String CONTENT_FONT_SIZE_KEY = "content_font_size"; + public static final String FONT_FAMILY_KEY = "font_family"; + public static final String TITLE_FONT_FAMILY_KEY = "title_font_family"; + public static final String CONTENT_FONT_FAMILY_KEY = "content_font_family"; + public static final String AMOLED_DARK_KEY = "amoled_dark"; + public static final String IMMERSIVE_INTERFACE_ENTRY_KEY = "immersive_interface_entry"; + public static final String IMMERSIVE_INTERFACE_KEY = "immersive_interface"; + public static final String IMMERSIVE_INTERFACE_IGNORE_NAV_BAR_KEY = "immersive_interface_ignore_nav_bar"; + public static final String BOTTOM_APP_BAR_KEY = "bottom_app_bar"; + public static final String VOTE_BUTTONS_ON_THE_RIGHT_KEY = "vote_buttons_on_the_right"; + + public static final String SORT_TYPE_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.sort_type"; + public static final String SORT_TYPE_BEST_POST = "sort_type_best_post"; + public static final String SORT_TIME_BEST_POST = "sort_time_best_post"; + public static final String SORT_TYPE_SEARCH_POST = "sort_type_search_post"; + public static final String SORT_TIME_SEARCH_POST = "sort_time_search_post"; + public static final String SORT_TYPE_SUBREDDIT_POST_BASE = "sort_type_subreddit_post_"; + public static final String SORT_TIME_SUBREDDIT_POST_BASE = "sort_time_subreddit_post_"; + public static final String SORT_TYPE_MULTI_REDDIT_POST_BASE = "sort_type_multi_reddit_post_"; + public static final String SORT_TIME_MULTI_REDDIT_POST_BASE = "sort_time_multi_reddit_post_"; + public static final String SORT_TYPE_USER_POST_BASE = "sort_type_user_post_"; + public static final String SORT_TIME_USER_POST_BASE = "sort_time_user_post_"; + public static final String SORT_TYPE_USER_COMMENT = "sort_type_user_comment"; + public static final String SORT_TIME_USER_COMMENT = "sort_time_user_comment"; + public static final String SORT_TYPE_SEARCH_SUBREDDIT = "sort_type_search_subreddit"; + public static final String SORT_TYPE_SEARCH_USER = "sort_type_search_user"; + public static final String SORT_TYPE_POST_COMMENT = "sort_type_post_comment"; + + public static final String POST_LAYOUT_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.post_layout"; + public static final String POST_LAYOUT_FRONT_PAGE_POST = "post_layout_best_post"; + public static final String POST_LAYOUT_SUBREDDIT_POST_BASE = "post_layout_subreddit_post_"; + public static final String POST_LAYOUT_MULTI_REDDIT_POST_BASE = "post_layout_multi_reddit_post_"; + public static final String POST_LAYOUT_USER_POST_BASE = "post_layout_user_post_"; + public static final String POST_LAYOUT_SEARCH_POST = "post_layout_search_post"; + public static final int POST_LAYOUT_CARD = 0; + public static final int POST_LAYOUT_COMPACT = 1; + + public static final String FRONT_PAGE_SCROLLED_POSITION_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.front_page_scrolled_position"; + public static final String FRONT_PAGE_SCROLLED_POSITION_FRONT_PAGE_BASE = "_front_page"; + public static final String FRONT_PAGE_SCROLLED_POSITION_ANONYMOUS = ".anonymous"; + + public static final String PULL_NOTIFICATION_TIME = "pull_notification_time"; + public static final String SHOW_ELAPSED_TIME_KEY = "show_elapsed_time"; + public static final String TIME_FORMAT_KEY = "time_format"; + public static final String TIME_FORMAT_DEFAULT_VALUE = "MMM d, yyyy, HH:mm"; + public static final String DEFAULT_POST_LAYOUT_KEY = "default_post_layout"; + public static final String SHOW_DIVIDER_IN_COMPACT_LAYOUT = "show_divider_in_compact_layout"; + public static final String SHOW_THUMBNAIL_ON_THE_LEFT_IN_COMPACT_LAYOUT = "show_thumbnail_on_the_left_in_compact_layout"; + public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_PORTRAIT = "number_of_columns_in_post_feed_portrait"; + public static final String NUMBER_OF_COLUMNS_IN_POST_FEED_LANDSCAPE = "number_of_columns_in_post_feed_landscape"; + public static final String SWIPE_RIGHT_TO_GO_BACK = "swipe_to_go_back_from_post_detail"; + public static final String VOLUME_KEYS_NAVIGATE_COMMENTS = "volume_keys_navigate_comments"; + public static final String VOLUME_KEYS_NAVIGATE_POSTS = "volume_keys_navigate_posts"; + public static final String MUTE_VIDEO = "mute_video"; + public static final String OPEN_LINK_IN_APP = "open_link_in_app"; + public static final String VIDEO_AUTOPLAY = "video_autoplay"; + public static final String VIDEO_AUTOPLAY_VALUE_ALWAYS_ON = "2"; + public static final String VIDEO_AUTOPLAY_VALUE_ON_WIFI = "1"; + public static final String VIDEO_AUTOPLAY_VALUE_NEVER = "0"; + public static final String MUTE_AUTOPLAYING_VIDEOS = "mute_autoplaying_videos"; + public static final String AUTOPLAY_NSFW_VIDEOS = "autoplay_nsfw_videos"; + public static final String AUTOMATICALLY_TRY_REDGIFS = "automatically_try_redgifs"; + public static final String LOCK_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON = "lock_jump_to_next_top_level_comment_button"; + public static final String SWAP_TAP_AND_LONG_COMMENTS = "swap_tap_and_long_in_comments"; + public static final String SWIPE_UP_TO_HIDE_JUMP_TO_NEXT_TOP_LEVEL_COMMENT_BUTTON = "swipe_up_to_hide_jump_to_next_top_level_comments_button"; + public static final String SHOW_TOP_LEVEL_COMMENTS_FIRST = "show_top_level_comments_first"; + public static final String CONFIRM_TO_EXIT = "confirm_to_exit"; + public static final String LOCK_BOTTOM_APP_BAR = "lock_bottom_app_bar"; + public static final String COMMENT_TOOLBAR_HIDDEN = "comment_toolbar_hidden"; + public static final String COMMENT_TOOLBAR_HIDE_ON_CLICK = "comment_toolbar_hide_on_click"; + public static final String FULLY_COLLAPSE_COMMENT = "fully_collapse_comment"; + public static final String SHOW_COMMENT_DIVIDER = "show_comment_divider"; + public static final String SHOW_ABSOLUTE_NUMBER_OF_VOTES = "show_absolute_number_of_votes"; + public static final String CUSTOMIZE_LIGHT_THEME = "customize_light_theme"; + public static final String CUSTOMIZE_DARK_THEME = "customize_dark_theme"; + public static final String CUSTOMIZE_AMOLED_THEME = "customize_amoled_theme"; + public static final String MANAGE_THEMES = "manage_themes"; + public static final String DELETE_ALL_SUBREDDITS_DATA_IN_DATABASE = "delete_all_subreddits_data_in_database"; + public static final String DELETE_ALL_USERS_DATA_IN_DATABASE = "delete_all_users_data_in_database"; + public static final String DELETE_ALL_SORT_TYPE_DATA_IN_DATABASE = "delete_all_sort_type_data_in_database"; + public static final String DELETE_ALL_POST_LAYOUT_DATA_IN_DATABASE = "delete_all_post_layout_data_in_database"; + public static final String DELETE_ALL_THEMES_IN_DATABASE = "delete_all_themes_in_database"; + public static final String DELETE_FRONT_PAGE_SCROLLED_POSITIONS_IN_DATABASE = "delete_front_page_scrolled_positions_in_database"; + public static final String DELETE_ALL_LEGACY_SETTINGS = "delete_all_legacy_settings"; + public static final String RESET_ALL_SETTINGS = "reset_all_settings"; + public static final String IMAGE_DOWNLOAD_LOCATION = "image_download_location"; + public static final String GIF_DOWNLOAD_LOCATION = "gif_download_location"; + public static final String VIDEO_DOWNLOAD_LOCATION = "video_download_location"; + public static final String SEPARATE_FOLDER_FOR_EACH_SUBREDDIT = "separate_folder_for_each_subreddit"; + public static final String VIBRATE_WHEN_ACTION_TRIGGERED = "vibrate_when_action_triggered"; + public static final String DISABLE_SWIPING_BETWEEN_TABS = "disable_swiping_between_tabs"; + public static final String ENABLE_SWIPE_ACTION = "enable_swipe_action"; + public static final String SWIPE_ACTION_THRESHOLD = "swipe_action_threshold"; + public static final String PULL_TO_REFRESH = "pull_to_refresh"; + public static final String REQUIRE_AUTHENTICATION_TO_GO_TO_ACCOUNT_SECTION_IN_NAVIGATION_DRAWER = "require_auth_to_account_section"; + public static final String LONG_PRESS_TO_HIDE_TOOLBAR_IN_COMPACT_LAYOUT = "long_press_to_hide_toolbar_in_compact_layout"; + public static final String POST_COMPACT_LAYOUT_TOOLBAR_HIDDEN_BY_DEFAULT = "post_compact_layout_toolbar_hidden_by_default"; + public static final String SECURITY = "security"; + public static final String START_AUTOPLAY_VISIBLE_AREA_OFFSET_PORTRAIT = "start_autoplay_visible_area_offset_portrait"; + public static final String START_AUTOPLAY_VISIBLE_AREA_OFFSET_LANDSCAPE = "start_autoplay_visible_area_offset_landscape"; + public static final String MUTE_NSFW_VIDEO = "mute_nsfw_video"; + public static final String VIDEO_PLAYER_IGNORE_NAV_BAR = "video_player_ignore_nav_bar"; + public static final String SAVE_FRONT_PAGE_SCROLLED_POSITION = "save_front_page_scrolled_position"; + public static final String DATA_SAVING_MODE = "data_saving_mode"; + public static final String DATA_SAVING_MODE_OFF = "0"; + public static final String DATA_SAVING_MODE_ONLY_ON_CELLULAR_DATA = "1"; + public static final String DATA_SAVING_MODE_ALWAYS = "2"; + public static final String NATIONAL_FLAGS = "national_flags"; + public static final String RESPECT_SUBREDDIT_RECOMMENDED_COMMENT_SORT_TYPE = "respect_subreddit_recommended_comment_sort_type"; + public static final String SUBREDDIT_FILTER_POPULAR_AND_ALL = "subreddit_filter_popular_and_all"; + public static final String UFO_CAPTURING_ANIMATION = "ufo_capturing_animation"; + public static final String HIDE_SUBREDDIT_DESCRIPTION = "hide_subreddit_description"; + public static final String DISABLE_IMAGE_PREVIEW = "disable_image_preview"; + public static final String SWIPE_LEFT_ACTION = "swipe_left_action"; + public static final String SWIPE_RIGHT_ACTION = "swipe_right_action"; + public static final int SWIPE_ACITON_UPVOTE = 0; + public static final int SWIPE_ACITON_DOWNVOTE = 1; + + public static final String MAIN_PAGE_TABS_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.main_page_tabs"; + public static final String MAIN_PAGE_TAB_COUNT = "_main_page_tab_count"; + public static final String MAIN_PAGE_SHOW_TAB_NAMES = "_main_page_show_tab_names"; + public static final String MAIN_PAGE_TAB_1_TITLE = "_main_page_tab_1_title"; + public static final String MAIN_PAGE_TAB_2_TITLE = "_main_page_tab_2_title"; + public static final String MAIN_PAGE_TAB_3_TITLE = "_main_page_tab_3_title"; + public static final String MAIN_PAGE_TAB_1_POST_TYPE = "_main_page_tab_1_post_type"; + public static final String MAIN_PAGE_TAB_2_POST_TYPE = "_main_page_tab_2_post_type"; + public static final String MAIN_PAGE_TAB_3_POST_TYPE = "_main_page_tab_3_post_type"; + public static final String MAIN_PAGE_TAB_1_NAME = "_main_page_tab_1_name"; + public static final String MAIN_PAGE_TAB_2_NAME = "_main_page_tab_2_name"; + public static final String MAIN_PAGE_TAB_3_NAME = "_main_page_tab_3_name"; + public static final int MAIN_PAGE_TAB_POST_TYPE_HOME = 0; + public static final int MAIN_PAGE_TAB_POST_TYPE_POPULAR = 1; + public static final int MAIN_PAGE_TAB_POST_TYPE_ALL = 2; + public static final int MAIN_PAGE_TAB_POST_TYPE_SUBREDDIT = 3; + public static final int MAIN_PAGE_TAB_POST_TYPE_MULTIREDDIT = 4; + public static final int MAIN_PAGE_TAB_POST_TYPE_USER = 5; + public static final String MAIN_PAGE_SHOW_SUBSCRIBED_SUBREDDITS = "_main_page_show_subscribed_subreddits"; + public static final String MAIN_PAGE_SHOW_FAVORITE_SUBSCRIBED_SUBREDDITS = "_main_page_show_favorite_subscribed_subreddits"; + + public static final String BOTTOM_APP_BAR_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.bottom_app_bar"; + public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_COUNT = "main_activity_bottom_app_bar_option_count"; + public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_1 = "main_activity_bottom_app_bar_option_1"; + public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_2 = "main_activity_bottom_app_bar_option_2"; + public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_3 = "main_activity_bottom_app_bar_option_3"; + public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_4 = "main_activity_bottom_app_bar_option_4"; + public static final String MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB = "main_activity_bottom_app_bar_fab"; + public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_COUNT = "other_activities_bottom_app_bar_option_count"; + public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_1 = "other_activities_bottom_app_bar_option_1"; + public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_2 = "other_activities_bottom_app_bar_option_2"; + public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_3 = "other_activities_bottom_app_bar_option_3"; + public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_4 = "other_activities_bottom_app_bar_option_4"; + public static final String OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB = "other_activities_bottom_app_bar_fab"; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS = 0; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_MULTIREDDITS = 1; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_INBOX = 2; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_OPTION_PROFILE = 3; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS = 0; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_REFRESH = 1; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE = 2; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT = 3; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_SEARCH = 4; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT = 5; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_GO_TO_USER = 6; + public static final int MAIN_ACTIVITY_BOTTOM_APP_BAR_FAB_RANDOM = 7; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_HOME = 0; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_SUBSCRIPTIONS = 1; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_INBOX = 2; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_PROFILE = 3; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_OPTION_MULTIREDDITS = 4; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SUBMIT_POSTS = 0; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_REFRESH = 1; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_SORT_TYPE = 2; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_CHANGE_POST_LAYOUT = 3; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_SEARCH = 4; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_SUBREDDIT = 5; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_GO_TO_USER = 6; + public static final int OTHER_ACTIVITIES_BOTTOM_APP_BAR_FAB_RANDOM = 7; + + public static final String NSFW_AND_SPOILER_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.nsfw_and_spoiler"; + public static final String NSFW_BASE = "_nsfw"; + public static final String BLUR_NSFW_BASE = "_blur_nsfw"; + public static final String BLUR_SPOILER_BASE = "_blur_spoiler"; + + //Legacy Settings + public static final String MAIN_PAGE_TAB_1_TITLE_LEGACY = "main_page_tab_1_title"; + public static final String MAIN_PAGE_TAB_2_TITLE_LEGACY = "main_page_tab_2_title"; + public static final String MAIN_PAGE_TAB_3_TITLE_LEGACY = "main_page_tab_3_title"; + public static final String MAIN_PAGE_TAB_1_POST_TYPE_LEGACY = "main_page_tab_1_post_type"; + public static final String MAIN_PAGE_TAB_2_POST_TYPE_LEGACY = "main_page_tab_2_post_type"; + public static final String MAIN_PAGE_TAB_3_POST_TYPE_LEGACY = "main_page_tab_3_post_type"; + public static final String MAIN_PAGE_TAB_1_NAME_LEGACY = "main_page_tab_1_name"; + public static final String MAIN_PAGE_TAB_2_NAME_LEGACY = "main_page_tab_2_name"; + public static final String MAIN_PAGE_TAB_3_NAME_LEGACY = "main_page_tab_3_name"; + + public static final String SORT_TYPE_ALL_POST_LEGACY = "sort_type_all_post"; + public static final String SORT_TIME_ALL_POST_LEGACY = "sort_time_all_post"; + public static final String SORT_TYPE_POPULAR_POST_LEGACY = "sort_type_popular_post"; + public static final String SORT_TIME_POPULAR_POST_LEGACY = "sort_time_popular_post"; + + public static final String POST_LAYOUT_POPULAR_POST_LEGACY = "post_layout_popular_post"; + public static final String POST_LAYOUT_ALL_POST_LEGACY = "post_layout_all_post"; + + public static final String NSFW_KEY_LEGACY = "nsfw"; + public static final String BLUR_NSFW_KEY_LEGACY = "blur_nsfw"; + public static final String BLUR_SPOILER_KEY_LEGACY = "blur_spoiler"; +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java new file mode 100644 index 00000000..8d51256d --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/Utils.java @@ -0,0 +1,266 @@ +package ml.docilealligator.infinityforreddit.utils; + +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.net.ConnectivityManager; +import android.net.Network; +import android.net.NetworkCapabilities; +import android.net.NetworkInfo; +import android.os.Build; +import android.text.Html; +import android.text.Spannable; +import android.util.DisplayMetrics; +import android.view.inputmethod.InputMethodManager; +import android.widget.TextView; + +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.core.graphics.drawable.DrawableCompat; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Locale; + +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.SortType; + +public class Utils { + public static final int NETWORK_TYPE_OTHER = -1; + public static final int NETWORK_TYPE_WIFI = 0; + public static final int NETWORK_TYPE_CELLULAR = 1; + private static final long SECOND_MILLIS = 1000; + private static final long MINUTE_MILLIS = 60 * SECOND_MILLIS; + private static final long HOUR_MILLIS = 60 * MINUTE_MILLIS; + private static final long DAY_MILLIS = 24 * HOUR_MILLIS; + private static final long MONTH_MILLIS = 30 * DAY_MILLIS; + private static final long YEAR_MILLIS = 12 * MONTH_MILLIS; + + public static String modifyMarkdown(String markdown) { + StringBuilder regexed = new StringBuilder(markdown.replaceAll("((?<=[\\s])|^)/[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com$0)").replaceAll("((?<=[\\s])|^)[rRuU]/[\\w-]+/{0,1}", "[$0](https://www.reddit.com/$0)")); + + /*int startIndex = 0; + + Pattern pattern = Pattern.compile("\\^.+"); + Matcher matcher = pattern.matcher(regexed); + // Check all occurrences + while (matcher.find(startIndex)) { + int count = 0; + Pattern pattern2 = Pattern.compile("(\\^\\([^)]+\\))"); + Matcher matcher2 = pattern2.matcher(matcher.group()); + if (matcher2.find()) { + regexed.setCharAt(matcher2.end() + matcher.start() - 1, '^'); + regexed.deleteCharAt(matcher2.start() + matcher.start() + 1); + + startIndex = matcher.start() + matcher2.end(); + String substring = regexed.substring(matcher.start() + matcher2.start() + 1, matcher.start() + matcher2.end() - 2); + String trimmedSubstring = substring.trim(); + regexed.replace(matcher.start() + matcher2.start() + 1, matcher.start() + matcher2.end() - 2, trimmedSubstring); + startIndex -= (substring.length() - trimmedSubstring.length()); + continue; + } + + regexed.insert(matcher.end(), '^'); + + for (int i = matcher.end() - 1; i >= matcher.start() + 1; i--) { + if (regexed.charAt(i) == '^') { + regexed.deleteCharAt(i); + count++; + } + } + startIndex = matcher.end() - count; + }*/ + return regexed.toString(); + } + + public static CharSequence trimTrailingWhitespace(CharSequence source) { + + if(source == null) + return ""; + + int i = source.length(); + + // loop back to the first non-whitespace character + do { + i--; + } while (i >= 0 && Character.isWhitespace(source.charAt(i))); + + return source.subSequence(0, i+1); + } + + public static String getFormattedTime(Locale locale, long time, String pattern) { + Calendar postTimeCalendar = Calendar.getInstance(); + postTimeCalendar.setTimeInMillis(time); + return new SimpleDateFormat(pattern, locale).format(postTimeCalendar.getTime()); + } + + public static String getElapsedTime(Context context, long time) { + long now = System.currentTimeMillis(); + long diff = now - time; + + if (diff < MINUTE_MILLIS) { + return context.getString(R.string.elapsed_time_just_now); + } else if (diff < 2 * MINUTE_MILLIS) { + return context.getString(R.string.elapsed_time_a_minute_ago); + } else if (diff < 50 * MINUTE_MILLIS) { + return context.getString(R.string.elapsed_time_minutes_ago, diff / MINUTE_MILLIS); + } else if (diff < 120 * MINUTE_MILLIS) { + return context.getString(R.string.elapsed_time_an_hour_ago); + } else if (diff < 24 * HOUR_MILLIS) { + return context.getString(R.string.elapsed_time_hours_ago, diff / HOUR_MILLIS); + } else if (diff < 48 * HOUR_MILLIS) { + return context.getString(R.string.elapsed_time_yesterday); + } else if (diff < MONTH_MILLIS) { + return context.getString(R.string.elapsed_time_days_ago, diff / DAY_MILLIS); + } else if (diff < 2 * MONTH_MILLIS) { + return context.getString(R.string.elapsed_time_a_month_ago); + } else if (diff < YEAR_MILLIS) { + return context.getString(R.string.elapsed_time_months_ago, diff / MONTH_MILLIS); + } else if (diff < 2 * YEAR_MILLIS) { + return context.getString(R.string.elapsed_time_a_year_ago); + } else { + return context.getString(R.string.elapsed_time_years_ago, diff / YEAR_MILLIS); + } + } + + public static String getNVotes(boolean showAbsoluteNumberOfVotes, int votes) { + if (showAbsoluteNumberOfVotes) { + return Integer.toString(votes); + } else { + if (Math.abs(votes) < 1000) { + return Integer.toString(votes); + } + return String.format(Locale.US, "%.1f", (float) votes / 1000) + "K"; + } + } + + public static void setHTMLWithImageToTextView(TextView textView, String content, boolean enlargeImage) { + Spannable html; + GlideImageGetter glideImageGetter = new GlideImageGetter(textView, enlargeImage); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + html = (Spannable) Html.fromHtml(content, Html.FROM_HTML_MODE_LEGACY, glideImageGetter, null); + } else { + html = (Spannable) Html.fromHtml(content, glideImageGetter, null); + } + textView.setText(html); + } + + public static int getConnectedNetwork(Context context) { + ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (connMgr != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Network nw = connMgr.getActiveNetwork(); + if (nw == null) return NETWORK_TYPE_OTHER; + NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); + if (actNw != null) { + if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) { + return NETWORK_TYPE_WIFI; + } + if (actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) { + return NETWORK_TYPE_CELLULAR; + } + } + return NETWORK_TYPE_OTHER; + } else { + boolean isWifi = false; + boolean isCellular = false; + for (Network network : connMgr.getAllNetworks()) { + NetworkInfo networkInfo = connMgr.getNetworkInfo(network); + if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { + isWifi = true; + } + if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) { + isCellular = true; + } + } + + if (isWifi) { + return NETWORK_TYPE_WIFI; + } + + if (isCellular) { + return NETWORK_TYPE_CELLULAR; + } + + return NETWORK_TYPE_OTHER; + } + } + + return NETWORK_TYPE_OTHER; + } + + public static boolean isConnectedToWifi(Context context) { + ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (connMgr != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Network nw = connMgr.getActiveNetwork(); + if (nw == null) return false; + NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); + return actNw != null && actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI); + } else { + for (Network network : connMgr.getAllNetworks()) { + NetworkInfo networkInfo = connMgr.getNetworkInfo(network); + if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_WIFI) { + return networkInfo.isConnected(); + } + } + } + } + + return false; + } + + public static boolean isConnectedToCellularData(Context context) { + ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + if (connMgr != null) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + Network nw = connMgr.getActiveNetwork(); + if (nw == null) return false; + NetworkCapabilities actNw = connMgr.getNetworkCapabilities(nw); + return actNw != null && actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); + } else { + for (Network network : connMgr.getAllNetworks()) { + NetworkInfo networkInfo = connMgr.getNetworkInfo(network); + if (networkInfo != null && networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) { + return networkInfo.isConnected(); + } + } + } + } + + return false; + } + + public static void displaySortTypeInToolbar(SortType sortType, Toolbar toolbar) { + if (sortType != null) { + if (sortType.getTime() != null) { + toolbar.setSubtitle(sortType.getType().fullName + ": " + sortType.getTime().fullName); + } else { + toolbar.setSubtitle(sortType.getType().fullName); + } + } + } + + public static void hideKeyboard(Activity activity) { + InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); + if (inputMethodManager != null && activity.getCurrentFocus() != null) { + inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); + } + } + + public static float convertDpToPixel(float dp, Context context){ + return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT); + } + + @Nullable + public static Drawable getTintedDrawable(Context context, int drawableId, int color) { + Drawable drawable = context.getDrawable(drawableId); + if (drawable != null) { + Drawable wrappedDrawable = DrawableCompat.wrap(drawable).mutate(); + DrawableCompat.setTint(wrappedDrawable, color); + return wrappedDrawable; + } + + return null; + } +} -- cgit v1.2.3