From 33cf280c247e6b056697e6341a712a0cd59bc086 Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Tue, 27 Feb 2024 11:39:01 -0300 Subject: [PATCH 1/4] Create AppsPrefs for persisting selected feed item ID --- .../org/wordpress/android/ui/prefs/AppPrefs.java | 16 +++++++++++++++- .../android/ui/prefs/AppPrefsWrapper.kt | 4 ++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java index eb9e37a9e514..aff81c56ffed 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefs.java @@ -149,10 +149,11 @@ public enum DeletablePrefKey implements PrefKey { READER_CARDS_ENDPOINT_PAGE_HANDLE, // used to tell the server to return a different set of data so the content on discover tab doesn't look static READER_CARDS_ENDPOINT_REFRESH_COUNTER, - // Used to delete recommended tags saved as followed tags in tbl_tags // Need to be done just once for a logged out user READER_RECOMMENDED_TAGS_DELETED_FOR_LOGGED_OUT_USER, + // Selected Reader feed ID for persisting user preferred feed + READER_TOP_BAR_SELECTED_FEED_ITEM_ID, MANUAL_FEATURE_CONFIG, SITE_JETPACK_CAPABILITIES, REMOVED_QUICK_START_CARD_TYPE, @@ -1193,6 +1194,19 @@ public static void setReaderRecommendedTagsDeletedForLoggedOutUser(boolean delet setBoolean(DeletablePrefKey.READER_RECOMMENDED_TAGS_DELETED_FOR_LOGGED_OUT_USER, deleted); } + @Nullable + public static String getReaderTopBarSelectedFeedItemId() { + return getString(DeletablePrefKey.READER_TOP_BAR_SELECTED_FEED_ITEM_ID, null); + } + + public static void setReaderTopBarSelectedFeedItemId(@Nullable String selectedFeedItemId) { + if (selectedFeedItemId == null) { + remove(DeletablePrefKey.READER_TOP_BAR_SELECTED_FEED_ITEM_ID); + } else { + setString(DeletablePrefKey.READER_TOP_BAR_SELECTED_FEED_ITEM_ID, selectedFeedItemId); + } + } + public static void setShouldShowStoriesIntro(boolean shouldShow) { setBoolean(UndeletablePrefKey.SHOULD_SHOW_STORIES_INTRO, shouldShow); } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefsWrapper.kt b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefsWrapper.kt index 10b8ef20cd04..6052c7a85e7d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefsWrapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/prefs/AppPrefsWrapper.kt @@ -71,6 +71,10 @@ class AppPrefsWrapper @Inject constructor() { get() = AppPrefs.getReaderCardsPageHandle() set(pageHandle) = AppPrefs.setReaderCardsPageHandle(pageHandle) + var readerTopBarSelectedFeedItemId: String? + get() = AppPrefs.getReaderTopBarSelectedFeedItemId() + set(selectedFeedItemId) = AppPrefs.setReaderTopBarSelectedFeedItemId(selectedFeedItemId) + var shouldShowStoriesIntro: Boolean get() = AppPrefs.shouldShowStoriesIntro() set(shouldShow) = AppPrefs.setShouldShowStoriesIntro(shouldShow) From ba2e5b22fa942af820f64e362f24ec2d6272e764 Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Tue, 27 Feb 2024 11:39:29 -0300 Subject: [PATCH 2/4] Save and use persisted selected feed ID The priority for setting the selected feed item when opening the app from cold start is: 1. SavedState bundle (it's saved if the app is destroyed by the system) 2. Persisted AppPref (saved every time the user selects a feed) 3. First item (should be used only the first time ever opening the Reader) --- .../ui/reader/viewmodels/ReaderViewModel.kt | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/viewmodels/ReaderViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/reader/viewmodels/ReaderViewModel.kt index 0e13b2f17e0b..4232579bd121 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/viewmodels/ReaderViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/viewmodels/ReaderViewModel.kt @@ -182,6 +182,8 @@ class ReaderViewModel @Inject constructor( fun updateSelectedContent(selectedTag: ReaderTag) { getMenuItemFromReaderTag(selectedTag)?.let { newSelectedMenuItem -> + // Persist selected feed to app prefs + appPrefsWrapper.readerTopBarSelectedFeedItemId = newSelectedMenuItem.id // Update top bar UI state so menu is updated with new selected item _topBarUiState.value?.let { _topBarUiState.value = it.copy( @@ -311,27 +313,33 @@ class ReaderViewModel @Inject constructor( // if menu is exactly the same as before, don't update if (_topBarUiState.value?.menuItems == menuItems) return@withContext - - // if there's already a selected item, use it, otherwise use the first item, also try to use the saved state + // choose selected item, either from current, saved state, or persisted, falling back to first item val savedStateSelectedId = savedInstanceState?.getString(KEY_TOP_BAR_UI_STATE_SELECTED_ITEM_ID) + + val persistedSelectedId = appPrefsWrapper.readerTopBarSelectedFeedItemId + val selectedItem = _topBarUiState.value?.selectedItem ?: menuItems.filterSingleItems() .let { singleItems -> - singleItems.firstOrNull { it.id == savedStateSelectedId } ?: singleItems.first() + singleItems.firstOrNull { it.id == savedStateSelectedId } + ?: singleItems.firstOrNull { it.id == persistedSelectedId } + ?: singleItems.first() } // if there's a selected item and filter state, also use the filter state, also try to use the saved state + val savedStateFilterUiState = savedInstanceState + ?.let { + BundleCompat.getParcelable( + it, + KEY_TOP_BAR_UI_STATE_FILTER_UI_STATE, + TopBarUiState.FilterUiState::class.java + ) + } + ?.takeIf { selectedItem.id == savedStateSelectedId } + val filterUiState = _topBarUiState.value?.filterUiState ?.takeIf { _topBarUiState.value?.selectedItem != null } - ?: savedInstanceState - ?.let { - BundleCompat.getParcelable( - it, - KEY_TOP_BAR_UI_STATE_FILTER_UI_STATE, - TopBarUiState.FilterUiState::class.java - ) - } - ?.takeIf { selectedItem.id == savedStateSelectedId } + ?: savedStateFilterUiState _topBarUiState.postValue( TopBarUiState( From 557dff1e08ed3096e696b539a5553b37a097a8a3 Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Tue, 27 Feb 2024 17:46:51 -0300 Subject: [PATCH 3/4] Hide empty state text when there are posts in the Adapter --- .../wordpress/android/ui/reader/ReaderPostListFragment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index 287204bb16d1..ee5d9805e5d4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -1948,7 +1948,7 @@ private void showBookmarksSavedLocallyDialog(ShowBookmarkedSavedOnlyLocallyDialo private final ReaderInterfaces.DataLoadedListener mDataLoadedListener = new ReaderInterfaces.DataLoadedListener() { @Override public void onDataLoaded(boolean isEmpty) { - if (!isAdded() || !mHasUpdatedPosts) { + if (!isAdded() || (isEmpty && !mHasUpdatedPosts)) { return; } if (isEmpty) { @@ -2322,7 +2322,7 @@ public void run() { requireActivity().runOnUiThread(() -> updateCurrentTag()); } else { requireActivity().runOnUiThread(() -> { - if ((isBookmarksList()) && isPostAdapterEmpty() && isAdded()) { + if (isBookmarksList() && isPostAdapterEmpty() && isAdded()) { setEmptyTitleAndDescriptionForBookmarksList(); mActionableEmptyView.image.setImageResource( R.drawable.illustration_reader_empty); From 4e2ef82d251c6b3c67b1381075c47f0dad6b830f Mon Sep 17 00:00:00 2001 From: Thomas Horta Date: Wed, 28 Feb 2024 12:42:45 -0300 Subject: [PATCH 4/4] Fix image not being shown in Empty Lists sometimes --- .../org/wordpress/android/ui/reader/ReaderPostListFragment.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index ee5d9805e5d4..5ad4b8714426 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -2332,6 +2332,8 @@ public void run() { R.drawable.illustration_reader_empty); mActionableEmptyView.title.setText( getString(R.string.reader_empty_blogs_posts_in_custom_list)); + mActionableEmptyView.image.setVisibility(View.VISIBLE); + mActionableEmptyView.title.setVisibility(View.VISIBLE); mActionableEmptyView.button.setVisibility(View.GONE); mActionableEmptyView.subtitle.setVisibility(View.GONE); showEmptyView();