diff options
| author | Andrew Dolgov <fox@fakecake.org> | 2025-05-20 08:26:48 +0300 |
|---|---|---|
| committer | Andrew Dolgov <fox@fakecake.org> | 2025-05-20 08:26:48 +0300 |
| commit | 0ad4c4e3fcbfd2113aaf37db5001238b5f8898bc (patch) | |
| tree | d6e7615439e3e70c89b85caf5cf73f31cc90026e /org.fox.ttrss/src/main/java | |
| parent | caad6e9df646d0634b63b5be45a8fab7568f1ebd (diff) | |
move active article handling to model, optimize imports
Diffstat (limited to 'org.fox.ttrss/src/main/java')
19 files changed, 213 insertions, 326 deletions
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 index 39dbda57..8657623e 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleModel.java @@ -27,7 +27,6 @@ import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.stream.Collectors; public class ArticleModel extends AndroidViewModel implements ApiCommon.ApiCaller { private final String TAG = this.getClass().getSimpleName(); @@ -53,6 +52,7 @@ public class ArticleModel extends AndroidViewModel implements ApiCommon.ApiCalle private Handler m_mainHandler = new Handler(Looper.getMainLooper()); private MutableLiveData<Long> m_lastUpdate = new MutableLiveData<>(Long.valueOf(0)); private MutableLiveData<Integer> m_loadingProgress = new MutableLiveData<>(Integer.valueOf(0)); + private MutableLiveData<Integer> m_activeArticleId = new MutableLiveData<>(Integer.valueOf(0)); public ArticleModel(@NonNull Application application) { super(application); @@ -87,6 +87,42 @@ public class ArticleModel extends AndroidViewModel implements ApiCommon.ApiCalle m_articles.postValue(articles); } + public LiveData<Integer> getActive() { + return m_activeArticleId; + } + + public Article getActiveArticle() { + int activeId = m_activeArticleId.getValue(); + + return m_articles.getValue().getById(activeId); + } + + // we store .active flag in articleview for UI update and a separate observable for easy access + public void setActive(Article article) { + Article currentlyActive = getActiveArticle(); + + Log.d(TAG, "setActive set=" + article + " previous=" + currentlyActive); + + if (currentlyActive != null && (article == null || currentlyActive.id != article.id)) { + Article currentlyActiveClone = new Article(currentlyActive); + currentlyActiveClone.active = false; + + updateById(currentlyActiveClone); + } + + if (article != null) { + Article articleClone = new Article(article); + + articleClone.active = true; + updateById(articleClone); + + m_activeArticleId.postValue(articleClone.id); + } else { + m_activeArticleId.postValue(0); + } + } + + public void startLoading(boolean append, @NonNull Feed feed, int resizeWidth) { Log.d(TAG, "startLoading append=" + append + " feed id=" + feed.id + " cat=" + feed.is_cat + " lazyLoadEnabled=" + m_lazyLoadEnabled + " isLoading=" + m_isLoading.getValue()); 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 52f78cf0..c8fde41d 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 @@ -23,7 +23,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment { private final String TAG = this.getClass().getSimpleName(); private PagerAdapter m_adapter; private HeadlinesEventListener m_listener; - private int m_articleId; private OnlineActivity m_activity; private Feed m_feed; private ViewPager2 m_pager; @@ -51,7 +50,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment { } public void initialize(int articleId, Feed feed) { - m_articleId = articleId; m_feed = feed; } @@ -59,7 +57,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment { public void onSaveInstanceState(Bundle out) { super.onSaveInstanceState(out); - out.putInt("m_articleId", m_articleId); out.putParcelable("m_feed", m_feed); } @@ -68,7 +65,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment { super.onCreate(savedInstanceState); if (savedInstanceState != null) { - m_articleId = savedInstanceState.getInt("m_articleId"); m_feed = savedInstanceState.getParcelable("m_feed"); } @@ -89,18 +85,22 @@ public class ArticlePager extends androidx.fragment.app.Fragment { Log.d(TAG, "observed article list size=" + articles.size()); m_adapter.submitList(articles); }); - - m_pager = view.findViewById(R.id.article_pager); - m_listener.onArticleSelected(Application.getArticles().getById(m_articleId), false); + model.getActive().observe(getActivity(), (activeArticleId) -> { + Log.d(TAG, "observed active article=" + activeArticleId); - m_pager.setAdapter(m_adapter); - m_pager.setOffscreenPageLimit(3); + if (activeArticleId != null) { + int position = model.getArticles().getValue().getPositionById(activeArticleId); - int position = Application.getArticles().getPositionById(m_articleId); + if (position != -1 && position != m_pager.getCurrentItem()) + m_pager.setCurrentItem(position, false); + } + }); - if (position != -1) - m_pager.setCurrentItem(position, false); + m_pager = view.findViewById(R.id.article_pager); + + m_pager.setAdapter(m_adapter); + m_pager.setOffscreenPageLimit(3); m_pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override @@ -110,12 +110,7 @@ public class ArticlePager extends androidx.fragment.app.Fragment { // wtf if (position != -1) { Article article = Application.getArticles().get(position); - - if (article != null) { - m_articleId = article.id; - - m_listener.onArticleSelected(article, false); - } + Application.getArticlesModel().setActive(article); } } }); @@ -138,17 +133,8 @@ public class ArticlePager extends androidx.fragment.app.Fragment { m_activity.invalidateOptionsMenu(); } - public void setActiveArticleId(int articleId) { - if (m_pager != null && articleId != m_articleId) { - int position = Application.getArticles().getPositionById(articleId); - - if (position != -1) - m_pager.setCurrentItem(position, false); - } - } - public void switchToArticle(boolean next) { - int position = Application.getArticles().getPositionById(m_articleId); + int position = m_pager.getCurrentItem(); if (position != -1) { @@ -160,22 +146,14 @@ public class ArticlePager extends androidx.fragment.app.Fragment { try { Article targetArticle = Application.getArticles().get(position); - setActiveArticleId(targetArticle.id); + Application.getArticlesModel().setActive(targetArticle); + } catch (IndexOutOfBoundsException e) { e.printStackTrace(); } } } - public int getSelectedArticleId() { - return m_articleId; - } - - public void notifyItemChanged(int position) { - if (m_adapter != null) - m_adapter.notifyItemChanged(position); - } - public void syncToSharedArticles() { if (m_adapter != null) m_adapter.syncToSharedArticles(); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java index aa96940f..847f7981 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/DetailActivity.java @@ -26,7 +26,6 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList protected BottomAppBar m_bottomAppBar; protected SharedPreferences m_prefs; - //private int m_activeArticleId; @SuppressLint("NewApi") @Override @@ -68,33 +67,29 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList if (m_bottomAppBar != null) { m_bottomAppBar.setOnMenuItemClickListener(item -> { + Article activeArticle = Application.getArticlesModel().getActiveArticle(); - final ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - final HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - Article article = Application.getArticles().getById(ap.getSelectedArticleId()); - - if (article != null) { + if (activeArticle != null) { int itemId = item.getItemId(); if (itemId == R.id.article_set_labels) { - editArticleLabels(article); + editArticleLabels(activeArticle); return true; } else if (itemId == R.id.toggle_attachments) { - displayAttachments(article); + displayAttachments(activeArticle); return true; } else if (itemId == R.id.article_edit_note) { - editArticleNote(article); + editArticleNote(activeArticle); return true; } else if (itemId == R.id.article_set_score) { - setArticleScore(article); + setArticleScore(activeArticle); return true; } else if (itemId == R.id.toggle_unread) { - Article articleClone = new Article(article); + Article articleClone = new Article(activeArticle); articleClone.unread = !articleClone.unread; saveArticleUnread(articleClone); @@ -114,13 +109,10 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList fab.show(); fab.setOnClickListener(view -> { - ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (ap != null) { - Article article = Application.getArticles().getById(ap.getSelectedArticleId()); + Article activeArticle = Application.getArticlesModel().getActiveArticle(); - if (article != null) - openUri(Uri.parse(article.link)); - } + if (activeArticle != null) + openUri(Uri.parse(activeArticle.link)); }); } else { fab.hide(); @@ -188,25 +180,21 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList menu.findItem(R.id.article_set_labels).setEnabled(getApiLevel() >= 1); menu.findItem(R.id.article_edit_note).setEnabled(getApiLevel() >= 1); - final ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + Article activeArticle = Application.getArticlesModel().getActiveArticle(); - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); - - if (selectedArticle != null) { - if (selectedArticle.score > 0) { - menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_up_24); - } else if (selectedArticle.score < 0) { - menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_down_24); - } else { - menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_flat_24); - } + if (activeArticle != null) { + if (activeArticle.score > 0) { + menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_up_24); + } else if (activeArticle.score < 0) { + menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_down_24); + } else { + menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_flat_24); + } - menu.findItem(R.id.toggle_unread).setIcon(selectedArticle.unread ? R.drawable.baseline_email_24 : - R.drawable.baseline_drafts_24); + menu.findItem(R.id.toggle_unread).setIcon(activeArticle.unread ? R.drawable.baseline_email_24 : + R.drawable.baseline_drafts_24); - menu.findItem(R.id.toggle_attachments).setVisible(selectedArticle.attachments != null && !selectedArticle.attachments.isEmpty()); - } + menu.findItem(R.id.toggle_attachments).setVisible(activeArticle.attachments != null && !activeArticle.attachments.isEmpty()); } } } @@ -278,9 +266,11 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList Application.getArticlesModel().updateById(articleClone); } + Application.getArticlesModel().setActive(articleClone); + if (!getSupportActionBar().isShowing()) getSupportActionBar().show(); - ArticlePager ap = (ArticlePager) DetailActivity.this.getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + /* ArticlePager ap = (ArticlePager) DetailActivity.this.getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); if (open) { @@ -291,7 +281,7 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList if (hf != null) { hf.setActiveArticleId(article.id); } - } + } */ invalidateOptionsMenu(); } @@ -317,11 +307,6 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList public void onBackPressed() { Intent resultIntent = new Intent(); - ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - - if (ap != null) - resultIntent.putExtra("activeArticleId", ap.getSelectedArticleId()); - setResult(Activity.RESULT_OK, resultIntent); try { diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java index 8dcda413..b7450afa 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsFragment.java @@ -1,6 +1,5 @@ package org.fox.ttrss; -import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; import android.content.Intent; @@ -43,7 +42,6 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; -import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; import java.util.stream.IntStream; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java index 66fd0443..f1274f64 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/FeedsModel.java @@ -19,7 +19,6 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.reflect.TypeToken; -import org.fox.ttrss.types.ArticleList; import org.fox.ttrss.types.Feed; import java.lang.reflect.Type; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java index b33dd467..7b97a60b 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryActivity.java @@ -1,8 +1,6 @@ package org.fox.ttrss; -import android.graphics.Bitmap; import android.net.Uri; -import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.MenuInflater; @@ -14,7 +12,6 @@ import android.widget.ProgressBar; import androidx.annotation.NonNull; import androidx.appcompat.widget.Toolbar; -import androidx.core.app.ActivityCompat; import androidx.core.view.WindowCompat; import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsControllerCompat; @@ -23,20 +20,11 @@ import androidx.fragment.app.FragmentActivity; import androidx.lifecycle.ViewModelProvider; import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.DiffUtil; -import androidx.recyclerview.widget.PagerSnapHelper; import androidx.viewpager2.widget.ViewPager2; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.DiskCacheStrategy; - import org.fox.ttrss.types.GalleryEntry; import org.fox.ttrss.util.DiffFragmentStateAdapter; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; - -import me.relex.circleindicator.CircleIndicator2; import me.relex.circleindicator.CircleIndicator3; public class GalleryActivity extends CommonActivity { diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java index db141427..cae52798 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryImageFragment.java @@ -10,7 +10,6 @@ import android.widget.ImageView; import android.widget.ProgressBar; import androidx.annotation.Nullable; -import androidx.core.app.ActivityCompat; import androidx.core.view.ViewCompat; import com.bogdwellers.pinchtozoom.ImageMatrixTouchHandler; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java index a171fb5b..4c8ad1ed 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/GalleryVideoFragment.java @@ -15,7 +15,6 @@ import android.view.ViewGroup; import android.widget.ImageView; import android.widget.MediaController; -import androidx.core.app.ActivityCompat; import androidx.core.view.ViewCompat; import java.io.IOException; 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 c46743de..95af0a73 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 @@ -87,7 +87,6 @@ import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.TimeZone; -import java.util.stream.Collectors; public class HeadlinesFragment extends androidx.fragment.app.Fragment { @@ -104,9 +103,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { private Feed m_feed; - /** TODO this should be stored in model, either as an observable or a field - article.active or something */ - @Deprecated - private int m_activeArticleId; private String m_searchQuery = ""; private SharedPreferences m_prefs; @@ -131,7 +127,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { public void initialize(Feed feed, int activeArticleId, boolean compactMode) { m_feed = feed; m_compactLayoutMode = compactMode; - m_activeArticleId = activeArticleId; } public boolean onArticleMenuItemSelected(MenuItem item, Article article, int position) { @@ -267,7 +262,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { if (savedInstanceState != null) { m_feed = savedInstanceState.getParcelable("m_feed"); - m_activeArticleId = savedInstanceState.getInt("m_activeArticleId"); m_searchQuery = savedInstanceState.getString("m_searchQuery"); m_compactLayoutMode = savedInstanceState.getBoolean("m_compactLayoutMode"); } @@ -282,7 +276,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { super.onSaveInstanceState(out); out.putParcelable("m_feed", m_feed); - out.putInt("m_activeArticleId", m_activeArticleId); out.putString("m_searchQuery", m_searchQuery); out.putBoolean("m_compactLayoutMode", m_compactLayoutMode); } @@ -487,6 +480,15 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { m_listener.onHeadlinesLoadingProgress(progress); }); + // this gets notified if active article changes + model.getActive().observe(getActivity(), (activeArticleId) -> { + Log.d(TAG, "observed active article=" + activeArticleId); + + if (activeArticleId > 0) { + scrollToArticleId(activeArticleId); + } + }); + // this gets notified on network update model.getUpdatesData().observe(getActivity(), lastUpdate -> { if (lastUpdate > 0) { @@ -555,14 +557,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { syncToSharedArticles(); - // we only set this in detail activity - if (m_activeArticleId > 0) { - Article activeArticle = Application.getArticles().getById(m_activeArticleId); - - if (activeArticle != null) - scrollToArticle(activeArticle); - } - m_activity.invalidateOptionsMenu(); } @@ -582,7 +576,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { return; if (!append) { - setActiveArticleId(-1); + model.setActive(null); model.setSelection(ArticleModel.ArticlesSelection.NONE); } @@ -792,9 +786,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { // only set active article when it makes sense (in DetailActivity) if (getActivity() instanceof DetailActivity) { - m_activeArticleId = article.id; - - m_adapter.notifyItemChanged(position); + Application.getArticlesModel().setActive(article); } } }); @@ -1035,6 +1027,7 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { switch (payload) { case UNREAD: + case ACTIVE: updateUnreadView(article, holder); break; case MARKED: @@ -1075,22 +1068,23 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { } private void updateActiveView(final Article article, final ArticleViewHolder holder) { - if (article.id == m_activeArticleId) { - holder.view.setBackgroundColor(m_colorTertiaryContainer); + if (m_activity instanceof DetailActivity) { + if (article.active) { + holder.view.setBackgroundColor(m_colorTertiaryContainer); - if (holder.titleView != null) { - holder.titleView.setTextColor(m_colorOnTertiaryContainer); + if (holder.titleView != null) { + holder.titleView.setTextColor(m_colorOnTertiaryContainer); + } } - } - if (holder.excerptView != null) { - holder.excerptView.setTextColor(article.id == m_activeArticleId ? m_colorOnTertiaryContainer : m_colorOnSurface); - } + if (holder.excerptView != null) { + holder.excerptView.setTextColor(article.active ? m_colorOnTertiaryContainer : m_colorOnSurface); + } - if (holder.feedTitleView != null) { - holder.feedTitleView.setTextColor(article.id == m_activeArticleId ? m_colorOnTertiaryContainer : m_colorSecondary); + if (holder.feedTitleView != null) { + holder.feedTitleView.setTextColor(article.active ? m_colorOnTertiaryContainer : m_colorSecondary); + } } - } @Override @@ -1615,30 +1609,6 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { m_list.scrollToPosition(position); } - public void setActiveArticleId(int articleId) { - if (m_list != null && articleId != m_activeArticleId) { - - ArticleList articles = Application.getArticles(); - - int oldPosition = articles.getPositionById(m_activeArticleId); - int newPosition = articles.getPositionById(articleId); - - m_activeArticleId = articleId; - - if (oldPosition != -1) - m_adapter.notifyItemChanged(oldPosition); - - if (newPosition != -1) { - m_adapter.notifyItemChanged(newPosition); - - scrollToArticleId(articleId); - - if (newPosition >= articles.size() - 5) - new Handler().postDelayed(() -> refresh(true), 0); - } - } - } - /** move to model? */ @Deprecated public String getSearchQuery() { diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java index 70e41976..4ce1dc15 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/MasterActivity.java @@ -428,19 +428,16 @@ public class MasterActivity extends OnlineActivity implements HeadlinesEventList if (open) { HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - if (m_prefs.getBoolean("always_open_uri", false)) { - - if (hf != null) { - hf.setActiveArticleId(article.id); - } + Application.getArticlesModel().setActive(article); + if (m_prefs.getBoolean("always_open_uri", false)) { openUri(Uri.parse(article.link)); } else if (hf != null) { Intent intent = new Intent(MasterActivity.this, DetailActivity.class); - intent.putExtra("feed", hf.getFeed()); + intent.putExtra("feed", m_activeFeed); intent.putExtra("searchQuery", hf.getSearchQuery()); - intent.putExtra("openedArticleId", article.id); + //intent.putExtra("openedArticleId", article.id); startActivityForResult(intent, HEADLINES_REQUEST); overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left); 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 934bca66..8ecf59d1 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 @@ -7,7 +7,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.res.ColorStateList; import android.graphics.Point; -import android.net.ConnectivityManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; @@ -197,7 +196,13 @@ public class OnlineActivity extends CommonActivity { setSupportActionBar(toolbar); m_headlinesActionModeCallback = new HeadlinesActionModeCallback(); - } + + ArticleModel model = Application.getArticlesModel(); + + model.getActive().observe(this, (articles) -> { + invalidateOptionsMenu(); + }); + } public void login() { login(false, null); @@ -260,8 +265,6 @@ public class OnlineActivity extends CommonActivity { @Override public boolean onContextItemSelected(android.view.MenuItem item) { - final ArticlePager ap = (ArticlePager)getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - int itemId = item.getItemId(); if (itemId == R.id.article_img_open) { if (getLastContentImageHitTestUrl() != null) { @@ -290,27 +293,23 @@ public class OnlineActivity extends CommonActivity { return true; } else if (itemId == R.id.article_img_view_caption) { if (getLastContentImageHitTestUrl() != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + Article selectedArticle = Application.getArticlesModel().getActiveArticle(); if (selectedArticle != null) displayImageCaption(getLastContentImageHitTestUrl(), selectedArticle.content); } return true; } else if (itemId == R.id.article_link_share) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + Article selectedArticle = Application.getArticlesModel().getActiveArticle(); - if (selectedArticle != null) - shareArticle(selectedArticle); - } + if (selectedArticle != null) + shareArticle(selectedArticle); return true; } else if (itemId == R.id.article_link_copy) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + Article selectedArticle = Application.getArticlesModel().getActiveArticle(); - if (selectedArticle != null) - copyToClipboard(selectedArticle.link); - } + if (selectedArticle != null) + copyToClipboard(selectedArticle.link); return true; } Log.d(TAG, "onContextItemSelected, unhandled id=" + item.getItemId()); @@ -354,7 +353,10 @@ public class OnlineActivity extends CommonActivity { @Override public boolean onOptionsItemSelected(MenuItem item) { final HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - final ArticlePager ap = (ArticlePager)getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + + Article activeArticle = Application.getArticlesModel().getActiveArticle(); + + Log.d(TAG, "onOptionsItemSelected, active article=" + activeArticle); int itemId = item.getItemId(); if (itemId == R.id.subscribe_to_feed) { @@ -362,23 +364,15 @@ public class OnlineActivity extends CommonActivity { startActivityForResult(subscribe, 0); return true; } else if (itemId == R.id.toggle_attachments) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); - - if (selectedArticle != null) - displayAttachments(selectedArticle); - } + if (activeArticle != null) + displayAttachments(activeArticle); return true; } else if (itemId == R.id.login) { login(); return true; } else if (itemId == R.id.article_edit_note) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); - - if (selectedArticle != null) - editArticleNote(selectedArticle); - } + if (activeArticle != null) + editArticleNote(activeArticle); return true; } else if (itemId == R.id.preferences) { Intent intent = new Intent(OnlineActivity.this, @@ -413,7 +407,6 @@ public class OnlineActivity extends CommonActivity { return true; } else if (itemId == R.id.headlines_mark_as_read) { if (hf != null) { - Feed feed = hf.getFeed(); if (feed != null) { @@ -549,50 +542,35 @@ public class OnlineActivity extends CommonActivity { dialog.show(); return true; } else if (itemId == R.id.share_article) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + if (activeArticle != null) + shareArticle(activeArticle); - if (selectedArticle != null) - shareArticle(selectedArticle); - } return true; } else if (itemId == R.id.article_set_score) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); - - if (selectedArticle != null) { - setArticleScore(selectedArticle); - } - } + if (activeArticle != null) { + setArticleScore(activeArticle); + } return true; } else if (itemId == R.id.toggle_marked) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + if (activeArticle != null) { + Article articleClone = new Article(activeArticle); - if (selectedArticle != null) { - Article articleClone = new Article(selectedArticle); - - articleClone.marked = !articleClone.marked; + articleClone.marked = !articleClone.marked; - saveArticleMarked(selectedArticle); + saveArticleMarked(activeArticle); - Application.getArticlesModel().updateById(articleClone); - } + Application.getArticlesModel().updateById(articleClone); } return true; } else if (itemId == R.id.toggle_unread) { - if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + if (activeArticle != null) { + Article articleClone = new Article(activeArticle); - if (selectedArticle != null) { - Article articleClone = new Article(selectedArticle); - - articleClone.unread = !articleClone.unread; + articleClone.unread = !articleClone.unread; - saveArticleUnread(selectedArticle); + saveArticleUnread(activeArticle); - Application.getArticlesModel().updateById(articleClone); - } + Application.getArticlesModel().updateById(articleClone); } return true; } else if (itemId == R.id.selection_toggle_unread) { @@ -644,80 +622,67 @@ public class OnlineActivity extends CommonActivity { } return true; } else if (itemId == R.id.toggle_published) { - if (ap != null && hf != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + if (activeArticle != null) { + Article articleClone = new Article(activeArticle); - if (selectedArticle != null) { - Article articleClone = new Article(selectedArticle); + articleClone.published = !articleClone.published; + saveArticlePublished(articleClone); - articleClone.published = !articleClone.published; - saveArticlePublished(articleClone); - - Application.getArticlesModel().updateById(articleClone); - } + Application.getArticlesModel().updateById(articleClone); } return true; } else if (itemId == R.id.catchup_above) { - if (hf != null) { - - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this) - .setMessage(R.string.confirm_catchup_above) - .setPositiveButton(R.string.dialog_ok, - (dialog, which) -> catchupAbove(hf, ap)) - .setNegativeButton(R.string.dialog_cancel, - (dialog, which) -> { + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this) + .setMessage(R.string.confirm_catchup_above) + .setPositiveButton(R.string.dialog_ok, + (dialog, which) -> catchupAbove()) + .setNegativeButton(R.string.dialog_cancel, + (dialog, which) -> { - }); + }); - Dialog dialog = builder.create(); - dialog.show(); + Dialog dialog = builder.create(); + dialog.show(); - } return true; } else if (itemId == R.id.article_set_labels) { - if (ap != null) { - if (getApiLevel() != 7) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); - - if (selectedArticle != null) - editArticleLabels(selectedArticle); - } else { - toast(R.string.server_function_not_available); - } - + if (getApiLevel() != 7) { + if (activeArticle != null) + editArticleLabels(activeArticle); + } else { + toast(R.string.server_function_not_available); } + return true; } Log.d(TAG, "onOptionsItemSelected, unhandled id=" + item.getItemId()); return super.onOptionsItemSelected(item); } - private void catchupAbove(HeadlinesFragment hf, ArticlePager ap) { - if (ap != null) { - int selectedArticleId = ap.getSelectedArticleId(); + private void catchupAbove() { + Article activeArticle = Application.getArticlesModel().getActiveArticle(); - if (Application.getArticles().containsId(selectedArticleId)) { - ArticleList tmp = new ArticleList(); + if (activeArticle != null) { + ArticleList tmp = new ArticleList(); - for (Article a : Application.getArticles()) { - if (a.id == selectedArticleId) - break; + for (Article a : Application.getArticles()) { + if (a.id == activeArticle.id) + break; - Article articleClone = new Article(a); + Article articleClone = new Article(a); - if (articleClone.unread) { - articleClone.unread = false; + if (articleClone.unread) { + articleClone.unread = false; - tmp.add(articleClone); + tmp.add(articleClone); - Application.getArticlesModel().updateById(articleClone); - } + Application.getArticlesModel().updateById(articleClone); } + } - if (!tmp.isEmpty()) { - setArticlesUnread(tmp, Article.UPDATE_SET_FALSE); - invalidateOptionsMenu(); - } + if (!tmp.isEmpty()) { + setArticlesUnread(tmp, Article.UPDATE_SET_FALSE); + invalidateOptionsMenu(); } } } @@ -1022,7 +987,7 @@ public class OnlineActivity extends CommonActivity { return true; case KeyEvent.KEYCODE_O: if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + Article selectedArticle = Application.getArticlesModel().getActiveArticle(); if (selectedArticle != null) openUri(Uri.parse(selectedArticle.link)); @@ -1033,7 +998,7 @@ public class OnlineActivity extends CommonActivity { return true; case KeyEvent.KEYCODE_U: if (ap != null) { - Article selectedArticle = Application.getArticles().getById(ap.getSelectedArticleId()); + Article selectedArticle = Application.getArticlesModel().getActiveArticle(); if (selectedArticle != null) { selectedArticle.unread = !selectedArticle.unread; @@ -1182,38 +1147,35 @@ public class OnlineActivity extends CommonActivity { MenuItem search = m_menu.findItem(R.id.search); search.setEnabled(getApiLevel() >= 2); - ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + Article activeArticle = Application.getArticlesModel().getActiveArticle(); - if (ap != null) { - Article article = Application.getArticles().getById(ap.getSelectedArticleId()); + Log.d(TAG, "active article=" + activeArticle); - if (article != null) { + if (activeArticle != null) { - m_menu.findItem(R.id.toggle_marked).setIcon(article.marked ? R.drawable.baseline_star_24 : - R.drawable.baseline_star_outline_24); + m_menu.findItem(R.id.toggle_marked).setIcon(activeArticle.marked ? R.drawable.baseline_star_24 : + R.drawable.baseline_star_outline_24); - // TODO we probably shouldn't do this all the time - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && m_prefs.getBoolean("enable_icon_tinting", true)) { - TypedValue tvTertiary = new TypedValue(); - getTheme().resolveAttribute(R.attr.colorTertiary, tvTertiary, true); + // TODO we probably shouldn't do this all the time + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && m_prefs.getBoolean("enable_icon_tinting", true)) { + TypedValue tvTertiary = new TypedValue(); + getTheme().resolveAttribute(R.attr.colorTertiary, tvTertiary, true); - ColorStateList colorStateTertiary = ColorStateList.valueOf(ContextCompat.getColor(this, tvTertiary.resourceId)); + ColorStateList colorStateTertiary = ColorStateList.valueOf(ContextCompat.getColor(this, tvTertiary.resourceId)); - TypedValue tvNormal = new TypedValue(); - getTheme().resolveAttribute(R.attr.colorControlNormal, tvNormal, true); + TypedValue tvNormal = new TypedValue(); + getTheme().resolveAttribute(R.attr.colorControlNormal, tvNormal, true); - ColorStateList colorStateNormal = ColorStateList.valueOf(ContextCompat.getColor(this, tvNormal.resourceId)); + ColorStateList colorStateNormal = ColorStateList.valueOf(ContextCompat.getColor(this, tvNormal.resourceId)); - m_menu.findItem(R.id.toggle_published).setIconTintList(article.published ? colorStateTertiary : colorStateNormal); - m_menu.findItem(R.id.toggle_marked).setIconTintList(article.marked ? colorStateTertiary : colorStateNormal); - - } else { - m_menu.findItem(R.id.toggle_published).setIcon(article.published ? R.drawable.rss_box : - R.drawable.baseline_rss_feed_24); - } + m_menu.findItem(R.id.toggle_published).setIconTintList(activeArticle.published ? colorStateTertiary : colorStateNormal); + m_menu.findItem(R.id.toggle_marked).setIconTintList(activeArticle.marked ? colorStateTertiary : colorStateNormal); - } - } + } else { + m_menu.findItem(R.id.toggle_published).setIcon(activeArticle.published ? R.drawable.rss_box : + R.drawable.baseline_rss_feed_24); + } + } } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesFragment.java index c96948e6..2eaeae0d 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/PreferencesFragment.java @@ -4,7 +4,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.os.Build; import android.os.Bundle; import androidx.annotation.Nullable; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java index 7e548879..f8e2d254 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/RootCategoriesFragment.java @@ -1,25 +1,6 @@ package org.fox.ttrss; -import android.annotation.SuppressLint; -import android.os.Bundle; - -import androidx.annotation.NonNull; import androidx.lifecycle.ViewModelProvider; -import androidx.loader.content.Loader; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.reflect.TypeToken; - -import org.fox.ttrss.types.Feed; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.stream.Collectors; public class RootCategoriesFragment extends FeedsFragment { private final String TAG = this.getClass().getSimpleName(); diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/BitmapSizeDecoder.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/BitmapSizeDecoder.java index 1a709073..00bd872c 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/BitmapSizeDecoder.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/BitmapSizeDecoder.java @@ -1,17 +1,16 @@ package org.fox.ttrss.glide; -import java.io.File; -import java.io.IOException; +import android.graphics.BitmapFactory; + +import androidx.annotation.NonNull; import com.bumptech.glide.load.Options; import com.bumptech.glide.load.ResourceDecoder; import com.bumptech.glide.load.engine.Resource; import com.bumptech.glide.load.resource.SimpleResource; -import android.graphics.BitmapFactory; -import android.util.Log; - -import androidx.annotation.NonNull; +import java.io.File; +import java.io.IOException; class BitmapSizeDecoder implements ResourceDecoder<File, BitmapFactory.Options> { @Override diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OkHttpProgressGlideModule.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OkHttpProgressGlideModule.java index 44f69b79..d196ab89 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OkHttpProgressGlideModule.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OkHttpProgressGlideModule.java @@ -4,11 +4,9 @@ import android.content.Context; import android.graphics.BitmapFactory; import android.os.Handler; import android.os.Looper; -import android.util.Log; import android.util.Size; import com.bumptech.glide.Glide; -import com.bumptech.glide.GlideBuilder; import com.bumptech.glide.Registry; import com.bumptech.glide.annotation.GlideModule; import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OptionsSizeResourceTranscoder.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OptionsSizeResourceTranscoder.java index 2fc56fe7..d1d8c47e 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OptionsSizeResourceTranscoder.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/OptionsSizeResourceTranscoder.java @@ -1,13 +1,12 @@ package org.fox.ttrss.glide; import android.graphics.BitmapFactory; -import android.util.Log; import android.util.Size; import com.bumptech.glide.load.Options; -import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; import com.bumptech.glide.load.engine.Resource; import com.bumptech.glide.load.resource.SimpleResource; +import com.bumptech.glide.load.resource.transcode.ResourceTranscoder; class OptionsSizeResourceTranscoder implements ResourceTranscoder<BitmapFactory.Options, Size> { @Override diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/ProgressTarget.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/ProgressTarget.java index 172dd28a..1e7c868a 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/ProgressTarget.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/glide/ProgressTarget.java @@ -2,13 +2,10 @@ package org.fox.ttrss.glide; import android.graphics.drawable.Drawable; -import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.bumptech.glide.Glide; -import com.bumptech.glide.load.engine.Resource; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; 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 92d003e1..585e3c7f 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 @@ -58,6 +58,7 @@ public class Article implements Parcelable { public String author; public String note; public boolean selected; + public boolean active; public String flavor_image; public String flavor_stream; public int flavor_kind; diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java index 576048b3..4832a2b4 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/ArticleDiffItemCallback.java @@ -8,7 +8,7 @@ import org.fox.ttrss.types.Article; public class ArticleDiffItemCallback extends DiffUtil.ItemCallback<Article> { private final String TAG = this.getClass().getSimpleName(); - public enum ChangePayload { UNREAD, MARKED, SELECTED, PUBLISHED, NOTE, SCORE }; + public enum ChangePayload { UNREAD, MARKED, SELECTED, PUBLISHED, NOTE, ACTIVE, SCORE }; @Override public boolean areItemsTheSame(@NonNull Article oldItem, @NonNull Article newItem) { @@ -30,6 +30,8 @@ public class ArticleDiffItemCallback extends DiffUtil.ItemCallback<Article> { return ChangePayload.NOTE; else if (oldItem.score != newItem.score) return ChangePayload.SCORE; + else if (oldItem.active != newItem.active) + return ChangePayload.ACTIVE; return null; } @@ -38,6 +40,6 @@ public class ArticleDiffItemCallback extends DiffUtil.ItemCallback<Article> { public boolean areContentsTheSame(@NonNull Article oldItem, @NonNull Article newItem) { return oldItem.id == newItem.id && oldItem.unread == newItem.unread && oldItem.marked == newItem.marked && oldItem.selected == newItem.selected && oldItem.published == newItem.published - && oldItem.score == newItem.score && oldItem.note.equals(newItem.note); + && oldItem.score == newItem.score && oldItem.note.equals(newItem.note) && oldItem.active == newItem.active; } } |