summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <fox@fakecake.org>2025-05-13 08:48:58 +0300
committerAndrew Dolgov <fox@fakecake.org>2025-05-13 08:48:58 +0300
commit524dc199ea76d5cc9e08e79c9279de2ed76afe69 (patch)
treefb8a19a4e2b1f22bc6e16025e5253f81a86dd88e
parentc2413dd121e509ac1012ad7026accbae5e16a242 (diff)
prevent loader from triggering callbacks twice, cleanup
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java7
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java211
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesLoader.java41
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java2
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java3
5 files changed, 31 insertions, 233 deletions
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java
index 46cf36ee..3cd73734 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java
@@ -3,7 +3,6 @@ package org.fox.ttrss;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.SharedPreferences;
-import android.os.BadParcelableException;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
@@ -18,14 +17,8 @@ import androidx.preference.PreferenceManager;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;
-import com.google.android.material.snackbar.Snackbar;
-import com.google.gson.JsonElement;
-
import org.fox.ttrss.types.Article;
import org.fox.ttrss.types.Feed;
-import org.fox.ttrss.util.HeadlinesRequest;
-
-import java.util.HashMap;
public class ArticlePager extends androidx.fragment.app.Fragment {
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 22601897..df59d863 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
@@ -1,6 +1,5 @@
package org.fox.ttrss;
-import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
@@ -70,21 +69,18 @@ import com.bumptech.glide.request.target.Target;
import com.google.android.material.button.MaterialButton;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.snackbar.Snackbar;
-import com.google.gson.JsonElement;
import org.fox.ttrss.glide.ProgressTarget;
import org.fox.ttrss.types.Article;
import org.fox.ttrss.types.ArticleList;
import org.fox.ttrss.types.Attachment;
import org.fox.ttrss.types.Feed;
-import org.fox.ttrss.util.HeadlinesRequest;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
-import java.util.HashMap;
import java.util.TimeZone;
import jp.wasabeef.glide.transformations.CropCircleTransformation;
@@ -129,7 +125,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
@Override
public void onLoadFinished(@NonNull Loader<ArticleList> loader, ArticleList data) {
- Log.d(TAG, "onLoadFinished loader=" + loader + " count=" + data.size());
+ Log.d(TAG, "onLoadFinished loader=" + loader);
HeadlinesLoader headlinesLoader = (HeadlinesLoader) loader;
@@ -154,9 +150,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
diffResult.dispatchUpdatesTo(m_adapter);
- if (!headlinesLoader.getAppend())
- m_list.scrollToPosition(0);
-
if (headlinesLoader.getFirstIdChanged()) {
//if (m_activity.isSmallScreen() || !m_activity.isPortrait()) {
Snackbar.make(getView(), R.string.headlines_row_top_changed, Snackbar.LENGTH_LONG)
@@ -170,14 +163,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
if (headlinesLoader.getLastError() == ApiCommon.ApiError.LOGIN_FAILED) {
m_activity.login();
} else {
-
if (headlinesLoader.getLastErrorMessage() != null) {
m_activity.toast(m_activity.getString(headlinesLoader.getErrorMessage()) + "\n" + headlinesLoader.getLastErrorMessage());
} else {
m_activity.toast(headlinesLoader.getErrorMessage());
}
}
-
}
if (m_swipeLayout != null)
@@ -199,7 +190,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
private Feed m_feed;
private int m_activeArticleId;
private String m_searchQuery = "";
- private boolean m_refreshInProgress = false;
+ private HeadlinesLoader m_loader;
private int m_firstId = 0;
//private boolean m_lazyLoadDisabled = false;
@@ -483,14 +474,15 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
if (!m_readArticles.isEmpty()) {
m_activity.toggleArticlesUnread(m_readArticles);
- for (Article a : m_readArticles)
+ for (Article a : m_readArticles) {
a.unread = false;
+ m_adapter.notifyItemChanged(Application.getArticles().getPositionById(a.id));
+ }
+
if (m_feed != null)
m_feed.unread -= m_readArticles.size();
- m_adapter.notifyDataSetChanged();
-
m_readArticles.clear();
new Handler().postDelayed(() -> m_activity.refresh(false), 100);
@@ -499,7 +491,9 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
int lastVisibleItem = m_layoutManager.findLastVisibleItemPosition();
if (lastVisibleItem >= Application.getArticles().size() - 5)
- new Handler().postDelayed(() -> refresh(true), 100);
+ refresh(true);
+
+ new Handler().postDelayed(() -> refresh(true), 0);
}
}
@@ -529,13 +523,8 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
}
}
- /*if (!m_refreshInProgress && !m_lazyLoadDisabled && lastVisibleItem >= Application.getArticles().size() - 5) {
- m_refreshInProgress = true;
- new Handler().postDelayed(() -> refresh(true), 100);
- }*/
-
/* if (lastVisibleItem >= Application.getArticles().size() - 5)
- new Handler().postDelayed(() -> refresh(true), 100); */
+ new Handler().postDelayed(() -> refresh(true), 1000); */
}
});
@@ -573,180 +562,16 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment implements
}
public void refresh(final boolean append) {
- HeadlinesLoader loader = (HeadlinesLoader) LoaderManager.getInstance(this).initLoader(Application.LOADER_HEADLINES, null, this);
-
- loader.setSearchQuery(getSearchQuery());
- loader.refresh(append);
- }
-
- /* public void __refresh(final boolean append) {
- Application.getArticles().stripFooters();
- m_adapter.notifyDataSetChanged();
-
- if (!append) m_lazyLoadDisabled = false;
-
- if (m_activity != null && isAdded() && m_feed != null) {
- m_refreshInProgress = true;
-
- if (m_swipeLayout != null) m_swipeLayout.setRefreshing(true);
-
- if (!append) {
- m_activity.getSupportActionBar().show();
- Application.getArticles().clear();
- m_adapter.notifyDataSetChanged();
- } else if (!(m_activity instanceof DetailActivity)) {
- // detail activity does not use footers because it would break 1-to-1 mapping with pager view
- // pager will need to work on a footerless subset of shared article view before this is possible
- Application.getArticles().add(new Article(Article.TYPE_LOADMORE));
- m_adapter.notifyDataSetChanged();
- }
-
- final String sessionId = m_activity.getSessionId();
- final boolean isCat = m_feed.is_cat;
-
- @SuppressLint("StaticFieldLeak") HeadlinesRequest req = new HeadlinesRequest(getActivity().getApplicationContext(), m_activity, Application.getArticles()) {
- @Override
- protected void onPostExecute(JsonElement result) {
- if (isDetached() || !isAdded()) return;
-
- super.onPostExecute(result);
-
- if (m_swipeLayout != null) m_swipeLayout.setRefreshing(false);
-
- m_refreshInProgress = false;
-
- if (result != null) {
-
- // is this needed?
- if (!Application.getArticles().containsId(m_activeArticleId))
- m_activeArticleId = 0;
-
- if (m_firstIdChanged) {
- m_lazyLoadDisabled = true;
-
- Log.d(TAG, "first id changed, disabling lazy load");
-
- // article pager deals with this in tablet landscape view
- if (m_activity.isSmallScreen() || !m_activity.isPortrait()) {
- Snackbar.make(getView(), R.string.headlines_row_top_changed, Snackbar.LENGTH_LONG)
- .setAction(R.string.reload, v -> refresh(false)).show();
- }
- }
-
- if (m_amountLoaded < Integer.parseInt(m_prefs.getString("headlines_request_size", "15"))) {
- // Log.d(TAG, "amount loaded "+m_amountLoaded+" < request size, disabling lazy load");
- m_lazyLoadDisabled = true;
- }
-
- HeadlinesFragment.this.m_firstId = m_firstId;
-
- m_adapter.notifyDataSetChanged();
- m_listener.onHeadlinesLoaded(append);
-
- } else {
- m_lazyLoadDisabled = true;
-
- if (m_lastError == ApiCommon.ApiError.LOGIN_FAILED) {
- m_activity.login(true);
- } else {
- if (m_lastErrorMessage != null) {
- m_activity.toast(getString(getErrorMessage()) + "\n" + m_lastErrorMessage);
- } else {
- m_activity.toast(getErrorMessage());
- }
- }
- }
-
- // detail activity does not use footers (see above)
- if (!(m_activity instanceof DetailActivity)) {
- Application.getArticles().add(new Article(Article.TYPE_AMR_FOOTER));
- m_adapter.notifyDataSetChanged();
- }
- }
- };
-
- final int skip = getSkip(append);
-
- final boolean allowForceUpdate = m_activity.getApiLevel() >= 9 &&
- !m_feed.is_cat && m_feed.id > 0 && !append && skip == 0;
-
- Log.d(TAG, "allowForceUpdate=" + allowForceUpdate + " skip=" + skip);
-
- req.setOffset(skip);
-
- HashMap<String,String> map = new HashMap<>();
- map.put("op", "getHeadlines");
- map.put("sid", sessionId);
- map.put("feed_id", String.valueOf(m_feed.id));
- map.put("show_excerpt", "true");
- map.put("excerpt_length", String.valueOf(CommonActivity.EXCERPT_MAX_LENGTH));
- map.put("show_content", "true");
- map.put("include_attachments", "true");
- map.put("view_mode", m_activity.getViewMode());
- map.put("limit", m_prefs.getString("headlines_request_size", "15"));
- map.put("offset", String.valueOf(0));
- map.put("skip", String.valueOf(skip));
- map.put("include_nested", "true");
- map.put("has_sandbox", "true");
- map.put("order_by", m_activity.getSortMode());
-
- if (m_prefs.getBoolean("enable_image_downsampling", false)) {
- if (m_prefs.getBoolean("always_downsample_images", false) || !m_activity.isWifiConnected()) {
- map.put("resize_width", String.valueOf(m_activity.getResizeWidth()));
- }
- }
-
- if (isCat) map.put("is_cat", "true");
-
- if (allowForceUpdate) {
- map.put("force_update", "true");
- }
-
- if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
- map.put("search", m_searchQuery);
- map.put("search_mode", "");
- map.put("match_on", "both");
- }
-
- if (m_firstId > 0) map.put("check_first_id", String.valueOf(m_firstId));
-
- if (m_activity.getApiLevel() >= 12) {
- map.put("include_header", "true");
- }
-
- Log.d(TAG, "[HP] request more headlines, firstId=" + m_firstId);
-
- req.execute(map);
+ // if we try to initLoader() all the time, onLoadFinished() might be sent twice
+ // https://stackoverflow.com/questions/11293441/android-loadercallbacks-onloadfinished-called-twice
+ if (m_loader == null) {
+ m_loader = (HeadlinesLoader) LoaderManager.getInstance(this).
+ initLoader(Application.LOADER_HEADLINES, null, this);
}
- }
- private int getSkip(boolean append) {
- int skip = 0;
-
- if (append) {
- // adaptive, all_articles, marked, published, unread
- String viewMode = m_activity.getViewMode();
-
- int numUnread = Math.toIntExact(Application.getArticles().getUnreadCount());
- int numAll = Math.toIntExact(Application.getArticles().getSizeWithoutFooters());
-
- if ("marked".equals(viewMode)) {
- skip = numAll;
- } else if ("published".equals(viewMode)) {
- skip = numAll;
- } else if ("unread".equals(viewMode)) {
- skip = numUnread;
- } else if (m_searchQuery != null && !m_searchQuery.isEmpty()) {
- skip = numAll;
- } else if ("adaptive".equals(viewMode)) {
- skip = numUnread > 0 ? numUnread : numAll;
- } else {
- skip = numAll;
- }
- }
-
- return skip;
- } */
+ m_loader.setSearchQuery(getSearchQuery());
+ m_loader.startLoading(append);
+ }
static class ArticleViewHolder extends RecyclerView.ViewHolder {
public View view;
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 7f3dddac..63a1bae4 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
@@ -56,36 +56,27 @@ public class HeadlinesLoader extends AsyncTaskLoader<ArticleList> implements Api
m_prefs = PreferenceManager.getDefaultSharedPreferences(context);
}
- protected void refresh(boolean append) {
- Log.d(TAG, "refresh, append=" + append + " inProgress=" + m_loadingInProgress + " lazyLoadEnabled=" + m_lazyLoadEnabled);
+ protected void startLoading(boolean append) {
+ // Log.d(TAG, this + " refresh, append=" + append + " inProgress=" + m_loadingInProgress + " lazyLoadEnabled=" + m_lazyLoadEnabled);
if (!append) {
m_append = false;
m_lazyLoadEnabled = true;
forceLoad();
- } else if (!m_loadingInProgress && m_lazyLoadEnabled) {
+ } else if (m_lazyLoadEnabled && !m_loadingInProgress) {
m_append = true;
forceLoad();
- } else {
- deliverResult(m_articles);
- }
- }
-
- @Override
- protected void onStartLoading() {
- if (m_articles != null) {
- deliverResult(m_articles);
- } else {
- forceLoad();
+ /* } else {
+ deliverResult(m_articles); */
}
}
@Override
public void deliverResult(ArticleList data) {
- m_articles = data;
+ Log.d(TAG, "deliverResult=" + data);
- super.deliverResult(m_articles);
+ super.deliverResult(data);
}
public int getErrorMessage() {
@@ -106,6 +97,7 @@ public class HeadlinesLoader extends AsyncTaskLoader<ArticleList> implements Api
@Override
public ArticleList loadInBackground() {
+ Log.d(TAG, "loadInBackground append=" + m_append + " offset=" + m_offset);
m_loadingInProgress = true;
@@ -212,6 +204,7 @@ public class HeadlinesLoader extends AsyncTaskLoader<ArticleList> implements Api
m_lazyLoadEnabled = false;
}
+ m_offset += m_amountLoaded;
m_loadingInProgress = false;
return m_articles;
@@ -225,18 +218,6 @@ public class HeadlinesLoader extends AsyncTaskLoader<ArticleList> implements Api
m_loadingInProgress = false;
return null;
-
- /* TODO move to onLoaderFinished() if (m_lastError == ApiCommon.ApiError.LOGIN_FAILED) {
- m_activity.login();
- } else {
-
- if (m_lastErrorMessage != null) {
- m_activity.toast(m_activity.getString(getErrorMessage()) + "\n" + m_lastErrorMessage);
- } else {
- m_activity.toast(getErrorMessage());
- }
- //m_activity.setLoadingStatus(getErrorMessage(), false);
- } */
}
private int getSkip(boolean append) {
@@ -297,4 +278,8 @@ public class HeadlinesLoader extends AsyncTaskLoader<ArticleList> implements Api
public String getSearchQuery() {
return m_searchQuery;
}
+
+ public int getOffset() {
+ return m_offset;
+ }
}
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 ec620337..800ca55f 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
@@ -3,8 +3,6 @@ package org.fox.ttrss.types;
import android.os.Parcel;
import android.os.Parcelable;
-import androidx.annotation.NonNull;
-
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java
index 873b311b..01af780c 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java
@@ -1,8 +1,5 @@
package org.fox.ttrss.types;
-import android.os.Parcel;
-import android.os.Parcelable;
-
import java.util.ListIterator;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;