From 6da36366a2383d6da3d3375d6ebd9c7287687384 Mon Sep 17 00:00:00 2001 From: Eitan <53308841+blahberi@users.noreply.github.com> Date: Sun, 20 Oct 2024 23:43:32 +0300 Subject: Changed the way read posts are handled to support an arbitrary read posts limit (#1720) * Changed the way read posts are handled to support an arbitrary 'read posts limit' * Changed db size in summary to kb * Use return HashSet instead of List in ReadPostsListInterface * Moved DB summary to Advanced Preferences. * Completed merge from master into feature/readPost * Fix some bugs and code style. --------- Co-authored-by: Docile-Alligator <25734209+Docile-Alligator@users.noreply.github.com> --- ...tchPostFilterAndConcatenatedSubredditNames.java | 75 ++++++++++++++ ...lterReadPostsAndConcatenatedSubredditNames.java | 88 ---------------- .../activities/AccountSavedThingActivity.java | 7 +- .../activities/FilteredPostsActivity.java | 7 +- .../infinityforreddit/activities/MainActivity.java | 7 +- .../activities/ViewMultiRedditDetailActivity.java | 7 +- .../activities/ViewPostDetailActivity.java | 20 ++-- .../activities/ViewSubredditDetailActivity.java | 7 +- .../activities/ViewUserDetailActivity.java | 7 +- ...ovidePostListToViewPostDetailActivityEvent.java | 8 +- .../fragments/HistoryPostFragment.java | 9 +- .../infinityforreddit/fragments/PostFragment.java | 111 ++++++++------------- .../fragments/ViewPostDetailFragment.java | 4 +- .../post/HistoryPostPagingSource.java | 3 +- .../infinityforreddit/post/ParsePost.java | 51 +++++----- .../infinityforreddit/post/PostPagingSource.java | 26 ++--- .../infinityforreddit/post/PostViewModel.java | 71 ++++++------- .../infinityforreddit/readpost/InsertReadPost.java | 8 +- .../readpost/NullReadPostsList.java | 20 ++++ .../infinityforreddit/readpost/ReadPostDao.java | 16 ++- .../infinityforreddit/readpost/ReadPostsList.java | 24 +++++ .../readpost/ReadPostsListInterface.java | 8 ++ .../infinityforreddit/readpost/ReadPostsUtils.java | 14 +++ .../settings/AdvancedPreferenceFragment.java | 28 ++++-- .../settings/PostHistoryFragment.java | 105 ++++++++++++++++++- .../utils/SharedPreferencesUtils.java | 2 + app/src/main/res/layout/fragment_post_history.xml | 55 ++++++++++ app/src/main/res/values/strings.xml | 3 + app/src/main/res/xml/advanced_preferences.xml | 4 +- build.gradle | 4 +- 30 files changed, 517 insertions(+), 282 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterAndConcatenatedSubredditNames.java delete mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterReadPostsAndConcatenatedSubredditNames.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/readpost/NullReadPostsList.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsList.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsListInterface.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsUtils.java diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterAndConcatenatedSubredditNames.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterAndConcatenatedSubredditNames.java new file mode 100644 index 00000000..0d9a7bef --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterAndConcatenatedSubredditNames.java @@ -0,0 +1,75 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Handler; + +import java.util.List; +import java.util.concurrent.Executor; + +import ml.docilealligator.infinityforreddit.account.Account; +import ml.docilealligator.infinityforreddit.multireddit.AnonymousMultiredditSubreddit; +import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; + +public class FetchPostFilterAndConcatenatedSubredditNames { + public static void fetchPostFilter(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, + Handler handler, int postFilterUsage, + String nameOfUsage, FetchPostFilterListerner fetchPostFilterListerner) { + executor.execute(() -> { + List postFilters = redditDataRoomDatabase.postFilterDao().getValidPostFilters(postFilterUsage, nameOfUsage); + PostFilter mergedPostFilter = PostFilter.mergePostFilter(postFilters); + handler.post(() -> fetchPostFilterListerner.success(mergedPostFilter)); + }); + } + + public static void fetchPostFilterAndConcatenatedSubredditNames(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, + Handler handler, int postFilterUsage, String nameOfUsage, + FetchPostFilterAndConcatenatecSubredditNamesListener fetchPostFilterAndConcatenatecSubredditNamesListener) { + executor.execute(() -> { + List postFilters = redditDataRoomDatabase.postFilterDao().getValidPostFilters(postFilterUsage, nameOfUsage); + PostFilter mergedPostFilter = PostFilter.mergePostFilter(postFilters); + List anonymousSubscribedSubreddits = redditDataRoomDatabase.subscribedSubredditDao().getAllSubscribedSubredditsList(Account.ANONYMOUS_ACCOUNT); + if (anonymousSubscribedSubreddits != null && !anonymousSubscribedSubreddits.isEmpty()) { + StringBuilder stringBuilder = new StringBuilder(); + for (SubscribedSubredditData s : anonymousSubscribedSubreddits) { + stringBuilder.append(s.getName()).append("+"); + } + if (stringBuilder.length() > 0) { + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + } + handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, stringBuilder.toString())); + } else { + handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, null)); + } + }); + } + + public static void fetchPostFilterAndConcatenatedSubredditNames(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, + Handler handler, String multipath, int postFilterUsage, String nameOfUsage, + FetchPostFilterAndConcatenatecSubredditNamesListener fetchPostFilterAndConcatenatecSubredditNamesListener) { + executor.execute(() -> { + List postFilters = redditDataRoomDatabase.postFilterDao().getValidPostFilters(postFilterUsage, nameOfUsage); + PostFilter mergedPostFilter = PostFilter.mergePostFilter(postFilters); + List anonymousMultiredditSubreddits = redditDataRoomDatabase.anonymousMultiredditSubredditDao().getAllAnonymousMultiRedditSubreddits(multipath); + if (anonymousMultiredditSubreddits != null && !anonymousMultiredditSubreddits.isEmpty()) { + StringBuilder stringBuilder = new StringBuilder(); + for (AnonymousMultiredditSubreddit s : anonymousMultiredditSubreddits) { + stringBuilder.append(s.getSubredditName()).append("+"); + } + if (stringBuilder.length() > 0) { + stringBuilder.deleteCharAt(stringBuilder.length() - 1); + } + handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, stringBuilder.toString())); + } else { + handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, null)); + } + }); + } + + public interface FetchPostFilterListerner { + void success(PostFilter postFilter); + } + + public interface FetchPostFilterAndConcatenatecSubredditNamesListener { + void success(PostFilter postFilter, String concatenatedSubredditNames); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterReadPostsAndConcatenatedSubredditNames.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterReadPostsAndConcatenatedSubredditNames.java deleted file mode 100644 index 2971a150..00000000 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchPostFilterReadPostsAndConcatenatedSubredditNames.java +++ /dev/null @@ -1,88 +0,0 @@ -package ml.docilealligator.infinityforreddit; - -import android.os.Handler; - -import androidx.annotation.NonNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.Executor; - -import ml.docilealligator.infinityforreddit.account.Account; -import ml.docilealligator.infinityforreddit.multireddit.AnonymousMultiredditSubreddit; -import ml.docilealligator.infinityforreddit.postfilter.PostFilter; -import ml.docilealligator.infinityforreddit.readpost.ReadPost; -import ml.docilealligator.infinityforreddit.subscribedsubreddit.SubscribedSubredditData; - -public class FetchPostFilterReadPostsAndConcatenatedSubredditNames { - public interface FetchPostFilterAndReadPostsListener { - void success(PostFilter postFilter, ArrayList readPostList); - } - - public interface FetchPostFilterAndConcatenatecSubredditNamesListener { - void success(PostFilter postFilter, String concatenatedSubredditNames); - } - - public static void fetchPostFilterAndReadPosts(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, - Handler handler, @NonNull String accountName, int postFilterUsage, - String nameOfUsage, FetchPostFilterAndReadPostsListener fetchPostFilterAndReadPostsListener) { - executor.execute(() -> { - List postFilters = redditDataRoomDatabase.postFilterDao().getValidPostFilters(postFilterUsage, nameOfUsage); - PostFilter mergedPostFilter = PostFilter.mergePostFilter(postFilters); - if (accountName.equals(Account.ANONYMOUS_ACCOUNT)) { - handler.post(() -> fetchPostFilterAndReadPostsListener.success(mergedPostFilter, null)); - } else { - List readPosts = redditDataRoomDatabase.readPostDao().getAllReadPosts(accountName); - ArrayList readPostStrings = new ArrayList<>(); - for (ReadPost readPost : readPosts) { - readPostStrings.add(readPost.getId()); - } - handler.post(() -> fetchPostFilterAndReadPostsListener.success(mergedPostFilter, readPostStrings)); - } - }); - } - - public static void fetchPostFilterAndConcatenatedSubredditNames(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, - Handler handler, int postFilterUsage, String nameOfUsage, - FetchPostFilterAndConcatenatecSubredditNamesListener fetchPostFilterAndConcatenatecSubredditNamesListener) { - executor.execute(() -> { - List postFilters = redditDataRoomDatabase.postFilterDao().getValidPostFilters(postFilterUsage, nameOfUsage); - PostFilter mergedPostFilter = PostFilter.mergePostFilter(postFilters); - List anonymousSubscribedSubreddits = redditDataRoomDatabase.subscribedSubredditDao().getAllSubscribedSubredditsList(Account.ANONYMOUS_ACCOUNT); - if (anonymousSubscribedSubreddits != null && !anonymousSubscribedSubreddits.isEmpty()) { - StringBuilder stringBuilder = new StringBuilder(); - for (SubscribedSubredditData s : anonymousSubscribedSubreddits) { - stringBuilder.append(s.getName()).append("+"); - } - if (stringBuilder.length() > 0) { - stringBuilder.deleteCharAt(stringBuilder.length() - 1); - } - handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, stringBuilder.toString())); - } else { - handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, null)); - } - }); - } - - public static void fetchPostFilterAndConcatenatedSubredditNames(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, - Handler handler, String multipath, int postFilterUsage, String nameOfUsage, - FetchPostFilterAndConcatenatecSubredditNamesListener fetchPostFilterAndConcatenatecSubredditNamesListener) { - executor.execute(() -> { - List postFilters = redditDataRoomDatabase.postFilterDao().getValidPostFilters(postFilterUsage, nameOfUsage); - PostFilter mergedPostFilter = PostFilter.mergePostFilter(postFilters); - List anonymousMultiredditSubreddits = redditDataRoomDatabase.anonymousMultiredditSubredditDao().getAllAnonymousMultiRedditSubreddits(multipath); - if (anonymousMultiredditSubreddits != null && !anonymousMultiredditSubreddits.isEmpty()) { - StringBuilder stringBuilder = new StringBuilder(); - for (AnonymousMultiredditSubreddit s : anonymousMultiredditSubreddits) { - stringBuilder.append(s.getSubredditName()).append("+"); - } - if (stringBuilder.length() > 0) { - stringBuilder.deleteCharAt(stringBuilder.length() - 1); - } - handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, stringBuilder.toString())); - } else { - handler.post(() -> fetchPostFilterAndConcatenatecSubredditNamesListener.success(mergedPostFilter, null)); - } - }); - } -} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java index 1c0c77b1..a6411ecb 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/AccountSavedThingActivity.java @@ -19,6 +19,7 @@ import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.tabs.TabLayoutMediator; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -58,6 +59,9 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT @Named("default") SharedPreferences mSharedPreferences; @Inject + @Named("post_history") + SharedPreferences mPostHistorySharedPreferences; + @Inject @Named("post_layout") SharedPreferences mPostLayoutSharedPreferences; @Inject @@ -251,7 +255,8 @@ public class AccountSavedThingActivity extends BaseActivity implements ActivityT @Override public void markPostAsRead(Post post) { - InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId(), readPostsLimit); } private class SectionsPagerAdapter extends FragmentStateAdapter { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java index dd8ff575..02ddae35 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/FilteredPostsActivity.java @@ -15,6 +15,7 @@ import androidx.annotation.Nullable; import androidx.coordinatorlayout.widget.CoordinatorLayout; import androidx.lifecycle.ViewModelProvider; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -73,6 +74,9 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec @Named("default") SharedPreferences mSharedPreferences; @Inject + @Named("post_history") + SharedPreferences mPostHistorySharedPreferences; + @Inject @Named("post_layout") SharedPreferences mPostLayoutSharedPreferences; @Inject @@ -459,7 +463,8 @@ public class FilteredPostsActivity extends BaseActivity implements SortTypeSelec @Override public void markPostAsRead(Post post) { - InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId(), readPostsLimit); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java index 045394ce..d86b862f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java @@ -52,6 +52,7 @@ import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayoutMediator; import com.google.android.material.textfield.TextInputEditText; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; @@ -154,6 +155,9 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb @Named("sort_type") SharedPreferences mSortTypeSharedPreferences; @Inject + @Named("post_history") + SharedPreferences mPostHistorySharedPreferences; + @Inject @Named("post_layout") SharedPreferences mPostLayoutSharedPreferences; @Inject @@ -1598,7 +1602,8 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb @Override public void markPostAsRead(Post post) { - InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId(), readPostsLimit); } public void doNotShowRedditAPIInfoAgain() { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java index 8d842ecf..4d0320bd 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewMultiRedditDetailActivity.java @@ -25,6 +25,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.textfield.TextInputEditText; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -99,6 +100,9 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT @Named("sort_type") SharedPreferences mSortTypeSharedPreferences; @Inject + @Named("post_history") + SharedPreferences mPostHistorySharedPreferences; + @Inject @Named("post_layout") SharedPreferences mPostLayoutSharedPreferences; @Inject @@ -878,7 +882,8 @@ public class ViewMultiRedditDetailActivity extends BaseActivity implements SortT @Override public void markPostAsRead(Post post) { - InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId(), readPostsLimit); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java index 1e64bf89..9b5a65ae 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewPostDetailActivity.java @@ -51,12 +51,8 @@ import javax.inject.Inject; import javax.inject.Named; import ml.docilealligator.infinityforreddit.Infinity; -import ml.docilealligator.infinityforreddit.post.LoadingMorePostsStatus; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; -import ml.docilealligator.infinityforreddit.thing.SaveThing; -import ml.docilealligator.infinityforreddit.thing.SortType; -import ml.docilealligator.infinityforreddit.thing.SortTypeSelectionCallback; import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.asynctasks.AccountManagement; @@ -70,11 +66,17 @@ import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; import ml.docilealligator.infinityforreddit.fragments.MorePostsInfoFragment; import ml.docilealligator.infinityforreddit.fragments.ViewPostDetailFragment; import ml.docilealligator.infinityforreddit.post.HistoryPostPagingSource; +import ml.docilealligator.infinityforreddit.post.LoadingMorePostsStatus; import ml.docilealligator.infinityforreddit.post.ParsePost; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.post.PostPagingSource; import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import ml.docilealligator.infinityforreddit.readpost.NullReadPostsList; import ml.docilealligator.infinityforreddit.readpost.ReadPost; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsListInterface; +import ml.docilealligator.infinityforreddit.thing.SaveThing; +import ml.docilealligator.infinityforreddit.thing.SortType; +import ml.docilealligator.infinityforreddit.thing.SortTypeSelectionCallback; import ml.docilealligator.infinityforreddit.utils.APIUtils; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import retrofit2.Call; @@ -141,8 +143,6 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele @State SortType.Time sortTime; @State - ArrayList readPostList; - @State Post post; @State @LoadingMorePostsStatus @@ -156,6 +156,8 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele private boolean mVolumeKeysNavigateComments; private boolean isNsfwSubreddit; private ActivityViewPostDetailBinding binding; + @Nullable + private ReadPostsListInterface readPostsList; @Override protected void onCreate(Bundle savedInstanceState) { @@ -581,7 +583,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele Response response = call.execute(); if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostsList); if (newPosts == null) { handler.post(() -> { loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS; @@ -663,7 +665,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele Response response = historyPosts.execute(); if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, NullReadPostsList.getInstance()); if (newPosts == null || newPosts.isEmpty()) { handler.post(() -> { loadingMorePostsStatus = LoadingMorePostsStatus.NO_MORE_POSTS; @@ -744,7 +746,7 @@ public class ViewPostDetailActivity extends BaseActivity implements SortTypeSele this.postFilter = event.postFilter; this.sortType = event.sortType.getType(); this.sortTime = event.sortType.getTime(); - this.readPostList = event.readPostList; + this.readPostsList = event.readPostsList; if (sectionsPagerAdapter != null) { if (postListPosition > 0) diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java index 9b20c311..af86bda3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java @@ -48,6 +48,7 @@ import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayoutMediator; import com.google.android.material.textfield.TextInputEditText; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -151,6 +152,9 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp @Inject @Named("nsfw_and_spoiler") SharedPreferences mNsfwAndSpoilerSharedPreferences; + @Inject() + @Named("post_history") + SharedPreferences mPostHistorySharedPreferences; @Inject @Named("post_layout") SharedPreferences mPostLayoutSharedPreferences; @@ -1537,7 +1541,8 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp @Override public void markPostAsRead(Post post) { - InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId(), readPostsLimit); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java index cad5c906..379da366 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java @@ -44,6 +44,7 @@ import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayoutMediator; import com.google.android.material.textfield.TextInputEditText; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -147,6 +148,9 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele @Named("sort_type") SharedPreferences mSortTypeSharedPreferences; @Inject + @Named("post_history") + SharedPreferences mPostHistorySharedPreferences; + @Inject @Named("post_layout") SharedPreferences mPostLayoutSharedPreferences; @Inject @@ -1550,7 +1554,8 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele @Override public void markPostAsRead(Post post) { - InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, accountName, post.getId(), readPostsLimit); } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java index e387c27d..bf8dc974 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/ProvidePostListToViewPostDetailActivityEvent.java @@ -2,6 +2,7 @@ package ml.docilealligator.infinityforreddit.events; import java.util.ArrayList; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsListInterface; import ml.docilealligator.infinityforreddit.thing.SortType; import ml.docilealligator.infinityforreddit.post.Post; import ml.docilealligator.infinityforreddit.postfilter.PostFilter; @@ -19,14 +20,13 @@ public class ProvidePostListToViewPostDetailActivityEvent { public String trendingSource; public PostFilter postFilter; public SortType sortType; - public ArrayList readPostList; + public ReadPostsListInterface readPostsList; public ProvidePostListToViewPostDetailActivityEvent(long postFragmentId, ArrayList posts, int postType, String subredditName, String concatenatedSubredditNames, String username, String userWhere, String multiPath, String query, String trendingSource, - PostFilter postFilter, SortType sortType, - ArrayList readPostList) { + PostFilter postFilter, SortType sortType, ReadPostsListInterface readPostsList) { this.postFragmentId = postFragmentId; this.posts = posts; this.postType = postType; @@ -39,6 +39,6 @@ public class ProvidePostListToViewPostDetailActivityEvent { this.trendingSource = trendingSource; this.postFilter = postFilter; this.sortType = sortType; - this.readPostList = readPostList; + this.readPostsList = readPostsList; } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java index 3ea7ae13..fd21e73a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/HistoryPostFragment.java @@ -37,7 +37,7 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; -import ml.docilealligator.infinityforreddit.FetchPostFilterReadPostsAndConcatenatedSubredditNames; +import ml.docilealligator.infinityforreddit.FetchPostFilterAndConcatenatedSubredditNames; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterface; @@ -112,7 +112,6 @@ public class HistoryPostFragment extends PostFragmentBase implements FragmentCom private PostRecyclerViewAdapter mAdapter; private int maxPosition = -1; private PostFilter postFilter; - private ArrayList readPosts; private int historyType; private FragmentHistoryPostBinding binding; @@ -163,7 +162,6 @@ public class HistoryPostFragment extends PostFragmentBase implements FragmentCom recyclerViewPosition = savedInstanceState.getInt(RECYCLER_VIEW_POSITION_STATE); isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - readPosts = savedInstanceState.getStringArrayList(READ_POST_LIST_STATE); postFilter = savedInstanceState.getParcelable(POST_FILTER_STATE); postFragmentId = savedInstanceState.getLong(POST_FRAGMENT_ID_STATE); } else { @@ -264,8 +262,8 @@ public class HistoryPostFragment extends PostFragmentBase implements FragmentCom } if (postFilter == null) { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndReadPosts(mRedditDataRoomDatabase, mExecutor, - new Handler(), activity.accountName, PostFilterUsage.HISTORY_TYPE, PostFilterUsage.HISTORY_TYPE_USAGE_READ_POSTS, (postFilter, readPostList) -> { + FetchPostFilterAndConcatenatedSubredditNames.fetchPostFilter(mRedditDataRoomDatabase, mExecutor, + new Handler(), PostFilterUsage.HISTORY_TYPE, PostFilterUsage.HISTORY_TYPE_USAGE_READ_POSTS, (postFilter) -> { if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { this.postFilter = postFilter; postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(activity.accountName + SharedPreferencesUtils.NSFW_BASE, false); @@ -402,7 +400,6 @@ public class HistoryPostFragment extends PostFragmentBase implements FragmentCom public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putStringArrayList(READ_POST_LIST_STATE, readPosts); if (mLinearLayoutManager != null) { outState.putInt(RECYCLER_VIEW_POSITION_STATE, mLinearLayoutManager.findFirstVisibleItemPosition()); } else if (mStaggeredGridLayoutManager != null) { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java index 69ea35d0..a3d0dab9 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/PostFragment.java @@ -40,7 +40,7 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Provider; -import ml.docilealligator.infinityforreddit.FetchPostFilterReadPostsAndConcatenatedSubredditNames; +import ml.docilealligator.infinityforreddit.FetchPostFilterAndConcatenatedSubredditNames; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; import ml.docilealligator.infinityforreddit.RecyclerViewContentScrollingInterface; @@ -68,6 +68,10 @@ import ml.docilealligator.infinityforreddit.post.PostPagingSource; import ml.docilealligator.infinityforreddit.post.PostViewModel; import ml.docilealligator.infinityforreddit.postfilter.PostFilter; import ml.docilealligator.infinityforreddit.postfilter.PostFilterUsage; +import ml.docilealligator.infinityforreddit.readpost.InsertReadPost; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsList; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsListInterface; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import ml.docilealligator.infinityforreddit.thing.SortType; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -93,7 +97,6 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat private static final String IS_IN_LAZY_MODE_STATE = "IILMS"; private static final String RECYCLER_VIEW_POSITION_STATE = "RVPS"; - private static final String READ_POST_LIST_STATE = "RPLS"; private static final String POST_FILTER_STATE = "PFS"; private static final String CONCATENATED_SUBREDDIT_NAMES_STATE = "CSNS"; private static final String POST_FRAGMENT_ID_STATE = "PFIS"; @@ -137,7 +140,7 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat private int maxPosition = -1; private SortType sortType; private PostFilter postFilter; - private ArrayList readPosts; + private ReadPostsListInterface readPostsList; private FragmentPostBinding binding; public PostFragment() { @@ -206,7 +209,6 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat recyclerViewPosition = savedInstanceState.getInt(RECYCLER_VIEW_POSITION_STATE); isInLazyMode = savedInstanceState.getBoolean(IS_IN_LAZY_MODE_STATE); - readPosts = savedInstanceState.getStringArrayList(READ_POST_LIST_STATE); postFilter = savedInstanceState.getParcelable(POST_FILTER_STATE); concatenatedSubredditNames = savedInstanceState.getString(CONCATENATED_SUBREDDIT_NAMES_STATE); postFragmentId = savedInstanceState.getLong(POST_FRAGMENT_ID_STATE); @@ -215,6 +217,9 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat postFragmentId = System.currentTimeMillis() + new Random().nextInt(1000); } + readPostsList = new ReadPostsList(mRedditDataRoomDatabase.readPostDao(), activity.accountName, + getArguments().getBoolean(EXTRA_DISABLE_READ_POSTS, false)); + binding.recyclerViewPostFragment.setOnTouchListener((view, motionEvent) -> { if (isInLazyMode) { pauseLazyMode(true); @@ -719,56 +724,27 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat } if (!activity.accountName.equals(Account.ANONYMOUS_ACCOUNT)) { - if (mPostHistorySharedPreferences.getBoolean(activity.accountName + SharedPreferencesUtils.MARK_POSTS_AS_READ_BASE, false) && readPosts == null) { - if (getArguments().getBoolean(EXTRA_DISABLE_READ_POSTS, false)) { - if (postFilter == null) { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndReadPosts(mRedditDataRoomDatabase, mExecutor, - new Handler(), activity.accountName, usage, nameOfUsage, (postFilter, readPostList) -> { - if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { - this.postFilter = postFilter; - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(activity.accountName + SharedPreferencesUtils.NSFW_BASE, false); - initializeAndBindPostViewModel(); - } - }); - } else { - initializeAndBindPostViewModel(); - } - } else { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndReadPosts(mRedditDataRoomDatabase, mExecutor, - new Handler(), activity.accountName, usage, nameOfUsage, (postFilter, readPostList) -> { - if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { - if (this.postFilter == null) { - this.postFilter = postFilter; - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(activity.accountName + SharedPreferencesUtils.NSFW_BASE, false); - } - this.readPosts = readPostList; - initializeAndBindPostViewModel(); - } - }); - } + if (postFilter == null) { + FetchPostFilterAndConcatenatedSubredditNames.fetchPostFilter(mRedditDataRoomDatabase, mExecutor, + new Handler(), usage, nameOfUsage, (postFilter) -> { + if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { + this.postFilter = postFilter; + this.postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(activity.accountName + SharedPreferencesUtils.NSFW_BASE, false); + initializeAndBindPostViewModel(); + } + }); } else { - if (postFilter == null) { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndReadPosts(mRedditDataRoomDatabase, mExecutor, - new Handler(), activity.accountName, usage, nameOfUsage, (postFilter, readPostList) -> { - if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { - this.postFilter = postFilter; - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(activity.accountName + SharedPreferencesUtils.NSFW_BASE, false); - initializeAndBindPostViewModel(); - } - }); - } else { - initializeAndBindPostViewModel(); - } + initializeAndBindPostViewModel(); } } else { if (postFilter == null) { if (postType == PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE) { if (concatenatedSubredditNames == null) { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), usage, nameOfUsage, + FetchPostFilterAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), usage, nameOfUsage, (postFilter, concatenatedSubredditNames) -> { if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { this.postFilter = postFilter; - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); + this.postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); this.concatenatedSubredditNames = concatenatedSubredditNames; if (concatenatedSubredditNames == null) { showErrorView(R.string.anonymous_front_page_no_subscriptions); @@ -782,11 +758,11 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat } } else if (postType == PostPagingSource.TYPE_ANONYMOUS_MULTIREDDIT) { if (concatenatedSubredditNames == null) { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), multiRedditPath, usage, nameOfUsage, + FetchPostFilterAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), multiRedditPath, usage, nameOfUsage, (postFilter, concatenatedSubredditNames) -> { if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { this.postFilter = postFilter; - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); + this.postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); this.concatenatedSubredditNames = concatenatedSubredditNames; if (concatenatedSubredditNames == null) { showErrorView(R.string.anonymous_multireddit_no_subreddit); @@ -799,11 +775,11 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat initializeAndBindPostViewModelForAnonymous(concatenatedSubredditNames); } } else { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndReadPosts(mRedditDataRoomDatabase, mExecutor, - new Handler(), activity.accountName, usage, nameOfUsage, (postFilter, readPostList) -> { + FetchPostFilterAndConcatenatedSubredditNames.fetchPostFilter(mRedditDataRoomDatabase, mExecutor, + new Handler(), usage, nameOfUsage, (postFilter) -> { if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { this.postFilter = postFilter; - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); + this.postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); initializeAndBindPostViewModelForAnonymous(null); } }); @@ -811,10 +787,10 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat } else { if (postType == PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE) { if (concatenatedSubredditNames == null) { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), usage, nameOfUsage, + FetchPostFilterAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), usage, nameOfUsage, (postFilter, concatenatedSubredditNames) -> { if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); + this.postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); this.concatenatedSubredditNames = concatenatedSubredditNames; if (concatenatedSubredditNames == null) { showErrorView(R.string.anonymous_front_page_no_subscriptions); @@ -828,10 +804,10 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat } } else if (postType == PostPagingSource.TYPE_ANONYMOUS_MULTIREDDIT) { if (concatenatedSubredditNames == null) { - FetchPostFilterReadPostsAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), multiRedditPath, usage, nameOfUsage, + FetchPostFilterAndConcatenatedSubredditNames.fetchPostFilterAndConcatenatedSubredditNames(mRedditDataRoomDatabase, mExecutor, new Handler(), multiRedditPath, usage, nameOfUsage, (postFilter, concatenatedSubredditNames) -> { if (activity != null && !activity.isFinishing() && !activity.isDestroyed() && !isDetached()) { - postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); + this.postFilter.allowNSFW = !mSharedPreferences.getBoolean(SharedPreferencesUtils.DISABLE_NSFW_FOREVER, false) && mNsfwAndSpoilerSharedPreferences.getBoolean(SharedPreferencesUtils.NSFW_BASE, false); this.concatenatedSubredditNames = concatenatedSubredditNames; if (concatenatedSubredditNames == null) { showErrorView(R.string.anonymous_multireddit_no_subreddit); @@ -967,27 +943,27 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, activity.accountName.equals(Account.ANONYMOUS_ACCOUNT) ? mRetrofit : mOauthRetrofit, activity.accessToken, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, mPostHistorySharedPreferences, subredditName, - query, trendingSource, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); + query, trendingSource, postType, sortType, postFilter, readPostsList)).get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_SUBREDDIT) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, activity.accountName.equals(Account.ANONYMOUS_ACCOUNT) ? mRetrofit : mOauthRetrofit, activity.accessToken, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, subredditName, postType, sortType, postFilter, readPosts)) + mPostHistorySharedPreferences, subredditName, postType, sortType, postFilter, readPostsList)) .get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_MULTI_REDDIT) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, activity.accountName.equals(Account.ANONYMOUS_ACCOUNT) ? mRetrofit : mOauthRetrofit, activity.accessToken, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, multiRedditPath, query, postType, sortType, postFilter, readPosts)) + mPostHistorySharedPreferences, multiRedditPath, query, postType, sortType, postFilter, readPostsList)) .get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_USER) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, activity.accountName.equals(Account.ANONYMOUS_ACCOUNT) ? mRetrofit : mOauthRetrofit, activity.accessToken, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, username, postType, sortType, postFilter, where, readPosts)) + mPostHistorySharedPreferences, username, postType, sortType, postFilter, where, readPostsList)) .get(PostViewModel.class); } else { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mOauthRetrofit, activity.accessToken, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, - mPostHistorySharedPreferences, postType, sortType, postFilter, readPosts)).get(PostViewModel.class); + mPostHistorySharedPreferences, postType, sortType, postFilter, readPostsList)).get(PostViewModel.class); } bindPostViewModel(); @@ -998,21 +974,21 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, null, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, null, subredditName, query, trendingSource, - postType, sortType, postFilter, readPosts)).get(PostViewModel.class); + postType, sortType, postFilter, readPostsList)).get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_SUBREDDIT) { mPostViewModel = new ViewModelProvider(this, new PostViewModel.Factory(mExecutor, mRetrofit, null, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, null, subredditName, postType, sortType, - postFilter, readPosts)).get(PostViewModel.class); + postFilter, readPostsList)).get(PostViewModel.class); } else if (postType == PostPagingSource.TYPE_USER) { mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, mRetrofit, null, activity.accountName, mSharedPreferences, mPostFeedScrolledPositionSharedPreferences, null, username, postType, sortType, postFilter, - where, readPosts)).get(PostViewModel.class); + where, readPostsList)).get(PostViewModel.class); } else { //Anonymous front page or multireddit mPostViewModel = new ViewModelProvider(PostFragment.this, new PostViewModel.Factory(mExecutor, - mRetrofit, mSharedPreferences, concatenatedSubredditNames, postType, sortType, postFilter)) + mRetrofit, mSharedPreferences, concatenatedSubredditNames, postType, sortType, postFilter, readPostsList)) .get(PostViewModel.class); } @@ -1169,7 +1145,6 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putBoolean(IS_IN_LAZY_MODE_STATE, isInLazyMode); - outState.putStringArrayList(READ_POST_LIST_STATE, readPosts); if (mLinearLayoutManager != null) { outState.putInt(RECYCLER_VIEW_POSITION_STATE, mLinearLayoutManager.findFirstVisibleItemPosition()); } else if (mStaggeredGridLayoutManager != null) { @@ -1390,10 +1365,8 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat @Override public void markPostAsRead(Post post) { - if (readPosts == null) { - readPosts = new ArrayList<>(); - } - readPosts.add(post.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(activity.accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, activity.accountName, post.getId(), readPostsLimit); } @Subscribe @@ -1462,7 +1435,7 @@ public class PostFragment extends PostFragmentBase implements FragmentCommunicat EventBus.getDefault().post(new ProvidePostListToViewPostDetailActivityEvent(postFragmentId, new ArrayList<>(mAdapter.snapshot()), postType, subredditName, concatenatedSubredditNames, username, where, multiRedditPath, query, trendingSource, - postFilter, sortType, readPosts)); + postFilter, sortType, readPostsList)); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java index d8f8b03d..66535d27 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/fragments/ViewPostDetailFragment.java @@ -48,6 +48,7 @@ import com.evernote.android.state.State; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.livefront.bridge.Bridge; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsUtils; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; @@ -1156,7 +1157,8 @@ public class ViewPostDetailFragment extends Fragment implements FragmentCommunic private void tryMarkingPostAsRead() { if (mMarkPostsAsRead && mPost != null && !mPost.isRead()) { mPost.markAsRead(); - InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, activity.accountName, mPost.getId()); + int readPostsLimit = ReadPostsUtils.GetReadPostsLimit(activity.accountName, mPostHistorySharedPreferences); + InsertReadPost.insertReadPost(mRedditDataRoomDatabase, mExecutor, activity.accountName, mPost.getId(), readPostsLimit); EventBus.getDefault().post(new PostUpdateEventToPostList(mPost, postListPosition)); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java index a0b9167f..5aad494a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/HistoryPostPagingSource.java @@ -20,6 +20,7 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.apis.RedditAPI; import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import ml.docilealligator.infinityforreddit.readpost.NullReadPostsList; import ml.docilealligator.infinityforreddit.readpost.ReadPost; import ml.docilealligator.infinityforreddit.utils.APIUtils; import retrofit2.Call; @@ -92,7 +93,7 @@ public class HistoryPostPagingSource extends ListenableFuturePagingSource response = historyPosts.execute(); if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, null); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, NullReadPostsList.getInstance()); if (newPosts == null) { return new LoadResult.Error<>(new Exception("Error parsing posts")); } else { diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java index 6092d9e1..88b6fc90 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/ParsePost.java @@ -13,16 +13,16 @@ import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; -import java.util.HashSet; import java.util.LinkedHashSet; -import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.Executor; import java.util.regex.Matcher; import java.util.regex.Pattern; -import ml.docilealligator.infinityforreddit.thing.MediaMetadata; import ml.docilealligator.infinityforreddit.postfilter.PostFilter; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsListInterface; +import ml.docilealligator.infinityforreddit.thing.MediaMetadata; import ml.docilealligator.infinityforreddit.utils.JSONUtils; import ml.docilealligator.infinityforreddit.utils.Utils; @@ -31,41 +31,41 @@ import ml.docilealligator.infinityforreddit.utils.Utils; */ public class ParsePost { - public static LinkedHashSet parsePostsSync(String response, int nPosts, PostFilter postFilter, List readPostList) { + @WorkerThread + public static LinkedHashSet parsePostsSync(String response, int nPosts, PostFilter postFilter, @Nullable ReadPostsListInterface readPostsList) { LinkedHashSet newPosts = new LinkedHashSet<>(); try { JSONObject jsonResponse = new JSONObject(response); - JSONArray allData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); + JSONArray allPostsData = jsonResponse.getJSONObject(JSONUtils.DATA_KEY).getJSONArray(JSONUtils.CHILDREN_KEY); //Posts listing - int size; - if (nPosts < 0 || nPosts > allData.length()) { - size = allData.length(); - } else { - size = nPosts; - } + int numberOfPosts = (nPosts < 0 || nPosts > allPostsData.length()) ? + allPostsData.length() : nPosts; - HashSet readPostHashSet = null; - if (readPostList != null) { - readPostHashSet = new HashSet<>(readPostList); - } - for (int i = 0; i < size; i++) { + ArrayList newPostsIds = new ArrayList<>(); + for (int i = 0; i < numberOfPosts; 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); - if (readPostHashSet != null && readPostHashSet.contains(post.getId())) { - post.markAsRead(); - } - if (PostFilter.isPostAllowed(post, postFilter)) { - newPosts.add(post); - } + if (!allPostsData.getJSONObject(i).getString(JSONUtils.KIND_KEY).equals("t3")) { + continue; + } + JSONObject data = allPostsData.getJSONObject(i).getJSONObject(JSONUtils.DATA_KEY); + Post post = parseBasicData(data); + if (PostFilter.isPostAllowed(post, postFilter)) { + newPosts.add(post); + newPostsIds.add(post.getId()); } } catch (JSONException e) { e.printStackTrace(); } } + Set readPostsIds = readPostsList.getReadPostsIdsByIds(newPostsIds); + for (Post post: newPosts) { + if (readPostsIds.contains(post.getId())) { + post.markAsRead(); + } + } + return newPosts; } catch (JSONException e) { e.printStackTrace(); @@ -143,6 +143,7 @@ public class ParsePost { }); } + @WorkerThread public static Post parseBasicData(JSONObject data) throws JSONException { String id = data.getString(JSONUtils.ID_KEY); String fullName = data.getString(JSONUtils.NAME_KEY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostPagingSource.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostPagingSource.java index 0e5926b8..f2cd1f7a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostPagingSource.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostPagingSource.java @@ -13,9 +13,9 @@ import com.google.common.util.concurrent.ListenableFuture; import java.io.IOException; import java.util.ArrayList; import java.util.LinkedHashSet; -import java.util.List; import java.util.concurrent.Executor; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsListInterface; import ml.docilealligator.infinityforreddit.thing.SortType; import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.apis.RedditAPI; @@ -53,7 +53,7 @@ public class PostPagingSource extends ListenableFuturePagingSource private final int postType; private final SortType sortType; private final PostFilter postFilter; - private final List readPostList; + private final ReadPostsListInterface readPostsList; private String userWhere; private String multiRedditPath; private final LinkedHashSet postLinkedHashSet; @@ -62,7 +62,7 @@ public class PostPagingSource extends ListenableFuturePagingSource PostPagingSource(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, int postType, - SortType sortType, PostFilter postFilter, List readPostList) { + SortType sortType, PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -72,7 +72,7 @@ public class PostPagingSource extends ListenableFuturePagingSource this.postType = postType; this.sortType = sortType == null ? new SortType(SortType.Type.BEST) : sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; postLinkedHashSet = new LinkedHashSet<>(); } @@ -80,7 +80,7 @@ public class PostPagingSource extends ListenableFuturePagingSource PostPagingSource(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String name, int postType, SortType sortType, PostFilter postFilter, - List readPostList) { + ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -102,7 +102,7 @@ public class PostPagingSource extends ListenableFuturePagingSource this.sortType = sortType; } this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; postLinkedHashSet = new LinkedHashSet<>(); } @@ -110,7 +110,7 @@ public class PostPagingSource extends ListenableFuturePagingSource PostPagingSource(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String path, String query, int postType, SortType sortType, PostFilter postFilter, - List readPostList) { + ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -130,14 +130,14 @@ public class PostPagingSource extends ListenableFuturePagingSource this.sortType = sortType; } this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; postLinkedHashSet = new LinkedHashSet<>(); } PostPagingSource(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, int postType, SortType sortType, PostFilter postFilter, - String where, List readPostList) { + String where, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -149,14 +149,14 @@ public class PostPagingSource extends ListenableFuturePagingSource this.sortType = sortType == null ? new SortType(SortType.Type.NEW) : sortType; this.postFilter = postFilter; userWhere = where; - this.readPostList = readPostList; + this.readPostsList = readPostsList; postLinkedHashSet = new LinkedHashSet<>(); } PostPagingSource(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, String subredditOrUserName, String query, String trendingSource, int postType, - SortType sortType, PostFilter postFilter, List readPostList) { + SortType sortType, PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -170,7 +170,7 @@ public class PostPagingSource extends ListenableFuturePagingSource this.sortType = sortType == null ? new SortType(SortType.Type.RELEVANCE) : sortType; this.postFilter = postFilter; postLinkedHashSet = new LinkedHashSet<>(); - this.readPostList = readPostList; + this.readPostsList = readPostsList; } @Nullable @@ -202,7 +202,7 @@ public class PostPagingSource extends ListenableFuturePagingSource public LoadResult transformData(Response response) { if (response.isSuccessful()) { String responseString = response.body(); - LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostList); + LinkedHashSet newPosts = ParsePost.parsePostsSync(responseString, -1, postFilter, readPostsList); String lastItem = ParsePost.getLastItem(responseString); if (newPosts == null) { return new LoadResult.Error<>(new Exception("Error parsing posts")); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java index 47ec89e2..21fca70a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/post/PostViewModel.java @@ -18,9 +18,9 @@ import androidx.paging.PagingData; import androidx.paging.PagingDataTransforms; import androidx.paging.PagingLiveData; -import java.util.List; import java.util.concurrent.Executor; +import ml.docilealligator.infinityforreddit.readpost.ReadPostsListInterface; import ml.docilealligator.infinityforreddit.thing.SortType; import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.postfilter.PostFilter; @@ -41,7 +41,7 @@ public class PostViewModel extends ViewModel { private SortType sortType; private PostFilter postFilter; private String userWhere; - private final List readPostList; + private ReadPostsListInterface readPostsList; private final MutableLiveData currentlyReadPostIdsLiveData = new MutableLiveData<>(); private final LiveData> posts; @@ -55,7 +55,7 @@ public class PostViewModel extends ViewModel { public PostViewModel(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, int postType, - SortType sortType, PostFilter postFilter, List readPostList) { + SortType sortType, PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -65,7 +65,7 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; sortTypeLiveData = new MutableLiveData<>(sortType); postFilterLiveData = new MutableLiveData<>(postFilter); @@ -95,7 +95,7 @@ public class PostViewModel extends ViewModel { public PostViewModel(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, String subredditName, int postType, - SortType sortType, PostFilter postFilter, List readPostList) { + SortType sortType, PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -105,7 +105,7 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; this.name = subredditName; sortTypeLiveData = new MutableLiveData<>(sortType); @@ -136,7 +136,7 @@ public class PostViewModel extends ViewModel { public PostViewModel(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, String multiredditPath, String query, int postType, - SortType sortType, PostFilter postFilter, List readPostList) { + SortType sortType, PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -146,7 +146,7 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; this.name = multiredditPath; this.query = query; @@ -179,7 +179,7 @@ public class PostViewModel extends ViewModel { SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, String username, int postType, SortType sortType, PostFilter postFilter, String userWhere, - List readPostList) { + ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -189,7 +189,7 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; this.name = username; this.userWhere = userWhere; @@ -222,7 +222,7 @@ public class PostViewModel extends ViewModel { SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, @Nullable SharedPreferences postHistorySharedPreferences, String subredditName, String query, String trendingSource, int postType, SortType sortType, PostFilter postFilter, - List readPostList) { + ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -232,7 +232,7 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; this.name = subredditName; this.query = query; this.trendingSource = trendingSource; @@ -275,30 +275,30 @@ public class PostViewModel extends ViewModel { case PostPagingSource.TYPE_FRONT_PAGE: paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postType, sortType, - postFilter, readPostList); + postFilter, readPostsList); break; case PostPagingSource.TYPE_SUBREDDIT: case PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE: case PostPagingSource.TYPE_ANONYMOUS_MULTIREDDIT: paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, - sortType, postFilter, readPostList); + sortType, postFilter, readPostsList); break; case PostPagingSource.TYPE_MULTI_REDDIT: paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, query, postType, - sortType, postFilter, readPostList); + sortType, postFilter, readPostsList); break; case PostPagingSource.TYPE_SEARCH: paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, query, trendingSource, - postType, sortType, postFilter, readPostList); + postType, sortType, postFilter, readPostsList); break; default: //User paging3PagingSource = new PostPagingSource(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, name, postType, - sortType, postFilter, userWhere, readPostList); + sortType, postFilter, userWhere, readPostsList); break; } return paging3PagingSource; @@ -332,13 +332,13 @@ public class PostViewModel extends ViewModel { private final SortType sortType; private final PostFilter postFilter; private String userWhere; - private List readPostList; + private final ReadPostsListInterface readPostsList; // Front page public Factory(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, int postType, SortType sortType, - PostFilter postFilter, List readPostList) { + PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -349,14 +349,14 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; } // PostPagingSource.TYPE_SUBREDDIT public Factory(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, String name, int postType, SortType sortType, - PostFilter postFilter, List readPostList) { + PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -368,14 +368,14 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; } // PostPagingSource.TYPE_MULTI_REDDIT public Factory(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, String name, String query, int postType, SortType sortType, - PostFilter postFilter, List readPostList) { + PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -388,14 +388,14 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; } //User posts public Factory(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, String username, int postType, - SortType sortType, PostFilter postFilter, String where, List readPostList) { + SortType sortType, PostFilter postFilter, String where, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -408,14 +408,14 @@ public class PostViewModel extends ViewModel { this.sortType = sortType; this.postFilter = postFilter; userWhere = where; - this.readPostList = readPostList; + this.readPostsList = readPostsList; } // PostPagingSource.TYPE_SEARCH public Factory(Executor executor, Retrofit retrofit, @Nullable String accessToken, @NonNull String accountName, SharedPreferences sharedPreferences, SharedPreferences postFeedScrolledPositionSharedPreferences, SharedPreferences postHistorySharedPreferences, String name, String query, String trendingSource, - int postType, SortType sortType, PostFilter postFilter, List readPostList) { + int postType, SortType sortType, PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.accessToken = accessToken; @@ -429,12 +429,12 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; - this.readPostList = readPostList; + this.readPostsList = readPostsList; } //Anonymous Front Page public Factory(Executor executor, Retrofit retrofit, SharedPreferences sharedPreferences, - String concatenatedSubredditNames, int postType, SortType sortType, PostFilter postFilter) { + String concatenatedSubredditNames, int postType, SortType sortType, PostFilter postFilter, ReadPostsListInterface readPostsList) { this.executor = executor; this.retrofit = retrofit; this.sharedPreferences = sharedPreferences; @@ -442,6 +442,7 @@ public class PostViewModel extends ViewModel { this.postType = postType; this.sortType = sortType; this.postFilter = postFilter; + this.readPostsList = readPostsList; } @NonNull @@ -450,27 +451,27 @@ public class PostViewModel extends ViewModel { if (postType == PostPagingSource.TYPE_FRONT_PAGE) { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, postType, - sortType, postFilter, readPostList); + sortType, postFilter, readPostsList); } else if (postType == PostPagingSource.TYPE_SEARCH) { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, name, query, - trendingSource, postType, sortType, postFilter, readPostList); + trendingSource, postType, sortType, postFilter, readPostsList); } else if (postType == PostPagingSource.TYPE_SUBREDDIT) { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, name, - postType, sortType, postFilter, readPostList); + postType, sortType, postFilter, readPostsList); } else if (postType == PostPagingSource.TYPE_MULTI_REDDIT) { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, name, query, - postType, sortType, postFilter, readPostList); + postType, sortType, postFilter, readPostsList); } else if (postType == PostPagingSource.TYPE_ANONYMOUS_FRONT_PAGE || postType == PostPagingSource.TYPE_ANONYMOUS_MULTIREDDIT) { return (T) new PostViewModel(executor, retrofit, null, null, sharedPreferences, null, null, name, postType, sortType, - postFilter, null); + postFilter, readPostsList); } else { return (T) new PostViewModel(executor, retrofit, accessToken, accountName, sharedPreferences, postFeedScrolledPositionSharedPreferences, postHistorySharedPreferences, name, - postType, sortType, postFilter, userWhere, readPostList); + postType, sortType, postFilter, userWhere, readPostsList); } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/InsertReadPost.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/InsertReadPost.java index be548700..d6835845 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/InsertReadPost.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/InsertReadPost.java @@ -6,13 +6,15 @@ import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; public class InsertReadPost { public static void insertReadPost(RedditDataRoomDatabase redditDataRoomDatabase, Executor executor, - String username, String postId) { + String username, String postId, int readPostsLimit) { executor.execute(() -> { ReadPostDao readPostDao = redditDataRoomDatabase.readPostDao(); - if (readPostDao.getReadPostsCount() > 500) { + int limit = Math.max(readPostsLimit, 500); + boolean isReadPostLimit = readPostsLimit != -1; + while (readPostDao.getReadPostsCount(username) > limit && isReadPostLimit) { readPostDao.deleteOldestReadPosts(username); } - if (username != null && !username.equals("")) { + if (username != null && !username.isEmpty()) { readPostDao.insert(new ReadPost(username, postId)); } }); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/NullReadPostsList.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/NullReadPostsList.java new file mode 100644 index 00000000..6c68522b --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/NullReadPostsList.java @@ -0,0 +1,20 @@ +package ml.docilealligator.infinityforreddit.readpost; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class NullReadPostsList implements ReadPostsListInterface { + public static NullReadPostsList getInstance() { + return InstanceHolder.instance; + } + + @Override + public Set getReadPostsIdsByIds(List ids) { + return Collections.emptySet(); + } + + private static class InstanceHolder { + private static final NullReadPostsList instance = new NullReadPostsList(); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java index 5f7fb8da..db5253a3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostDao.java @@ -20,18 +20,24 @@ public interface ReadPostDao { @Query("SELECT * FROM read_posts WHERE username = :username AND (:before IS NULL OR time < :before) ORDER BY time DESC LIMIT 25") List getAllReadPosts(String username, Long before); - @Query("SELECT * FROM read_posts WHERE username = :username") - List getAllReadPosts(String username); - @Query("SELECT * FROM read_posts WHERE id = :id LIMIT 1") ReadPost getReadPost(String id); - @Query("SELECT COUNT(id) FROM read_posts") - int getReadPostsCount(); + @Query("SELECT COUNT(id) FROM read_posts WHERE username = :username") + int getReadPostsCount(String username); @Query("DELETE FROM read_posts WHERE rowid IN (SELECT rowid FROM read_posts ORDER BY time ASC LIMIT 100) AND username = :username") void deleteOldestReadPosts(String username); @Query("DELETE FROM read_posts") void deleteAllReadPosts(); + + @Query("SELECT id FROM read_posts WHERE id IN (:ids) AND username = :username") + List getReadPostsIdsByIds(List ids, String username); + + default int getMaxReadPostEntrySize() { // in bytes + return 20 + // max username size + 10 + // id size + 8; // time size + } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsList.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsList.java new file mode 100644 index 00000000..08b8c5ed --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsList.java @@ -0,0 +1,24 @@ +package ml.docilealligator.infinityforreddit.readpost; + +import androidx.annotation.WorkerThread; + +import java.util.HashSet; +import java.util.List; + +public class ReadPostsList implements ReadPostsListInterface { + private final ReadPostDao readPostDao; + private final String accountName; + private final boolean readPostsDisabled; + + public ReadPostsList(ReadPostDao readPostDao, String accountName, boolean readPostsDisabled) { + this.accountName = accountName; + this.readPostDao = readPostDao; + this.readPostsDisabled = readPostsDisabled; + } + + @WorkerThread + @Override + public HashSet getReadPostsIdsByIds(List ids) { + return readPostsDisabled ? new HashSet<>() : new HashSet<>(this.readPostDao.getReadPostsIdsByIds(ids, accountName)); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsListInterface.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsListInterface.java new file mode 100644 index 00000000..3563ed55 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsListInterface.java @@ -0,0 +1,8 @@ +package ml.docilealligator.infinityforreddit.readpost; + +import java.util.List; +import java.util.Set; + +public interface ReadPostsListInterface { + Set getReadPostsIdsByIds(List ids); +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsUtils.java new file mode 100644 index 00000000..a56bf9c8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/readpost/ReadPostsUtils.java @@ -0,0 +1,14 @@ +package ml.docilealligator.infinityforreddit.readpost; + +import android.content.SharedPreferences; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; + +public class ReadPostsUtils { + public static int GetReadPostsLimit(String accountName, SharedPreferences mPostHistorySharedPreferences) { + if (mPostHistorySharedPreferences.getBoolean(accountName + SharedPreferencesUtils.READ_POSTS_LIMIT_ENABLED, true)) { + return mPostHistorySharedPreferences.getInt(accountName + SharedPreferencesUtils.READ_POSTS_LIMIT, 500); + } else { + return -1; + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java index a430cb14..99a22068 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/AdvancedPreferenceFragment.java @@ -8,6 +8,7 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.os.Handler; +import android.os.Looper; import android.widget.Toast; import androidx.annotation.Nullable; @@ -36,6 +37,7 @@ import ml.docilealligator.infinityforreddit.asynctasks.DeleteAllUsers; import ml.docilealligator.infinityforreddit.asynctasks.RestoreSettings; import ml.docilealligator.infinityforreddit.customviews.CustomFontPreferenceFragmentCompat; import ml.docilealligator.infinityforreddit.events.RecreateActivityEvent; +import ml.docilealligator.infinityforreddit.readpost.ReadPostDao; import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; /** @@ -85,6 +87,7 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp SharedPreferences postHistorySharedPreferences; @Inject Executor executor; + private Handler handler; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { @@ -104,12 +107,14 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp Preference backupSettingsPreference = findPreference(SharedPreferencesUtils.BACKUP_SETTINGS); Preference restoreSettingsPreference = findPreference(SharedPreferencesUtils.RESTORE_SETTINGS); + handler = new Handler(Looper.getMainLooper()); + if (deleteSubredditsPreference != null) { deleteSubredditsPreference.setOnPreferenceClickListener(preference -> { new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) .setTitle(R.string.are_you_sure) .setPositiveButton(R.string.yes, (dialogInterface, i) - -> DeleteAllSubreddits.deleteAllSubreddits(executor, new Handler(), mRedditDataRoomDatabase, + -> DeleteAllSubreddits.deleteAllSubreddits(executor, handler, mRedditDataRoomDatabase, () -> Toast.makeText(activity, R.string.delete_all_subreddits_success, Toast.LENGTH_SHORT).show())) .setNegativeButton(R.string.no, null) .show(); @@ -122,7 +127,7 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) .setTitle(R.string.are_you_sure) .setPositiveButton(R.string.yes, (dialogInterface, i) - -> DeleteAllUsers.deleteAllUsers(executor, new Handler(), mRedditDataRoomDatabase, + -> DeleteAllUsers.deleteAllUsers(executor, handler, mRedditDataRoomDatabase, () -> Toast.makeText(activity, R.string.delete_all_users_success, Toast.LENGTH_SHORT).show())) .setNegativeButton(R.string.no, null) .show(); @@ -135,7 +140,7 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) .setTitle(R.string.are_you_sure) .setPositiveButton(R.string.yes, (dialogInterface, i) - -> DeleteAllSortTypes.deleteAllSortTypes(executor, new Handler(), + -> DeleteAllSortTypes.deleteAllSortTypes(executor, handler, mSharedPreferences, mSortTypeSharedPreferences, () -> { Toast.makeText(activity, R.string.delete_all_sort_types_success, Toast.LENGTH_SHORT).show(); EventBus.getDefault().post(new RecreateActivityEvent()); @@ -151,7 +156,7 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) .setTitle(R.string.are_you_sure) .setPositiveButton(R.string.yes, (dialogInterface, i) - -> DeleteAllPostLayouts.deleteAllPostLayouts(executor, new Handler(), + -> DeleteAllPostLayouts.deleteAllPostLayouts(executor, handler, mSharedPreferences, mPostLayoutSharedPreferences, () -> { Toast.makeText(activity, R.string.delete_all_post_layouts_success, Toast.LENGTH_SHORT).show(); EventBus.getDefault().post(new RecreateActivityEvent()); @@ -167,7 +172,7 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) .setTitle(R.string.are_you_sure) .setPositiveButton(R.string.yes, (dialogInterface, i) - -> DeleteAllThemes.deleteAllThemes(executor, new Handler(), + -> DeleteAllThemes.deleteAllThemes(executor, handler, mRedditDataRoomDatabase, lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences, () -> { Toast.makeText(activity, R.string.delete_all_themes_success, Toast.LENGTH_SHORT).show(); @@ -195,11 +200,18 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp } if (deleteReadPostsPreference != null) { + executor.execute(() -> { + ReadPostDao readPostDao = mRedditDataRoomDatabase.readPostDao(); + int tableCount = readPostDao.getReadPostsCount(activity.accountName); + long tableEntrySize = readPostDao.getMaxReadPostEntrySize(); + long tableSize = tableEntrySize * tableCount / 1024; + handler.post(() -> deleteReadPostsPreference.setSummary(getString(R.string.settings_read_posts_db_summary, tableSize, tableCount))); + }); deleteReadPostsPreference.setOnPreferenceClickListener(preference -> { new MaterialAlertDialogBuilder(activity, R.style.MaterialAlertDialogTheme) .setTitle(R.string.are_you_sure) .setPositiveButton(R.string.yes, (dialogInterface, i) - -> DeleteAllReadPosts.deleteAllReadPosts(executor, new Handler(), + -> DeleteAllReadPosts.deleteAllReadPosts(executor, handler, mRedditDataRoomDatabase, () -> { Toast.makeText(activity, R.string.delete_all_read_posts_success, Toast.LENGTH_SHORT).show(); })) @@ -308,7 +320,7 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp if (resultCode == RESULT_OK) { if (requestCode == SELECT_BACKUP_SETTINGS_DIRECTORY_REQUEST_CODE) { Uri uri = data.getData(); - BackupSettings.backupSettings(activity, executor, new Handler(), activity.getContentResolver(), uri, + BackupSettings.backupSettings(activity, executor, handler, activity.getContentResolver(), uri, mRedditDataRoomDatabase, mSharedPreferences, lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences, mSortTypeSharedPreferences, mPostLayoutSharedPreferences, postFeedScrolledPositionSharedPreferences, mainActivityTabsSharedPreferences, @@ -326,7 +338,7 @@ public class AdvancedPreferenceFragment extends CustomFontPreferenceFragmentComp }); } else if (requestCode == SELECT_RESTORE_SETTINGS_DIRECTORY_REQUEST_CODE) { Uri uri = data.getData(); - RestoreSettings.restoreSettings(activity, executor, new Handler(), activity.getContentResolver(), uri, + RestoreSettings.restoreSettings(activity, executor, handler, activity.getContentResolver(), uri, mRedditDataRoomDatabase, mSharedPreferences, lightThemeSharedPreferences, darkThemeSharedPreferences, amoledThemeSharedPreferences, mSortTypeSharedPreferences, mPostLayoutSharedPreferences, postFeedScrolledPositionSharedPreferences, mainActivityTabsSharedPreferences, diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostHistoryFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostHistoryFragment.java index 0268a7ca..5da131c7 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostHistoryFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/settings/PostHistoryFragment.java @@ -2,20 +2,29 @@ package ml.docilealligator.infinityforreddit.settings; import android.content.Context; import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.EditText; +import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import java.lang.reflect.Field; +import java.util.concurrent.Executor; + import javax.inject.Inject; import javax.inject.Named; import ml.docilealligator.infinityforreddit.Infinity; import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; import ml.docilealligator.infinityforreddit.account.Account; import ml.docilealligator.infinityforreddit.activities.SettingsActivity; import ml.docilealligator.infinityforreddit.databinding.FragmentPostHistoryBinding; @@ -28,6 +37,10 @@ public class PostHistoryFragment extends Fragment { @Inject @Named("post_history") SharedPreferences postHistorySharedPreferences; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + Executor mExecutor; private SettingsActivity activity; public PostHistoryFragment() { @@ -49,9 +62,12 @@ public class PostHistoryFragment extends Fragment { Utils.setFontToAllTextViews(binding.getRoot(), activity.typeface); } - if (activity.accountName.equals(Account.ANONYMOUS_ACCOUNT)) { + boolean isAnonymous = activity.accountName.equals(Account.ANONYMOUS_ACCOUNT); + if (isAnonymous) { binding.infoTextViewPostHistoryFragment.setText(R.string.only_for_logged_in_user); binding.markPostsAsReadLinearLayoutPostHistoryFragment.setVisibility(View.GONE); + binding.readPostsLimitLinearLayoutPostHistoryFragment.setVisibility(View.GONE); + binding.readPostsLimitTextInputLayoutPostHistoryFragment.setVisibility(View.GONE); binding.markPostsAsReadAfterVotingLinearLayoutPostHistoryFragment.setVisibility(View.GONE); binding.markPostsAsReadOnScrollLinearLayoutPostHistoryFragment.setVisibility(View.GONE); binding.hideReadPostsAutomaticallyLinearLayoutPostHistoryFragment.setVisibility(View.GONE); @@ -60,6 +76,10 @@ public class PostHistoryFragment extends Fragment { binding.markPostsAsReadSwitchPostHistoryFragment.setChecked(postHistorySharedPreferences.getBoolean( activity.accountName + SharedPreferencesUtils.MARK_POSTS_AS_READ_BASE, false)); + binding.readPostsLimitSwitchPostHistoryFragment.setChecked(postHistorySharedPreferences.getBoolean( + activity.accountName + SharedPreferencesUtils.READ_POSTS_LIMIT_ENABLED, true)); + binding.readPostsLimitTextInputEditTextPostHistoryFragment.setText(String.valueOf(postHistorySharedPreferences.getInt( + activity.accountName + SharedPreferencesUtils.READ_POSTS_LIMIT, 500))); binding.markPostsAsReadAfterVotingSwitchPostHistoryFragment.setChecked(postHistorySharedPreferences.getBoolean( activity.accountName + SharedPreferencesUtils.MARK_POSTS_AS_READ_AFTER_VOTING_BASE, false)); binding.markPostsAsReadOnScrollSwitchPostHistoryFragment.setChecked(postHistorySharedPreferences.getBoolean( @@ -67,12 +87,37 @@ public class PostHistoryFragment extends Fragment { binding.hideReadPostsAutomaticallySwitchPostHistoryFragment.setChecked(postHistorySharedPreferences.getBoolean( activity.accountName + SharedPreferencesUtils.HIDE_READ_POSTS_AUTOMATICALLY_BASE, false)); - binding.markPostsAsReadLinearLayoutPostHistoryFragment.setOnClickListener(view -> { - binding.markPostsAsReadSwitchPostHistoryFragment.performClick(); + updateOptions(); + + binding.markPostsAsReadLinearLayoutPostHistoryFragment.setOnClickListener(view -> + binding.markPostsAsReadSwitchPostHistoryFragment.performClick()); + binding.markPostsAsReadSwitchPostHistoryFragment.setOnCheckedChangeListener((compoundButton, b) -> { + postHistorySharedPreferences.edit().putBoolean(activity.accountName + SharedPreferencesUtils.MARK_POSTS_AS_READ_BASE, b).apply(); + updateOptions(); }); - binding.markPostsAsReadSwitchPostHistoryFragment.setOnCheckedChangeListener((compoundButton, b) -> - postHistorySharedPreferences.edit().putBoolean(activity.accountName + SharedPreferencesUtils.MARK_POSTS_AS_READ_BASE, b).apply()); + + binding.readPostsLimitLinearLayoutPostHistoryFragment.setOnClickListener(view -> + binding.readPostsLimitSwitchPostHistoryFragment.performClick()); + binding.readPostsLimitSwitchPostHistoryFragment.setOnCheckedChangeListener((compoundButton, b) -> { + postHistorySharedPreferences.edit().putBoolean(activity.accountName + SharedPreferencesUtils.READ_POSTS_LIMIT_ENABLED, b).apply(); + updateOptions(); + }); + binding.readPostsLimitTextInputEditTextPostHistoryFragment.setOnFocusChangeListener((view, b) -> { + if (!b) { + String readPostsLimitString = binding.readPostsLimitTextInputEditTextPostHistoryFragment.getText().toString(); + if (readPostsLimitString.isEmpty()) { + binding.readPostsLimitTextInputEditTextPostHistoryFragment.setText("500"); + } else { + int readPostsLimit = Integer.parseInt(readPostsLimitString); + if (readPostsLimit < 100) { + binding.readPostsLimitTextInputEditTextPostHistoryFragment.setText("100"); + } + } + postHistorySharedPreferences.edit().putInt(activity.accountName + SharedPreferencesUtils.READ_POSTS_LIMIT, + Integer.parseInt(binding.readPostsLimitTextInputEditTextPostHistoryFragment.getText().toString())).apply(); + } + }); binding.markPostsAsReadAfterVotingLinearLayoutPostHistoryFragment.setOnClickListener(view -> binding.markPostsAsReadAfterVotingSwitchPostHistoryFragment.performClick()); @@ -90,15 +135,65 @@ public class PostHistoryFragment extends Fragment { return binding.getRoot(); } + private void updateOptions() { + if (binding.markPostsAsReadSwitchPostHistoryFragment.isChecked()) { + binding.readPostsLimitLinearLayoutPostHistoryFragment.setVisibility(View.VISIBLE); + binding.readPostsLimitTextInputLayoutPostHistoryFragment.setVisibility(View.VISIBLE); + binding.markPostsAsReadAfterVotingLinearLayoutPostHistoryFragment.setVisibility(View.VISIBLE); + binding.markPostsAsReadOnScrollLinearLayoutPostHistoryFragment.setVisibility(View.VISIBLE); + binding.hideReadPostsAutomaticallyLinearLayoutPostHistoryFragment.setVisibility(View.VISIBLE); + + boolean limitReadPosts = postHistorySharedPreferences.getBoolean( + activity.accountName + SharedPreferencesUtils.READ_POSTS_LIMIT_ENABLED, true); + binding.readPostsLimitTextInputLayoutPostHistoryFragment.setVisibility(limitReadPosts ? View.VISIBLE : View.GONE); + } else { + binding.readPostsLimitLinearLayoutPostHistoryFragment.setVisibility(View.GONE); + binding.readPostsLimitTextInputLayoutPostHistoryFragment.setVisibility(View.GONE); + binding.markPostsAsReadAfterVotingLinearLayoutPostHistoryFragment.setVisibility(View.GONE); + binding.markPostsAsReadOnScrollLinearLayoutPostHistoryFragment.setVisibility(View.GONE); + binding.hideReadPostsAutomaticallyLinearLayoutPostHistoryFragment.setVisibility(View.GONE); + } + } + private void applyCustomTheme() { binding.infoTextViewPostHistoryFragment.setTextColor(activity.customThemeWrapper.getSecondaryTextColor()); Drawable infoDrawable = Utils.getTintedDrawable(activity, R.drawable.ic_info_preference_day_night_24dp, activity.customThemeWrapper.getPrimaryIconColor()); binding.infoTextViewPostHistoryFragment.setCompoundDrawablesWithIntrinsicBounds(infoDrawable, null, null, null); int primaryTextColor = activity.customThemeWrapper.getPrimaryTextColor(); binding.markPostsAsReadTextViewPostHistoryFragment.setTextColor(primaryTextColor); + binding.readPostsLimitTextViewPostHistoryFragment.setTextColor(primaryTextColor); + binding.readPostsLimitTextInputLayoutPostHistoryFragment.setBoxStrokeColor(primaryTextColor); + binding.readPostsLimitTextInputLayoutPostHistoryFragment.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + binding.readPostsLimitTextInputEditTextPostHistoryFragment.setTextColor(primaryTextColor); binding.markPostsAsReadAfterVotingTextViewPostHistoryFragment.setTextColor(primaryTextColor); binding.markPostsAsReadOnScrollTextViewPostHistoryFragment.setTextColor(primaryTextColor); binding.hideReadPostsAutomaticallyTextViewPostHistoryFragment.setTextColor(primaryTextColor); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + binding.readPostsLimitTextInputLayoutPostHistoryFragment.setCursorColor(ColorStateList.valueOf(primaryTextColor)); + } else { + setCursorDrawableColor(binding.readPostsLimitTextInputEditTextPostHistoryFragment, primaryTextColor); + } + } + + private void setCursorDrawableColor(EditText editText, int color) { + try { + Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); + fCursorDrawableRes.setAccessible(true); + int mCursorDrawableRes = fCursorDrawableRes.getInt(editText); + Field fEditor = TextView.class.getDeclaredField("mEditor"); + fEditor.setAccessible(true); + Object editor = fEditor.get(editText); + Class clazz = editor.getClass(); + Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable"); + fCursorDrawable.setAccessible(true); + Drawable[] drawables = new Drawable[2]; + drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN); + drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN); + fCursorDrawable.set(editor, drawables); + } catch (Throwable ignored) { } } @Override diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java index b5bb598a..d53657da 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/utils/SharedPreferencesUtils.java @@ -386,6 +386,8 @@ public class SharedPreferencesUtils { public static final String POST_HISTORY_SHARED_PREFERENCES_FILE = "ml.docilealligator.infinityforreddit.post_history"; public static final String MARK_POSTS_AS_READ_BASE = "_mark_posts_as_read"; + public static final String READ_POSTS_LIMIT_ENABLED = "_read_posts_limit_enabled"; + public static final String READ_POSTS_LIMIT = "_read_posts_limit"; public static final String MARK_POSTS_AS_READ_AFTER_VOTING_BASE = "_mark_posts_as_read_after_voting"; public static final String MARK_POSTS_AS_READ_ON_SCROLL_BASE = "_mark_posts_as_read_on_scroll"; public static final String HIDE_READ_POSTS_AUTOMATICALLY_BASE = "_hide_read_posts_automatically"; diff --git a/app/src/main/res/layout/fragment_post_history.xml b/app/src/main/res/layout/fragment_post_history.xml index bd0d5ba3..2c3ae592 100644 --- a/app/src/main/res/layout/fragment_post_history.xml +++ b/app/src/main/res/layout/fragment_post_history.xml @@ -59,6 +59,61 @@ + + + + + + + + + + + + + + Enable Search History Post History Mark Posts as Read + Limit Read Posts + Set read posts limit + Read Posts DB Table \nSize: %1$d(KB) \nCount: %2$d Mark Posts as Read After Voting Mark Posts as Read on Scroll Hide Read Posts Automatically diff --git a/app/src/main/res/xml/advanced_preferences.xml b/app/src/main/res/xml/advanced_preferences.xml index 538a5f2e..895f6f86 100644 --- a/app/src/main/res/xml/advanced_preferences.xml +++ b/app/src/main/res/xml/advanced_preferences.xml @@ -27,7 +27,9 @@ + app:title="@string/settings_delete_read_posts_in_database_title" + app:summary="" + />