From 6c50858455da798226c38845386d4b33a566f6e9 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Wed, 14 May 2025 19:29:49 +0300 Subject: refactor some more --- .../src/main/java/org/fox/ttrss/Application.java | 14 +- .../src/main/java/org/fox/ttrss/ArticleModel.java | 316 ++++++++++++++++++++ .../src/main/java/org/fox/ttrss/ArticlePager.java | 4 +- .../src/main/java/org/fox/ttrss/ArticlesModel.java | 319 --------------------- .../main/java/org/fox/ttrss/HeadlinesFragment.java | 14 +- 5 files changed, 330 insertions(+), 337 deletions(-) create mode 100644 org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java delete mode 100644 org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlesModel.java 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 ad6dbb93..75542e3c 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 @@ -17,26 +17,22 @@ public class Application extends android.app.Application { private static Application m_singleton; - // this is the only instance of a (large) object which contains all currently loaded articles and is - // used by all fragments and activities concurrently - // private final ArticleList m_articles = new ArticleList(); - private String m_sessionId; private int m_apiLevel; public LinkedHashMap m_customSortModes = new LinkedHashMap<>(); ConnectivityManager m_cmgr; - ArticlesModel m_articlesModel; + ArticleModel m_articleModel; public static Application getInstance(){ return m_singleton; } public static ArticleList getArticles() { - return getInstance().m_articlesModel.getArticles(); + return getInstance().m_articleModel.getArticles().getValue(); } - public static ArticlesModel getArticlesModel() { - return getInstance().m_articlesModel; + public static ArticleModel getArticlesModel() { + return getInstance().m_articleModel; } @Override @@ -45,7 +41,7 @@ public class Application extends android.app.Application { m_singleton = this; m_cmgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); - m_articlesModel = new ArticlesModel(this); + m_articleModel = new ArticleModel(this); } public String getSessionId() { diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java new file mode 100644 index 00000000..2496b84c --- /dev/null +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java @@ -0,0 +1,316 @@ +package org.fox.ttrss; + +import android.app.Application; +import android.content.SharedPreferences; +import android.os.Handler; +import android.os.Looper; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; +import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; +import androidx.preference.PreferenceManager; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.reflect.TypeToken; + +import org.fox.ttrss.types.Article; +import org.fox.ttrss.types.ArticleList; +import org.fox.ttrss.types.Feed; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ArticleModel extends AndroidViewModel implements ApiCommon.ApiCaller { + private final String TAG = this.getClass().getSimpleName(); + private final MutableLiveData m_articles = new MutableLiveData<>(new ArticleList()); + private SharedPreferences m_prefs; + private final int m_responseCode = 0; + protected String m_responseMessage; + private int m_apiStatusCode = 0; + + private String m_lastErrorMessage; + private ApiCommon.ApiError m_lastError; + private Feed m_feed; + private int m_firstId; + private String m_searchQuery = ""; + private boolean m_firstIdChanged; + private int m_offset; + private int m_amountLoaded; + private int m_resizeWidth; + private boolean m_append; + private boolean m_lazyLoadEnabled = true; + private boolean m_loadingInProgress; + private ExecutorService m_executor; + private Handler m_mainHandler = new Handler(Looper.getMainLooper()); + private MutableLiveData m_lastUpdate = new MutableLiveData<>(new Long(0)); + + public ArticleModel(@NonNull Application application) { + super(application); + + m_prefs = PreferenceManager.getDefaultSharedPreferences(application); + + // do we need concurrency or not? + m_executor = Executors.newSingleThreadExecutor(); + } + + public LiveData getUpdatesData() { + return m_lastUpdate; + } + + public LiveData getArticles() { + return m_articles; + } + + + 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); + } + + public void startLoading(boolean append, @NonNull Feed feed, int resizeWidth) { + Log.d(TAG, "startLoading append=" + append); + + m_resizeWidth = resizeWidth; + + if (!append) { + m_append = false; + m_lazyLoadEnabled = true; + m_feed = feed; + + loadInBackground(); + } else if (feed != m_feed || m_lazyLoadEnabled && !m_loadingInProgress) { + m_append = true; + m_feed = feed; + + loadInBackground(); + } else { + m_articles.postValue(m_articles.getValue()); + } + } + + private ArticleList loadInBackground() { + Log.d(TAG, this + " loadInBackground append=" + m_append + " offset=" + m_offset); + + ArticleList articlesWork = new ArticleList(m_articles.getValue()); + + m_loadingInProgress = true; + + final int skip = getSkip(m_append, articlesWork); + final boolean allowForceUpdate = org.fox.ttrss.Application.getInstance().getApiLevel() >= 9 && + !m_feed.is_cat && m_feed.id > 0 && !m_append && skip == 0; + + HashMap params = new HashMap<>(); + + params.put("op", "getHeadlines"); + params.put("sid", org.fox.ttrss.Application.getInstance().getSessionId()); + params.put("feed_id", String.valueOf(m_feed.id)); + params.put("show_excerpt", "true"); + params.put("excerpt_length", String.valueOf(CommonActivity.EXCERPT_MAX_LENGTH)); + params.put("show_content", "true"); + params.put("include_attachments", "true"); + params.put("view_mode", m_prefs.getString("view_mode", "adaptive")); + params.put("limit", m_prefs.getString("headlines_request_size", "15")); + params.put("skip", String.valueOf(skip)); + params.put("include_nested", "true"); + params.put("has_sandbox", "true"); + params.put("order_by", m_prefs.getString("headlines_sort_mode", "default")); + + if (m_prefs.getBoolean("enable_image_downsampling", false)) { + if (m_prefs.getBoolean("always_downsample_images", false) || !org.fox.ttrss.Application.getInstance().isWifiConnected()) { + params.put("resize_width", String.valueOf(m_resizeWidth)); + } + } + + if (m_feed.is_cat) + params.put("is_cat", "true"); + + if (allowForceUpdate) { + params.put("force_update", "true"); + } + + if (m_searchQuery != null && !m_searchQuery.isEmpty()) { + params.put("search", m_searchQuery); + params.put("search_mode", ""); + params.put("match_on", "both"); + } + + if (m_firstId > 0) + params.put("check_first_id", String.valueOf(m_firstId)); + + if (org.fox.ttrss.Application.getInstance().getApiLevel() >= 12) { + params.put("include_header", "true"); + } + + Log.d(TAG, "firstId=" + m_firstId + " append=" + m_append + " skip=" + skip + " localSize=" + articlesWork.size()); + + m_executor.execute(() -> { + JsonElement result = ApiCommon.performRequest(getApplication(), params, this); + + Log.d(TAG, "got result=" + result); + + if (result != null) { + try { + JsonArray content = result.getAsJsonArray(); + if (content != null) { + final List
articlesJson; + final JsonObject header; + + if (org.fox.ttrss.Application.getInstance().getApiLevel() >= 12) { + header = content.get(0).getAsJsonObject(); + + m_firstIdChanged = header.get("first_id_changed") != null; + + try { + m_firstId = header.get("first_id").getAsInt(); + } catch (NumberFormatException e) { + m_firstId = 0; + } + + Log.d(TAG, this + " firstID=" + m_firstId + " firstIdChanged=" + m_firstIdChanged); + + Type listType = new TypeToken>() {}.getType(); + articlesJson = new Gson().fromJson(content.get(1), listType); + } else { + Type listType = new TypeToken>() {}.getType(); + articlesJson = new Gson().fromJson(content, listType); + } + + if (!m_append) + articlesWork.clear(); + + m_amountLoaded = articlesJson.size(); + + for (Article article : articlesJson) + if (!articlesWork.containsId(article.id)) { + article.collectMediaInfo(); + article.cleanupExcerpt(); + article.fixNullFields(); + articlesWork.add(article); + } + + if (m_firstIdChanged) { + Log.d(TAG, "first id changed, disabling lazy load"); + m_lazyLoadEnabled = false; + } + + if (m_amountLoaded < Integer.parseInt(m_prefs.getString("headlines_request_size", "15"))) { + Log.d(TAG, this + " amount loaded "+m_amountLoaded+" < request size, disabling lazy load"); + m_lazyLoadEnabled = false; + } + + m_offset += m_amountLoaded; + m_loadingInProgress = false; + + Log.d(TAG, this + " loaded headlines=" + m_amountLoaded + " resultingLocalSize=" + articlesWork.size()); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + m_mainHandler.post(() -> { + m_articles.setValue(articlesWork); + m_lastUpdate.setValue(System.currentTimeMillis()); + }); + }); + + m_loadingInProgress = false; + + return articlesWork; + } + + private int getSkip(boolean append, ArticleList articles) { + int skip = 0; + + if (append) { + // adaptive, all_articles, marked, published, unread + String viewMode = m_prefs.getString("view_mode", "adaptive"); + + int numUnread = Math.toIntExact(articles.getUnreadCount()); + int numAll = Math.toIntExact(articles.size()); + + 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; + } + + @Override + public void setStatusCode(int statusCode) { + m_apiStatusCode = statusCode; + } + + @Override + public void setLastError(ApiCommon.ApiError lastError) { + m_lastError = lastError; + } + + @Override + public void setLastErrorMessage(String message) { + m_lastErrorMessage = message; + } + + public boolean getFirstIdChanged() { + return m_firstIdChanged; + } + + public boolean getAppend() { + return m_append; + } + + public void setSearchQuery(String searchQuery) { + m_searchQuery = searchQuery; + } + + public String getSearchQuery() { + return m_searchQuery; + } + + public int getOffset() { + return m_offset; + } + + public boolean lazyLoadEnabled() { + return m_lazyLoadEnabled; + } + + public int getErrorMessage() { + return ApiCommon.getErrorMessage(m_lastError); + } + + ApiCommon.ApiError getLastError() { + return m_lastError; + } + + String getLastErrorMessage() { + return m_lastErrorMessage; + } + + public boolean isLoading() { + return m_loadingInProgress; + } +} 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 d2978858..cf43f4f0 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 @@ -82,10 +82,10 @@ public class ArticlePager extends androidx.fragment.app.Fragment { m_adapter = new PagerAdapter(this); m_adapter.submitList(Application.getArticles()); - ArticlesModel model = Application.getArticlesModel(); + ArticleModel model = Application.getArticlesModel(); // deal with further updates - model.getArticlesData().observe(getActivity(), articles -> { + model.getArticles().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/ArticlesModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlesModel.java deleted file mode 100644 index 66027966..00000000 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticlesModel.java +++ /dev/null @@ -1,319 +0,0 @@ -package org.fox.ttrss; - -import android.app.Application; -import android.content.SharedPreferences; -import android.os.Handler; -import android.os.Looper; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.LiveData; -import androidx.lifecycle.MutableLiveData; -import androidx.preference.PreferenceManager; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.reflect.TypeToken; - -import org.fox.ttrss.types.Article; -import org.fox.ttrss.types.ArticleList; -import org.fox.ttrss.types.Feed; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.List; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -public class ArticlesModel extends AndroidViewModel implements ApiCommon.ApiCaller { - private final String TAG = this.getClass().getSimpleName(); - private final MutableLiveData m_articles = new MutableLiveData<>(new ArticleList()); - private SharedPreferences m_prefs; - private final int m_responseCode = 0; - protected String m_responseMessage; - private int m_apiStatusCode = 0; - - private String m_lastErrorMessage; - private ApiCommon.ApiError m_lastError; - private Feed m_feed; - private int m_firstId; - private String m_searchQuery = ""; - private boolean m_firstIdChanged; - private int m_offset; - private int m_amountLoaded; - private int m_resizeWidth; - private boolean m_append; - private boolean m_lazyLoadEnabled = true; - private boolean m_loadingInProgress; - private ExecutorService m_executor; - private Handler m_mainHandler = new Handler(Looper.getMainLooper()); - private MutableLiveData m_lastUpdate = new MutableLiveData<>(new Long(0)); - - public ArticlesModel(@NonNull Application application) { - super(application); - - m_prefs = PreferenceManager.getDefaultSharedPreferences(application); - - // do we need concurrency or not? - m_executor = Executors.newSingleThreadExecutor(); - } - - public LiveData getUpdatesData() { - return m_lastUpdate; - } - - public LiveData getArticlesData() { - return m_articles; - } - - public ArticleList getArticles() { - 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); - } - - public void startLoading(boolean append, @NonNull Feed feed, int resizeWidth) { - Log.d(TAG, "startLoading append=" + append); - - m_resizeWidth = resizeWidth; - - if (!append) { - m_append = false; - m_lazyLoadEnabled = true; - m_feed = feed; - - loadInBackground(); - } else if (feed != m_feed || m_lazyLoadEnabled && !m_loadingInProgress) { - m_append = true; - m_feed = feed; - - loadInBackground(); - } else { - m_articles.postValue(m_articles.getValue()); - } - } - - private ArticleList loadInBackground() { - Log.d(TAG, this + " loadInBackground append=" + m_append + " offset=" + m_offset); - - ArticleList articlesWork = new ArticleList(m_articles.getValue()); - - m_loadingInProgress = true; - - final int skip = getSkip(m_append, articlesWork); - final boolean allowForceUpdate = org.fox.ttrss.Application.getInstance().getApiLevel() >= 9 && - !m_feed.is_cat && m_feed.id > 0 && !m_append && skip == 0; - - HashMap params = new HashMap<>(); - - params.put("op", "getHeadlines"); - params.put("sid", org.fox.ttrss.Application.getInstance().getSessionId()); - params.put("feed_id", String.valueOf(m_feed.id)); - params.put("show_excerpt", "true"); - params.put("excerpt_length", String.valueOf(CommonActivity.EXCERPT_MAX_LENGTH)); - params.put("show_content", "true"); - params.put("include_attachments", "true"); - params.put("view_mode", m_prefs.getString("view_mode", "adaptive")); - params.put("limit", m_prefs.getString("headlines_request_size", "15")); - params.put("skip", String.valueOf(skip)); - params.put("include_nested", "true"); - params.put("has_sandbox", "true"); - params.put("order_by", m_prefs.getString("headlines_sort_mode", "default")); - - if (m_prefs.getBoolean("enable_image_downsampling", false)) { - if (m_prefs.getBoolean("always_downsample_images", false) || !org.fox.ttrss.Application.getInstance().isWifiConnected()) { - params.put("resize_width", String.valueOf(m_resizeWidth)); - } - } - - if (m_feed.is_cat) - params.put("is_cat", "true"); - - if (allowForceUpdate) { - params.put("force_update", "true"); - } - - if (m_searchQuery != null && !m_searchQuery.isEmpty()) { - params.put("search", m_searchQuery); - params.put("search_mode", ""); - params.put("match_on", "both"); - } - - if (m_firstId > 0) - params.put("check_first_id", String.valueOf(m_firstId)); - - if (org.fox.ttrss.Application.getInstance().getApiLevel() >= 12) { - params.put("include_header", "true"); - } - - Log.d(TAG, "firstId=" + m_firstId + " append=" + m_append + " skip=" + skip + " localSize=" + articlesWork.size()); - - m_executor.execute(() -> { - JsonElement result = ApiCommon.performRequest(getApplication(), params, this); - - Log.d(TAG, "got result=" + result); - - if (result != null) { - try { - JsonArray content = result.getAsJsonArray(); - if (content != null) { - final List
articlesJson; - final JsonObject header; - - if (org.fox.ttrss.Application.getInstance().getApiLevel() >= 12) { - header = content.get(0).getAsJsonObject(); - - m_firstIdChanged = header.get("first_id_changed") != null; - - try { - m_firstId = header.get("first_id").getAsInt(); - } catch (NumberFormatException e) { - m_firstId = 0; - } - - Log.d(TAG, this + " firstID=" + m_firstId + " firstIdChanged=" + m_firstIdChanged); - - Type listType = new TypeToken>() {}.getType(); - articlesJson = new Gson().fromJson(content.get(1), listType); - } else { - Type listType = new TypeToken>() {}.getType(); - articlesJson = new Gson().fromJson(content, listType); - } - - if (!m_append) - articlesWork.clear(); - - m_amountLoaded = articlesJson.size(); - - for (Article article : articlesJson) - if (!articlesWork.containsId(article.id)) { - article.collectMediaInfo(); - article.cleanupExcerpt(); - article.fixNullFields(); - articlesWork.add(article); - } - - if (m_firstIdChanged) { - Log.d(TAG, "first id changed, disabling lazy load"); - m_lazyLoadEnabled = false; - } - - if (m_amountLoaded < Integer.parseInt(m_prefs.getString("headlines_request_size", "15"))) { - Log.d(TAG, this + " amount loaded "+m_amountLoaded+" < request size, disabling lazy load"); - m_lazyLoadEnabled = false; - } - - m_offset += m_amountLoaded; - m_loadingInProgress = false; - - Log.d(TAG, this + " loaded headlines=" + m_amountLoaded + " resultingLocalSize=" + articlesWork.size()); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - m_mainHandler.post(() -> { - m_articles.setValue(articlesWork); - m_lastUpdate.setValue(System.currentTimeMillis()); - }); - }); - - m_loadingInProgress = false; - - return articlesWork; - } - - private int getSkip(boolean append, ArticleList articles) { - int skip = 0; - - if (append) { - // adaptive, all_articles, marked, published, unread - String viewMode = m_prefs.getString("view_mode", "adaptive"); - - int numUnread = Math.toIntExact(articles.getUnreadCount()); - int numAll = Math.toIntExact(articles.size()); - - 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; - } - - @Override - public void setStatusCode(int statusCode) { - m_apiStatusCode = statusCode; - } - - @Override - public void setLastError(ApiCommon.ApiError lastError) { - m_lastError = lastError; - } - - @Override - public void setLastErrorMessage(String message) { - m_lastErrorMessage = message; - } - - public boolean getFirstIdChanged() { - return m_firstIdChanged; - } - - public boolean getAppend() { - return m_append; - } - - public void setSearchQuery(String searchQuery) { - m_searchQuery = searchQuery; - } - - public String getSearchQuery() { - return m_searchQuery; - } - - public int getOffset() { - return m_offset; - } - - public boolean lazyLoadEnabled() { - return m_lazyLoadEnabled; - } - - public int getErrorMessage() { - return ApiCommon.getErrorMessage(m_lastError); - } - - ApiCommon.ApiError getLastError() { - return m_lastError; - } - - String getLastErrorMessage() { - return m_lastErrorMessage; - } - - public boolean isLoading() { - return m_loadingInProgress; - } -} 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 da1c160b..28ffafec 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 @@ -389,7 +389,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); - ArticlesModel model = Application.getArticlesModel(); + ArticleModel model = Application.getArticlesModel(); if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (!m_readArticles.isEmpty() && !m_isLazyLoading && !model.isLoading() && m_prefs.getBoolean("headlines_mark_read_scroll", false)) { @@ -438,7 +438,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { // Log.d(TAG, "pending to auto mark as read count=" + m_readArticles.size()); } - ArticlesModel model = Application.getArticlesModel(); + ArticleModel model = Application.getArticlesModel(); if (dy > 0 && !m_isLazyLoading && !model.isLoading() && model.lazyLoadEnabled() && lastVisibleItem >= Application.getArticles().size() - 5) { @@ -457,11 +457,11 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { m_activity.setTitle(m_feed.title); } - ArticlesModel model = Application.getArticlesModel(); + ArticleModel model = Application.getArticlesModel(); // this gets notified on network update model.getUpdatesData().observe(getActivity(), lastUpdate -> { - ArticleList tmp = new ArticleList(model.getArticles()); + ArticleList tmp = new ArticleList(model.getArticles().getValue()); Log.d(TAG, "observed last update=" + lastUpdate + " article count=" + tmp.size()); @@ -500,10 +500,10 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { }); // loaded articles might get modified for all sorts of reasons - model.getArticlesData().observe(getActivity(), articles -> { + model.getArticles().observe(getActivity(), articles -> { Log.d(TAG, "observed article list size=" + articles.size()); - ArticleList tmp = new ArticleList(model.getArticles()); + ArticleList tmp = new ArticleList(articles); if (m_prefs.getBoolean("headlines_mark_read_scroll", false)) tmp.add(new Article(Article.TYPE_AMR_FOOTER)); @@ -542,7 +542,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { } public void refresh(final boolean append) { - ArticlesModel model = Application.getArticlesModel(); + ArticleModel model = Application.getArticlesModel(); if (!append) m_activeArticleId = -1; -- cgit v1.2.3-54-g00ecf