diff options
| author | Andrew Dolgov <fox@fakecake.org> | 2025-05-14 18:43:19 +0300 |
|---|---|---|
| committer | Andrew Dolgov <fox@fakecake.org> | 2025-05-14 18:43:19 +0300 |
| commit | 895b0d9c2473fcd3351c5368176b79e63b1d6079 (patch) | |
| tree | ae40e0345bb773fa8f9c80532ee964be257e94d7 | |
| parent | 1580f921cf2433d27591bf9358a3f23bc3d2e95e (diff) | |
refactor to more consistent naming, allow observing articlelist changes and update requests separately
| -rwxr-xr-x | org.fox.ttrss/src/main/java/org/fox/ttrss/Application.java | 6 | ||||
| -rwxr-xr-x | org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlePager.java | 8 | ||||
| -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-x | org.fox.ttrss/src/main/java/org/fox/ttrss/HeadlinesFragment.java | 54 | ||||
| -rwxr-xr-x | org.fox.ttrss/src/main/java/org/fox/ttrss/OnlineActivity.java | 17 | ||||
| -rwxr-xr-x | org.fox.ttrss/src/main/java/org/fox/ttrss/types/Article.java | 39 | ||||
| -rwxr-xr-x | org.fox.ttrss/src/main/java/org/fox/ttrss/types/ArticleList.java | 4 | ||||
| -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; } |