summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Dolgov <fox@fakecake.org>2025-05-14 18:43:19 +0300
committerAndrew Dolgov <fox@fakecake.org>2025-05-14 18:43:19 +0300
commit895b0d9c2473fcd3351c5368176b79e63b1d6079 (patch)
treeae40e0345bb773fa8f9c80532ee964be257e94d7
parent1580f921cf2433d27591bf9358a3f23bc3d2e95e (diff)
refactor to more consistent naming, allow observing articlelist changes and update requests separately
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/Application.java6
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java8
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlesModel.java (renamed from org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesModel.java)29
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java54
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java17
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java39
-rwxr-xr-xorg.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java4
-rw-r--r--org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java (renamed from org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesDiffItemCallback.java)5
8 files changed, 111 insertions, 51 deletions
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java
index 08beaa99..441929f4 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java
@@ -25,7 +25,7 @@ public class Application extends android.app.Application {
private int m_apiLevel;
public LinkedHashMap<String, String> m_customSortModes = new LinkedHashMap<>();
ConnectivityManager m_cmgr;
- HeadlinesModel m_headlinesModel;
+ ArticlesModel m_headlinesModel;
public static Application getInstance(){
return m_singleton;
@@ -35,7 +35,7 @@ public class Application extends android.app.Application {
return getInstance().m_headlinesModel.getArticles();
}
- public HeadlinesModel getHeadlinesModel() {
+ public static ArticlesModel getHeadlinesModel() {
return getInstance().m_headlinesModel;
}
@@ -45,7 +45,7 @@ public class Application extends android.app.Application {
m_singleton = this;
m_cmgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
- m_headlinesModel = new HeadlinesModel(this);
+ m_headlinesModel = new ArticlesModel(this);
}
public String getSessionId() {
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 89043cbc..ce3b114e 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
@@ -16,7 +16,7 @@ import org.fox.ttrss.types.Article;
import org.fox.ttrss.types.ArticleList;
import org.fox.ttrss.types.Feed;
import org.fox.ttrss.util.DiffFragmentStateAdapter;
-import org.fox.ttrss.util.HeadlinesDiffItemCallback;
+import org.fox.ttrss.util.ArticleDiffItemCallback;
public class ArticlePager extends androidx.fragment.app.Fragment {
@@ -31,7 +31,7 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
private static class PagerAdapter extends DiffFragmentStateAdapter<Article> {
public PagerAdapter(@NonNull Fragment fragment) {
- super(fragment, new HeadlinesDiffItemCallback());
+ super(fragment, new ArticleDiffItemCallback());
}
private void syncToSharedArticles() {
@@ -85,10 +85,10 @@ public class ArticlePager extends androidx.fragment.app.Fragment {
m_adapter = new PagerAdapter(this);
m_adapter.submitList(Application.getArticles());
- HeadlinesModel model = Application.getInstance().getHeadlinesModel();
+ ArticlesModel model = Application.getInstance().getHeadlinesModel();
// deal with further updates
- model.getLiveData().observe(getActivity(), articles -> {
+ model.getArticlesData().observe(getActivity(), articles -> {
Log.d(TAG, "observed article list size=" + articles.size());
m_adapter.submitList(articles);
});
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlesModel.java
index cc8a9d3d..af535580 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesModel.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlesModel.java
@@ -1,7 +1,6 @@
package org.fox.ttrss;
import android.app.Application;
-import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
@@ -11,7 +10,6 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
-import androidx.loader.app.LoaderManager;
import androidx.preference.PreferenceManager;
import com.google.gson.Gson;
@@ -30,7 +28,7 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-public class HeadlinesModel extends AndroidViewModel implements ApiCommon.ApiCaller {
+public class ArticlesModel extends AndroidViewModel implements ApiCommon.ApiCaller {
private final String TAG = this.getClass().getSimpleName();
private final MutableLiveData<ArticleList> m_articles = new MutableLiveData<>(new ArticleList());
private SharedPreferences m_prefs;
@@ -52,8 +50,9 @@ public class HeadlinesModel extends AndroidViewModel implements ApiCommon.ApiCal
private boolean m_loadingInProgress;
private ExecutorService m_executor;
private Handler m_mainHandler = new Handler(Looper.getMainLooper());
+ private MutableLiveData<Long> m_lastUpdate = new MutableLiveData<>(new Long(0));
- public HeadlinesModel(@NonNull Application application) {
+ public ArticlesModel(@NonNull Application application) {
super(application);
m_prefs = PreferenceManager.getDefaultSharedPreferences(application);
@@ -62,7 +61,11 @@ public class HeadlinesModel extends AndroidViewModel implements ApiCommon.ApiCal
m_executor = Executors.newSingleThreadExecutor();
}
- public LiveData<ArticleList> getLiveData() {
+ public LiveData<Long> getUpdatesData() {
+ return m_lastUpdate;
+ }
+
+ public LiveData<ArticleList> getArticlesData() {
return m_articles;
}
@@ -70,6 +73,11 @@ public class HeadlinesModel extends AndroidViewModel implements ApiCommon.ApiCal
return m_articles.getValue();
}
+ public void update(int position, Article article) {
+ m_articles.getValue().set(position, article);
+ m_articles.postValue(m_articles.getValue());
+ }
+
public void update(ArticleList articles) {
m_articles.postValue(articles);
}
@@ -90,17 +98,13 @@ public class HeadlinesModel extends AndroidViewModel implements ApiCommon.ApiCal
m_feed = feed;
forceLoad();
} else {
- ArticleList tmp = new ArticleList();
- tmp.addAll(m_articles.getValue());
-
- m_articles.postValue(tmp);
+ m_articles.postValue(m_articles.getValue());
}
}
private void forceLoad() {
Log.d(TAG, "forceLoad");
-
- m_articles.postValue(loadInBackground());
+ loadInBackground();
}
private ArticleList loadInBackground() {
@@ -225,7 +229,8 @@ public class HeadlinesModel extends AndroidViewModel implements ApiCommon.ApiCal
}
m_mainHandler.post(() -> {
- m_articles.postValue(articlesWork);
+ m_articles.setValue(articlesWork);
+ m_lastUpdate.setValue(System.currentTimeMillis());
});
});
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 2e6a4323..62f32cfa 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
@@ -43,12 +43,9 @@ import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.TextView;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ActivityOptionsCompat;
import androidx.core.view.ViewCompat;
-import androidx.loader.content.Loader;
import androidx.preference.PreferenceManager;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.ItemTouchHelper;
@@ -74,13 +71,12 @@ 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.HeadlinesDiffItemCallback;
+import org.fox.ttrss.util.ArticleDiffItemCallback;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
-import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.TimeZone;
@@ -395,7 +391,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
- HeadlinesModel model = Application.getInstance().getHeadlinesModel();
+ ArticlesModel model = Application.getInstance().getHeadlinesModel();
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
if (!m_readArticles.isEmpty() && !m_isLazyLoading && !model.isLoading() && m_prefs.getBoolean("headlines_mark_read_scroll", false)) {
@@ -444,7 +440,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
// Log.d(TAG, "pending to auto mark as read count=" + m_readArticles.size());
}
- HeadlinesModel model = Application.getInstance().getHeadlinesModel();
+ ArticlesModel model = Application.getInstance().getHeadlinesModel();
if (dy > 0 && !m_isLazyLoading && !model.isLoading() && model.lazyLoadEnabled() &&
lastVisibleItem >= Application.getArticles().size() - 5) {
@@ -463,14 +459,13 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_activity.setTitle(m_feed.title);
}
- HeadlinesModel model = Application.getInstance().getHeadlinesModel();
+ ArticlesModel model = Application.getHeadlinesModel();
- model.getLiveData().observe(getActivity(), articles -> {
- Log.d(TAG, "observed article list size=" + articles.size() + " append=" + model.getAppend());
+ // this gets notified on network update
+ model.getUpdatesData().observe(getActivity(), lastUpdate -> {
+ ArticleList tmp = new ArticleList(model.getArticles());
- ArticleList tmp = new ArticleList();
-
- tmp.addAll(articles);
+ Log.d(TAG, "observed last update=" + lastUpdate + " article count=" + tmp.size());
if (m_prefs.getBoolean("headlines_mark_read_scroll", false))
tmp.add(new Article(Article.TYPE_AMR_FOOTER));
@@ -503,6 +498,19 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
m_activity.toast(model.getErrorMessage());
}
}
+
+ });
+
+ // loaded articles might get modified for all sorts of reasons
+ model.getArticlesData().observe(getActivity(), articles -> {
+ Log.d(TAG, "observed article list size=" + articles.size());
+
+ ArticleList tmp = new ArticleList(model.getArticles());
+
+ if (m_prefs.getBoolean("headlines_mark_read_scroll", false))
+ tmp.add(new Article(Article.TYPE_AMR_FOOTER));
+
+ m_adapter.submitList(tmp);
});
return view;
@@ -536,7 +544,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
}
public void refresh(final boolean append) {
- HeadlinesModel model = Application.getInstance().getHeadlinesModel();
+ ArticlesModel model = Application.getInstance().getHeadlinesModel();
if (!append)
m_activeArticleId = -1;
@@ -688,7 +696,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
}
public ArticleListAdapter() {
- super(new HeadlinesDiffItemCallback());
+ super(new ArticleDiffItemCallback());
Display display = m_activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
@@ -836,11 +844,11 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
holder.markedView.setIconTint(ColorStateList.valueOf(tvPrimary.data));
holder.markedView.setOnClickListener(v -> {
- article.marked = !article.marked;
+ Article selectedArticle = new Article(getItem(position));
+ selectedArticle.marked = !selectedArticle.marked;
- m_adapter.notifyItemChanged(m_list.getChildAdapterPosition(holder.view));
-
- m_activity.saveArticleMarked(article);
+ m_activity.saveArticleMarked(selectedArticle);
+ Application.getHeadlinesModel().update(position, selectedArticle);
});
}
@@ -901,10 +909,12 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment {
holder.publishedView.setIconTint(ColorStateList.valueOf(tvPrimary.data));
holder.publishedView.setOnClickListener(v -> {
- article.published = !article.published;
- m_adapter.notifyItemChanged(m_list.getChildAdapterPosition(holder.view));
+ Article selectedArticle = new Article(getItem(position));
+ selectedArticle.published = !selectedArticle.published;
+
+ m_activity.saveArticlePublished(selectedArticle);
- m_activity.saveArticlePublished(article);
+ Application.getHeadlinesModel().update(position, selectedArticle);
});
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java
index db06415f..4faff8af 100755
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java
@@ -864,7 +864,8 @@ public class OnlineActivity extends CommonActivity {
protected void setApiLevel(int apiLevel) {
Application.getInstance().setApiLevel(apiLevel);
}
-
+
+ // TODO switch to setArticleField()
public void saveArticleUnread(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -878,11 +879,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("mode", article.unread ? "1" : "0");
- map.put("field", "2");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_UNREAD));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticleScore(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -896,11 +898,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("data", String.valueOf(article.score));
- map.put("field", "4");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_SCORE));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticleMarked(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -914,11 +917,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("mode", article.marked ? "1" : "0");
- map.put("field", "0");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_MARKED));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticlePublished(final Article article) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
@@ -933,11 +937,12 @@ public class OnlineActivity extends CommonActivity {
map.put("op", "updateArticle");
map.put("article_ids", String.valueOf(article.id));
map.put("mode", article.published ? "1" : "0");
- map.put("field", "1");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_PUBLISHED));
req.execute(map);
}
+ // TODO switch to setArticleField()
public void saveArticleNote(final Article article, final String note) {
ApiRequest req = new ApiRequest(getApplicationContext()) {
protected void onPostExecute(JsonElement result) {
@@ -951,7 +956,7 @@ public class OnlineActivity extends CommonActivity {
map.put("article_ids", String.valueOf(article.id));
map.put("mode", "1");
map.put("data", note);
- map.put("field", "3");
+ map.put("field", String.valueOf(Article.UPDATE_FIELD_NOTE));
req.execute(map);
}
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 624e54e4..c0f63937 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
@@ -69,7 +69,7 @@ public class Article implements Parcelable {
transient public String youtubeVid;
transient public List<Element> mediaList = new ArrayList<>();
- public Article(Parcel in) {
+ public Article(Parcel in) {
readFromParcel(in);
}
@@ -195,6 +195,43 @@ public class Article implements Parcelable {
fixNullFields();
}
+ public Article(Article clone) {
+ id = clone.id;
+ unread = clone.unread;
+ marked = clone.marked;
+ published = clone.published;
+ score = clone.score;
+ updated = clone.updated;
+ is_updated = clone.is_updated;
+ title = clone.title;
+ link = clone.link;
+ feed_id = clone.feed_id;
+ tags = clone.tags;
+ attachments = clone.attachments;
+ content = clone.content;
+ excerpt = clone.excerpt;
+ labels = clone.labels;
+ feed_title = clone.feed_title;
+ comments_count = clone.comments_count;
+ comments_link = clone.comments_link;
+ always_display_attachments = clone.always_display_attachments;
+ author = clone.author;
+ note = clone.note;
+ selected = clone.selected;
+ flavor_image = clone.flavor_image;
+ flavor_stream = clone.flavor_stream;
+ flavor_kind = clone.flavor_kind;
+ site_url = clone.site_url;
+
+ articleDoc = clone.articleDoc;
+ flavorImage = clone.flavorImage;
+
+ flavorImageUri = clone.flavorImageUri;
+ flavorStreamUri = clone.flavorStreamUri;
+ youtubeVid = clone.youtubeVid;
+ mediaList = new ArrayList<>(clone.mediaList);
+ }
+
@Override
public int describeContents() {
return 0;
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 01af780c..74df2c33 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
@@ -23,6 +23,10 @@ public class ArticleList extends CopyOnWriteArrayList<Article> {
public ArticleList() { }
+ public ArticleList(ArticleList clone) {
+ this.addAll(clone);
+ }
+
public ArticleList getWithoutFooters() {
return this.stream().filter(a -> { return a.id > 0; }).collect(Collectors.toCollection(ArticleList::new));
}
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesDiffItemCallback.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java
index c236610c..b037eea0 100644
--- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/HeadlinesDiffItemCallback.java
+++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java
@@ -5,11 +5,10 @@ import androidx.recyclerview.widget.DiffUtil;
import org.fox.ttrss.types.Article;
-public class HeadlinesDiffItemCallback extends DiffUtil.ItemCallback<Article> {
+public class ArticleDiffItemCallback extends DiffUtil.ItemCallback<Article> {
+ private final String TAG = this.getClass().getSimpleName();
@Override
public boolean areItemsTheSame(@NonNull Article a1, @NonNull Article a2) {
- // Log.d(TAG, "[DIFF] areItemsTheSame a1=" + a1.title + " a2=" + a2.title);
-
return a1.id == a2.id;
}