diff options
| author | Andrew Dolgov <fox@fakecake.org> | 2025-05-14 08:36:38 +0300 |
|---|---|---|
| committer | Andrew Dolgov <fox@fakecake.org> | 2025-05-14 08:36:38 +0300 |
| commit | 964a5b76b78e2d573924b7b15b6f404dcdabad1e (patch) | |
| tree | 8540e36dc315a7d52b44a1f6bdfe8cc058f3ba47 | |
| parent | 6f42b0904207789ba3e7cc9b51e82bc8b1d7f1d7 (diff) | |
lazy loading and item diff related tweaks
5 files changed, 71 insertions, 27 deletions
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java index 3ee42976..8794e653 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java @@ -157,7 +157,7 @@ public class ArticleFragment extends androidx.fragment.app.Fragment { View noteContainer = view.findViewById(R.id.note_container); if (note != null && noteContainer != null) { - if (m_article.note != null && !m_article.note.isEmpty()) { + if (!m_article.note.isEmpty()) { note.setTextSize(TypedValue.COMPLEX_UNIT_SP, m_articleSmallFontSize); note.setText(m_article.note); noteContainer.setVisibility(View.VISIBLE); @@ -259,7 +259,7 @@ public class ArticleFragment extends androidx.fragment.app.Fragment { String linkHexColor = String.format("#%06X", (0xFFFFFF & tvColorPrimary.data)); cssOverride += " a:link {color: "+linkHexColor+";} a:visited { color: "+linkHexColor+";}"; - String articleContent = m_article.content != null ? m_article.content : ""; + String articleContent = m_article.content; ws.setJavaScriptEnabled(false); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java index bd80b112..9674cf2a 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java @@ -55,6 +55,7 @@ import androidx.recyclerview.widget.DefaultItemAnimator; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.ListUpdateCallback; import androidx.recyclerview.widget.RecyclerView; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; @@ -113,13 +114,32 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements ArticleList tmp = new ArticleList(); tmp.addAll(data); - if (headlinesLoader.lazyLoadEnabled()) - tmp.add(new Article(Article.TYPE_LOADMORE)); - tmp.add(new Article(Article.TYPE_AMR_FOOTER)); DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new HeadlinesDiffUtilCallback(m_articles, tmp)); + /* diffResult.dispatchUpdatesTo(new ListUpdateCallback() { + @Override + public void onInserted(int position, int count) { + Log.d(TAG, "[DIFF] onInserted! pos=" + position + " count=" + count); + } + + @Override + public void onRemoved(int position, int count) { + Log.d(TAG, "[DIFF] onRemoved! pos=" + position + " count=" + count); + } + + @Override + public void onMoved(int fromPosition, int toPosition) { + Log.d(TAG, "[DIFF] onMoved! from=" + fromPosition + " to=" + toPosition); + } + + @Override + public void onChanged(int position, int count, @Nullable Object payload) { + Log.d(TAG, "[DIFF] onChanged! pos=" + position + " count=" + count + " payload=" + payload); + } + }); */ + m_articles.clear(); m_articles.addAll(tmp); @@ -154,7 +174,8 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements @Override public void onLoaderReset(@NonNull Loader<ArticleList> loader) { - + if (m_swipeLayout != null) + m_swipeLayout.setRefreshing(false); } public void notifyItemChanged(int position) { @@ -505,9 +526,13 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements } } - if (!m_isLazyLoading && lastVisibleItem >= Application.getArticles().size() - 5) { + if (dy > 0 && !m_isLazyLoading && (m_loader == null || m_loader.lazyLoadEnabled()) && + lastVisibleItem >= Application.getArticles().size() - 5) { + m_isLazyLoading = true; + Log.d(TAG, "attempting to lazy load more articles..."); + // this has to be dispatched delayed, consequent adapter updates are forbidden in scroll handler new Handler().postDelayed(() -> refresh(true), 0); } @@ -559,7 +584,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements if (m_adapter != null) { m_adapter.notifyItemRangeRemoved(0, size); - m_articles.add(new Article(Article.TYPE_LOADMORE)); m_articles.add(new Article(Article.TYPE_AMR_FOOTER)); m_adapter.notifyItemRangeInserted(0, m_articles.size()); @@ -573,6 +597,9 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements initLoader(Application.LOADER_HEADLINES, null, this); } + if (m_swipeLayout != null) + m_swipeLayout.setRefreshing(true); + m_loader.setSearchQuery(getSearchQuery()); m_loader.startLoading(append); } @@ -685,7 +712,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements public static final int VIEW_UNREAD = 1; public static final int VIEW_ACTIVE = 2; public static final int VIEW_ACTIVE_UNREAD = 3; - public static final int VIEW_LOADMORE = 4; public static final int VIEW_AMR_FOOTER = 5; public static final int VIEW_COUNT = VIEW_AMR_FOOTER + 1; @@ -742,9 +768,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements case VIEW_AMR_FOOTER: layoutId = R.layout.headlines_footer; break; - case VIEW_LOADMORE: - layoutId = R.layout.headlines_row_loadmore; - break; case VIEW_UNREAD: layoutId = m_compactLayoutMode ? R.layout.headlines_row_compact_unread : R.layout.headlines_row_unread; break; @@ -1299,8 +1322,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements if (a.id == Article.TYPE_AMR_FOOTER) { return VIEW_AMR_FOOTER; - } else if (a.id == Article.TYPE_LOADMORE) { - return VIEW_LOADMORE; } else if (a.id == m_activeArticleId && a.unread) { return VIEW_ACTIVE_UNREAD; } else if (a.id == m_activeArticleId) { @@ -1543,9 +1564,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements ArticleList tmp = new ArticleList(); tmp.addAll(Application.getArticles()); - if (m_loader != null && m_loader.lazyLoadEnabled()) - tmp.add(new Article(Article.TYPE_LOADMORE)); - tmp.add(new Article(Article.TYPE_AMR_FOOTER)); DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new HeadlinesDiffUtilCallback(m_articles, tmp)); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesLoader.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesLoader.java index 6ff06975..a7755f5b 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesLoader.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesLoader.java @@ -67,6 +67,8 @@ public class HeadlinesLoader extends AsyncTaskLoader<ArticleList> implements Api } else if (m_lazyLoadEnabled && !m_loadingInProgress) { m_append = true; forceLoad(); + } else { + deliverResult(m_articles); } } @@ -181,11 +183,12 @@ public class HeadlinesLoader extends AsyncTaskLoader<ArticleList> implements Api m_amountLoaded = articlesJson.size(); - for (Article f : articlesJson) - if (!m_articles.containsId(f.id)) { - f.collectMediaInfo(); - f.cleanupExcerpt(); - m_articles.add(f); + for (Article article : articlesJson) + if (!m_articles.containsId(article.id)) { + article.collectMediaInfo(); + article.cleanupExcerpt(); + article.fixNullFields(); + m_articles.add(article); } if (m_firstIdChanged) { diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java index 800ca55f..76a62c58 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java @@ -14,7 +14,6 @@ import java.util.regex.Pattern; // TODO: serialize Labels public class Article implements Parcelable { - public static final int TYPE_LOADMORE = -1; public static final int TYPE_AMR_FOOTER = -2; public static final int FLAVOR_KIND_ALBUM = 1; @@ -194,8 +193,7 @@ public class Article implements Parcelable { public Article(int id) { this.id = id; this.title = "ID:" + id; - this.link = ""; - this.tags = new ArrayList<>(); + fixNullFields(); } @Override @@ -280,4 +278,14 @@ public class Article implements Parcelable { return new Article[size]; } }; + + /** set fields which might be missing during JSON deserialization to sane values */ + public void fixNullFields() { + if (note == null) note = ""; + if (link == null) link = ""; + if (tags == null) tags = new ArrayList<>(); + if (note == null) note = ""; + if (excerpt == null) excerpt = ""; + if (content == null) content = ""; + } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesDiffUtilCallback.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesDiffUtilCallback.java index 80265758..e1292f99 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesDiffUtilCallback.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesDiffUtilCallback.java @@ -1,10 +1,14 @@ package org.fox.ttrss.util; +import android.util.Log; + import androidx.recyclerview.widget.DiffUtil; +import org.fox.ttrss.types.Article; import org.fox.ttrss.types.ArticleList; public class HeadlinesDiffUtilCallback extends DiffUtil.Callback { + private final String TAG = this.getClass().getSimpleName(); private ArticleList m_oldList; private ArticleList m_newList; @@ -25,11 +29,22 @@ public class HeadlinesDiffUtilCallback extends DiffUtil.Callback { @Override public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) { - return m_newList.get(newItemPosition).id == m_oldList.get(oldItemPosition).id; + Article a1 = m_oldList.get(oldItemPosition); + Article a2 = m_newList.get(newItemPosition); + + // Log.d(TAG, "[DIFF] areItemsTheSame a1=" + a1.title + " a2=" + a2.title); + + return a1.id == a2.id; } @Override public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) { - return false; + Article a1 = m_oldList.get(oldItemPosition); + Article a2 = m_newList.get(newItemPosition); + + // Log.d(TAG, "[DIFF] areContentsTheSame a1=" + a1.title + " a2=" + a2.title); + + return a1.id == a2.id && a1.unread == a2.unread && a1.marked == a2.marked + && a1.published == a2.published && a1.note.equals(a2.note); } } |