diff options
Diffstat (limited to 'org.fox.ttrss')
16 files changed, 247 insertions, 179 deletions
diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java index dd27631b..f7fb8433 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/ArticleFragment.java @@ -39,6 +39,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; +// TODO: add ability to update already rendered contents from article somehow (to refresh note, etc) public class ArticleFragment extends androidx.fragment.app.Fragment { private final String TAG = this.getClass().getSimpleName(); @@ -336,8 +337,6 @@ public class ArticleFragment extends androidx.fragment.app.Fragment { } }); - m_web.setVisibility(View.VISIBLE); - renderContent(savedInstanceState); return view; 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 c94f0c3a..9b1455f3 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 @@ -14,9 +14,13 @@ import android.view.View; import android.view.ViewGroup; import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; +import androidx.recyclerview.widget.RecyclerView; import androidx.viewpager.widget.ViewPager; +import androidx.viewpager2.adapter.FragmentStateAdapter; +import androidx.viewpager2.widget.ViewPager2; import com.google.android.material.snackbar.Snackbar; import com.google.gson.JsonElement; @@ -31,7 +35,7 @@ import java.util.HashMap; public class ArticlePager extends androidx.fragment.app.Fragment { private final String TAG = "ArticlePager"; - private PagerAdapter m_adapter; + private RecyclerView.Adapter m_adapter; private HeadlinesEventListener m_listener; protected Article m_article; protected ArticleList m_articles = new ArticleList(); //m_articles = Application.getInstance().m_loadedArticles; @@ -42,29 +46,18 @@ public class ArticlePager extends androidx.fragment.app.Fragment { protected int m_firstId = 0; private boolean m_refreshInProgress; private boolean m_lazyLoadDisabled; + private ViewPager2 m_pager; - private class PagerAdapter extends FragmentStatePagerAdapter { + private class PagerAdapter extends FragmentStateAdapter { - public PagerAdapter(FragmentManager fm) { - super(fm); + public PagerAdapter(FragmentActivity fa) { + super(fa); } private ArticleFragment m_currentFragment; - // workaround for possible TransactionTooLarge exception on 8.0+ - // we don't need to save member state anyway, bridge takes care of it @Override - public Parcelable saveState() { - Bundle bundle = (Bundle) super.saveState(); - - if (bundle != null) - bundle.putParcelableArray("states", null); // Never maintain any states from the base class, just null it out - - return bundle; - } - - @Override - public Fragment getItem(int position) { + public Fragment createFragment(int position) { try { Article article = m_articles.get(position); @@ -82,7 +75,7 @@ public class ArticlePager extends androidx.fragment.app.Fragment { } @Override - public int getCount() { + public int getItemCount() { return m_articles.size(); } @@ -90,13 +83,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment { return m_currentFragment; } - @Override - public void setPrimaryItem(ViewGroup container, int position, Object object) { - m_currentFragment = ((ArticleFragment) object); - - super.setPrimaryItem(container, position, object); - } - } public void initialize(Article article, Feed feed, ArticleList articles) { @@ -125,7 +111,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment { if (savedInstanceState != null) { m_article = savedInstanceState.getParcelable("m_article"); - //m_articles = savedInstanceState.getParcelable("m_articles"); m_feed = savedInstanceState.getParcelable("m_feed"); m_firstId = savedInstanceState.getInt("m_firstId"); } @@ -136,30 +121,26 @@ public class ArticlePager extends androidx.fragment.app.Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_article_pager, container, false); - + if (savedInstanceState != null) { if (m_activity instanceof DetailActivity) { m_articles = ((DetailActivity)m_activity).m_articles; } } - m_adapter = new PagerAdapter(getActivity().getSupportFragmentManager()); + m_adapter = new PagerAdapter(getActivity()); - ViewPager pager = view.findViewById(R.id.article_pager); - + m_pager = view.findViewById(R.id.article_pager); + int position = m_articles.indexOf(m_article); m_listener.onArticleSelected(m_article, false); - pager.setAdapter(m_adapter); - - pager.setCurrentItem(position); - pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { - @Override - public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { - - } + m_pager.setAdapter(m_adapter); + m_pager.setOffscreenPageLimit(3); + m_pager.setCurrentItem(position); + m_pager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { @Override public void onPageSelected(int position) { Log.d(TAG, "onPageSelected: " + position); @@ -178,7 +159,7 @@ public class ArticlePager extends androidx.fragment.app.Fragment { //Log.d(TAG, "Page #" + position + "/" + m_adapter.getCount()); - if (!m_refreshInProgress && !m_lazyLoadDisabled && (m_activity.isSmallScreen() || m_activity.isPortrait()) && position >= m_adapter.getCount() - 5) { + if (!m_refreshInProgress && !m_lazyLoadDisabled && (m_activity.isSmallScreen() || m_activity.isPortrait()) && position >= m_adapter.getItemCount() - 5) { Log.d(TAG, "loading more articles..."); new Handler().postDelayed(new Runnable() { @@ -190,11 +171,6 @@ public class ArticlePager extends androidx.fragment.app.Fragment { } } } - - @Override - public void onPageScrollStateChanged(int state) { - - } }); return view; 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 0edd6c10..8c573910 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 @@ -10,12 +10,14 @@ import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.util.Log; +import android.view.Menu; import android.view.MenuItem; import android.view.View; import androidx.appcompat.widget.Toolbar; import androidx.fragment.app.FragmentTransaction; +import com.google.android.material.bottomappbar.BottomAppBar; import com.google.android.material.floatingactionbutton.FloatingActionButton; import org.fox.ttrss.types.Article; @@ -25,6 +27,7 @@ import org.fox.ttrss.types.Feed; public class DetailActivity extends OnlineActivity implements HeadlinesEventListener { private final String TAG = this.getClass().getSimpleName(); protected ArticleList m_articles = new ArticleList(); + protected BottomAppBar m_bottomAppBar; protected SharedPreferences m_prefs; private Article m_activeArticle; @@ -68,6 +71,52 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList headlines.setVisibility(View.GONE); } + m_bottomAppBar = findViewById(R.id.detail_bottom_appbar); + + if (m_bottomAppBar != null) { + m_bottomAppBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + + final ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + final HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); + + Article article = ap.getSelectedArticle(); + + if (article == null) return false; + + int itemId = item.getItemId(); + + if (itemId == R.id.article_set_labels) { + editArticleLabels(article); + + return true; + } else if (itemId == R.id.toggle_attachments) { + displayAttachments(article); + + return true; + } else if (itemId == R.id.article_edit_note) { + editArticleNote(article); + + return true; + } else if (itemId == R.id.article_set_score) { + setArticleScore(article); + + return true; + } else if (itemId == R.id.toggle_unread) { + article.unread = !article.unread; + saveArticleUnread(article); + + if (hf != null) { + hf.notifyUpdated(); + } + } + + return false; + } + }); + } + FloatingActionButton fab = findViewById(R.id.detail_fab); if (fab != null && m_prefs.getBoolean("enable_article_fab", true)) { @@ -136,11 +185,50 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList if (feed != null) setTitle(feed.title); + + initBottomBarMenu(); + } + } + } + + @Override + public void invalidateOptionsMenu() { + super.invalidateOptionsMenu(); + + initBottomBarMenu(); + } + + protected void initBottomBarMenu() { + if (m_bottomAppBar != null) { + Menu menu = m_bottomAppBar.getMenu(); + + 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); + + if (ap != null) { + Article article = ap.getSelectedArticle(); + + if (article != null) { + if (article.score > 0) { + menu.findItem(R.id.article_set_score).setIcon(R.drawable.baseline_trending_up_24); + } else if (article.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(article.unread ? R.drawable.baseline_mark_as_unread_24 : + R.drawable.baseline_email_24); + + menu.findItem(R.id.toggle_attachments).setVisible(article.attachments != null && article.attachments.size() > 0); + } } } } - @Override + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -197,30 +285,13 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList if (m_menu != null && getSessionId() != null) { m_menu.setGroupVisible(R.id.menu_group_feeds, false); - //HeadlinesFragment hf = (HeadlinesFragment)getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - m_menu.setGroupVisible(R.id.menu_group_headlines, !isPortrait() && !isSmallScreen()); - //m_menu.findItem(R.id.headlines_toggle_sidebar).setVisible(!isPortrait() && !isSmallScreen()); m_menu.findItem(R.id.headlines_toggle_sort_order).setVisible(false); ArticlePager af = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); m_menu.setGroupVisible(R.id.menu_group_article, af != null); - - if (af != null) { - if (af.getSelectedArticle() != null && af.getSelectedArticle().attachments != null && af.getSelectedArticle().attachments.size() > 0) { - /* if (!isCompatMode() && (isSmallScreen() || !isPortrait())) { - m_menu.findItem(R.id.toggle_attachments).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - } */ - m_menu.findItem(R.id.toggle_attachments).setVisible(true); - } else { - /* if (!isCompatMode()) { - m_menu.findItem(R.id.toggle_attachments).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER); - } */ - m_menu.findItem(R.id.toggle_attachments).setVisible(false); - } - } - + m_menu.findItem(R.id.search).setVisible(false); } } @@ -278,7 +349,7 @@ public class DetailActivity extends OnlineActivity implements HeadlinesEventList //Application.getInstance().m_activeArticle = article; invalidateOptionsMenu(); - + initBottomBarMenu(); } public void showSidebar(boolean show) { 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 b6953bc6..52ef4327 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 @@ -157,10 +157,10 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { if (article == null) return false; int itemId = item.getItemId(); - if (itemId == R.id.set_labels) { + if (itemId == R.id.article_set_labels) { m_activity.editArticleLabels(article); return true; - } else if (itemId == R.id.article_set_note) { + } else if (itemId == R.id.article_edit_note) { m_activity.editArticleNote(article); return true; } else if (itemId == R.id.headlines_article_unread) { @@ -268,8 +268,8 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu); - menu.findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1); - menu.findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1); + menu.findItem(R.id.article_set_labels).setEnabled(m_activity.getApiLevel() >= 1); + menu.findItem(R.id.article_edit_note).setEnabled(m_activity.getApiLevel() >= 1); super.onCreateContextMenu(menu, v, menuInfo); } @@ -1531,8 +1531,8 @@ public class HeadlinesFragment extends androidx.fragment.app.Fragment { MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.context_headlines, popup.getMenu()); - popup.getMenu().findItem(R.id.set_labels).setEnabled(m_activity.getApiLevel() >= 1); - popup.getMenu().findItem(R.id.article_set_note).setEnabled(m_activity.getApiLevel() >= 1); + popup.getMenu().findItem(R.id.article_set_labels).setEnabled(m_activity.getApiLevel() >= 1); + popup.getMenu().findItem(R.id.article_edit_note).setEnabled(m_activity.getApiLevel() >= 1); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override 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 f06c9a7c..ae4622ef 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 @@ -550,7 +550,7 @@ public class OnlineActivity extends CommonActivity { /*case R.id.go_offline: switchOffline(); return true;*/ - } else if (itemId == R.id.article_set_note) { + } else if (itemId == R.id.article_edit_note) { if (ap != null && ap.getSelectedArticle() != null) { editArticleNote(ap.getSelectedArticle()); } @@ -859,7 +859,7 @@ public class OnlineActivity extends CommonActivity { } return true; - } else if (itemId == R.id.set_labels) { + } else if (itemId == R.id.article_set_labels) { if (ap != null && ap.getSelectedArticle() != null) { if (getApiLevel() != 7) { editArticleLabels(ap.getSelectedArticle()); @@ -937,27 +937,24 @@ public class OnlineActivity extends CommonActivity { } */ public void editArticleNote(final Article article) { - String note = ""; - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this) .setTitle(article.title); final EditText topicEdit = new EditText(this); - topicEdit.setText(note); + topicEdit.setText(article.note); builder.setView(topicEdit); - builder.setPositiveButton(R.string.article_set_note, new Dialog.OnClickListener() { + builder.setPositiveButton(R.string.article_edit_note, new Dialog.OnClickListener() { public void onClick(DialogInterface dialog, int which) { String note = topicEdit.getText().toString().trim(); saveArticleNote(article, note); - article.published = true; - article.note = note; - - saveArticlePublished(article); - + HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); if (hf != null) hf.notifyUpdated(); + + ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + if (ap != null) ap.notifyUpdated(); } }); @@ -1130,7 +1127,7 @@ public class OnlineActivity extends CommonActivity { ApiRequest req = new ApiRequest(getApplicationContext()) { protected void onPostExecute(JsonElement result) { //toast(R.string.article_set_unread); - initMenu(); + invalidateOptionsMenu(); } }; @@ -1204,7 +1201,7 @@ public class OnlineActivity extends CommonActivity { public void saveArticleNote(final Article article, final String note) { ApiRequest req = new ApiRequest(getApplicationContext()) { protected void onPostExecute(JsonElement result) { - // + article.note = note; } }; @@ -1413,64 +1410,54 @@ public class OnlineActivity extends CommonActivity { } // this may be called after activity has been destroyed (i.e. long asynctask) - // might as well prevent null pointers if menu items are missing protected void initMenu() { - try { - if (m_menu != null) { - if (getSessionId() != null) { - m_menu.setGroupVisible(R.id.menu_group_logged_in, true); - m_menu.setGroupVisible(R.id.menu_group_logged_out, false); - } else { - m_menu.setGroupVisible(R.id.menu_group_logged_in, false); - m_menu.setGroupVisible(R.id.menu_group_logged_out, true); - } - - m_menu.setGroupVisible(R.id.menu_group_headlines, false); - m_menu.setGroupVisible(R.id.menu_group_article, false); - m_menu.setGroupVisible(R.id.menu_group_feeds, false); + if (m_menu != null) { + if (getSessionId() != null) { + m_menu.setGroupVisible(R.id.menu_group_logged_in, true); + m_menu.setGroupVisible(R.id.menu_group_logged_out, false); + } else { + m_menu.setGroupVisible(R.id.menu_group_logged_in, false); + m_menu.setGroupVisible(R.id.menu_group_logged_out, true); + } - m_menu.findItem(R.id.set_labels).setEnabled(getApiLevel() >= 1); - m_menu.findItem(R.id.article_set_note).setEnabled(getApiLevel() >= 1); - m_menu.findItem(R.id.subscribe_to_feed).setEnabled(getApiLevel() >= 5); + m_menu.setGroupVisible(R.id.menu_group_headlines, false); + m_menu.setGroupVisible(R.id.menu_group_article, false); + m_menu.setGroupVisible(R.id.menu_group_feeds, false); - MenuItem search = m_menu.findItem(R.id.search); - search.setEnabled(getApiLevel() >= 2); + m_menu.findItem(R.id.subscribe_to_feed).setEnabled(getApiLevel() >= 5); - ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); + MenuItem search = m_menu.findItem(R.id.search); + search.setEnabled(getApiLevel() >= 2); - if (ap != null) { - Article article = ap.getSelectedArticle(); + ArticlePager ap = (ArticlePager) getSupportFragmentManager().findFragmentByTag(FRAG_ARTICLE); - if (article != null) { - m_menu.findItem(R.id.toggle_marked).setIcon(article.marked ? R.drawable.baseline_star_24 : - R.drawable.baseline_star_outline_24); + if (ap != null) { + Article article = ap.getSelectedArticle(); - m_menu.findItem(R.id.toggle_published).setIcon(article.published ? R.drawable.baseline_check_box_24 : - R.drawable.baseline_rss_feed_24); + if (article != 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_unread).setIcon(article.unread ? R.drawable.baseline_mark_as_unread_24 : - R.drawable.baseline_email_24); - } + m_menu.findItem(R.id.toggle_published).setIcon(article.published ? R.drawable.baseline_check_box_24 : + R.drawable.baseline_rss_feed_24); } + } - HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - - if (hf != null && !m_forceDisableActionMode) { - if (hf.getSelectedArticles().size() > 0) { - if (m_headlinesActionMode == null) { - m_headlinesActionMode = startSupportActionMode(m_headlinesActionModeCallback); - } + HeadlinesFragment hf = (HeadlinesFragment) getSupportFragmentManager().findFragmentByTag(FRAG_HEADLINES); - m_headlinesActionMode.setTitle(String.valueOf(hf.getSelectedArticles().size())); - } else if (hf.getSelectedArticles().size() == 0 && m_headlinesActionMode != null) { - m_headlinesActionMode.finish(); + if (hf != null && !m_forceDisableActionMode) { + if (hf.getSelectedArticles().size() > 0) { + if (m_headlinesActionMode == null) { + m_headlinesActionMode = startSupportActionMode(m_headlinesActionModeCallback); } - } else if (m_forceDisableActionMode && m_headlinesActionMode != null) { + + m_headlinesActionMode.setTitle(String.valueOf(hf.getSelectedArticles().size())); + } else if (hf.getSelectedArticles().size() == 0 && m_headlinesActionMode != null) { m_headlinesActionMode.finish(); } + } else if (m_forceDisableActionMode && m_headlinesActionMode != null) { + m_headlinesActionMode.finish(); } - } catch (NullPointerException e) { - e.printStackTrace(); } } diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java index 7994b576..0f1509fa 100755 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/offline/OfflineHeadlinesFragment.java @@ -135,8 +135,8 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis getActivity().getMenuInflater().inflate(R.menu.context_headlines, menu); - menu.findItem(R.id.set_labels).setVisible(false); - menu.findItem(R.id.article_set_note).setVisible(false); + menu.findItem(R.id.article_set_labels).setVisible(false); + menu.findItem(R.id.article_edit_note).setVisible(false); if (m_prefs.getBoolean("offline_sort_by_feed", false)) { menu.findItem(R.id.catchup_above).setVisible(false); @@ -1037,8 +1037,8 @@ public class OfflineHeadlinesFragment extends Fragment implements OnItemClickLis MenuInflater inflater = popup.getMenuInflater(); inflater.inflate(R.menu.context_headlines, popup.getMenu()); - popup.getMenu().findItem(R.id.set_labels).setVisible(false); - popup.getMenu().findItem(R.id.article_set_note).setVisible(false); + popup.getMenu().findItem(R.id.article_set_labels).setVisible(false); + popup.getMenu().findItem(R.id.article_edit_note).setVisible(false); popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { @Override diff --git a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/DetailActivityScrollingViewBehavior.java b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/DetailActivityScrollingViewBehavior.java index 85e8ae4b..b977b9a8 100644 --- a/org.fox.ttrss/src/main/java/org/fox/ttrss/util/DetailActivityScrollingViewBehavior.java +++ b/org.fox.ttrss/src/main/java/org/fox/ttrss/util/DetailActivityScrollingViewBehavior.java @@ -7,6 +7,7 @@ import android.util.AttributeSet; import android.view.View; import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.bottomappbar.BottomAppBar; import com.google.android.material.floatingactionbutton.FloatingActionButton; import java.util.List; @@ -29,7 +30,7 @@ public class DetailActivityScrollingViewBehavior extends AppBarLayout.ScrollingV @Override public boolean layoutDependsOn(CoordinatorLayout parent, View child, View dependency) { return super.layoutDependsOn(parent, child, dependency) || - dependency instanceof FloatingActionButton; + dependency instanceof FloatingActionButton || dependency instanceof BottomAppBar; } @Override @@ -54,6 +55,8 @@ public class DetailActivityScrollingViewBehavior extends AppBarLayout.ScrollingV for (View view : dependencies) { if (view instanceof FloatingActionButton) { ((FloatingActionButton) view).hide(); + } else if (view instanceof BottomAppBar) { + ((BottomAppBar) view).performHide(); } } } else if (dy < 0) { @@ -62,6 +65,8 @@ public class DetailActivityScrollingViewBehavior extends AppBarLayout.ScrollingV for (View view : dependencies) { if (view instanceof FloatingActionButton) { ((FloatingActionButton) view).show(); + } else if (view instanceof BottomAppBar) { + ((BottomAppBar) view).performShow(); } } } diff --git a/org.fox.ttrss/src/main/res/drawable/baseline_new_label_24.xml b/org.fox.ttrss/src/main/res/drawable/baseline_new_label_24.xml new file mode 100644 index 00000000..3eb7690c --- /dev/null +++ b/org.fox.ttrss/src/main/res/drawable/baseline_new_label_24.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp"> + + <path android:fillColor="@android:color/white" android:pathData="M21,12l-4.37,6.16C16.26,18.68 15.65,19 15,19h-3l0,-6H9v-3H3V7c0,-1.1 0.9,-2 2,-2h10c0.65,0 1.26,0.31 1.63,0.84L21,12zM10,15H7v-3H5v3H2v2h3v3h2v-3h3V15z"/> + +</vector> diff --git a/org.fox.ttrss/src/main/res/drawable/baseline_note_add_24.xml b/org.fox.ttrss/src/main/res/drawable/baseline_note_add_24.xml new file mode 100644 index 00000000..e1ffd854 --- /dev/null +++ b/org.fox.ttrss/src/main/res/drawable/baseline_note_add_24.xml @@ -0,0 +1,5 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp"> + + <path android:fillColor="@android:color/white" android:pathData="M14,2L6,2c-1.1,0 -1.99,0.9 -1.99,2L4,20c0,1.1 0.89,2 1.99,2L18,22c1.1,0 2,-0.9 2,-2L20,8l-6,-6zM16,16h-3v3h-2v-3L8,16v-2h3v-3h2v3h3v2zM13,9L13,3.5L18.5,9L13,9z"/> + +</vector> diff --git a/org.fox.ttrss/src/main/res/layout/fragment_article.xml b/org.fox.ttrss/src/main/res/layout/fragment_article.xml index e75980b0..5696e889 100755 --- a/org.fox.ttrss/src/main/res/layout/fragment_article.xml +++ b/org.fox.ttrss/src/main/res/layout/fragment_article.xml @@ -14,12 +14,12 @@ <com.otaliastudios.nestedscrollcoordinatorlayout.NestedScrollCoordinatorLayout android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:background="?colorSurfaceContainer" - android:layout_height="match_parent"> + android:layout_height="wrap_content"> <com.google.android.material.card.MaterialCardView app:layout_scrollFlags="scroll|enterAlways" @@ -150,7 +150,7 @@ android:id="@+id/article_content" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" - android:layout_height="wrap_content" /> + android:layout_height="match_parent" /> </com.otaliastudios.nestedscrollcoordinatorlayout.NestedScrollCoordinatorLayout> diff --git a/org.fox.ttrss/src/main/res/layout/fragment_article_pager.xml b/org.fox.ttrss/src/main/res/layout/fragment_article_pager.xml index 1a687b1d..2f962418 100755 --- a/org.fox.ttrss/src/main/res/layout/fragment_article_pager.xml +++ b/org.fox.ttrss/src/main/res/layout/fragment_article_pager.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<androidx.viewpager.widget.ViewPager +<androidx.viewpager2.widget.ViewPager2 xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/article_pager" android:layout_width="match_parent" diff --git a/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml b/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml index 429b27c0..420b6f3a 100644 --- a/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml +++ b/org.fox.ttrss/src/main/res/layout/layout_detail_phone.xml @@ -2,16 +2,7 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="wrap_content"> - - <com.google.android.material.floatingactionbutton.FloatingActionButton - android:id="@+id/detail_fab" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="end|bottom" - android:visibility="gone" - android:src="@drawable/baseline_open_in_browser_24" - android:layout_margin="16dp" /> + android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" @@ -25,7 +16,7 @@ android:id="@+id/article_fragment" app:layout_behavior=".util.DetailActivityScrollingViewBehavior" android:layout_width="match_parent" - android:layout_height="wrap_content"> + android:layout_height="match_parent"> </FrameLayout> <FrameLayout @@ -35,5 +26,22 @@ android:layout_width="0dp"> </FrameLayout> + <com.google.android.material.bottomappbar.BottomAppBar + android:id="@+id/detail_bottom_appbar" + app:backgroundTint="?colorSurfaceContainerHigh" + android:layout_width="match_parent" + android:layout_height="64dp" + android:layout_gravity="bottom" + app:menu="@menu/bottombar_detail" /> + + <com.google.android.material.floatingactionbutton.FloatingActionButton + android:id="@+id/detail_fab" + android:layout_gravity="end|bottom" + android:layout_marginEnd="16dp" + android:layout_marginBottom="38dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:srcCompat="@drawable/baseline_open_in_browser_24" /> + </androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/org.fox.ttrss/src/main/res/menu/activity_main.xml b/org.fox.ttrss/src/main/res/menu/activity_main.xml index 68dec353..1650f366 100755 --- a/org.fox.ttrss/src/main/res/menu/activity_main.xml +++ b/org.fox.ttrss/src/main/res/menu/activity_main.xml @@ -58,40 +58,14 @@ android:id="@+id/toggle_published" android:icon="@drawable/baseline_rss_feed_24" app:iconTint="?attr/colorControlNormal" - android:title="@string/article_toggle_published"/> - <item - android:id="@+id/toggle_unread" - android:icon="@drawable/baseline_email_24" - app:iconTint="?attr/colorControlNormal" app:showAsAction="ifRoom" - android:title="@string/article_toggle_unread"/> - <item - android:id="@+id/toggle_attachments" - android:icon="@drawable/baseline_attach_file_24" - app:showAsAction="" - android:title="@string/attachments_prompt"/> + android:title="@string/article_toggle_published"/> <item android:id="@+id/share_article" android:icon="@drawable/baseline_share_24" app:iconTint="?attr/colorControlNormal" app:showAsAction="ifRoom" android:title="@string/share_article"/> - <item - android:id="@+id/set_labels" - app:showAsAction="" - android:title="@string/article_set_labels"/> - <item - android:id="@+id/article_set_note" - app:showAsAction="" - android:title="@string/article_set_note"/> - <item - android:id="@+id/article_set_score" - app:showAsAction="" - android:title="@string/set_score"/> - - <item - android:id="@+id/catchup_above" - android:title="@string/article_mark_read_above"/> </group> diff --git a/org.fox.ttrss/src/main/res/menu/bottombar_detail.xml b/org.fox.ttrss/src/main/res/menu/bottombar_detail.xml new file mode 100644 index 00000000..744ae79b --- /dev/null +++ b/org.fox.ttrss/src/main/res/menu/bottombar_detail.xml @@ -0,0 +1,38 @@ +<menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> + + <item + android:id="@+id/article_set_score" + app:showAsAction="always" + app:iconTint="?attr/colorControlNormal" + android:icon="@drawable/baseline_trending_flat_24" + android:title="@string/set_score"/> + + <item + android:id="@+id/toggle_unread" + android:icon="@drawable/baseline_email_24" + app:iconTint="?attr/colorControlNormal" + app:showAsAction="always" + android:title="@string/article_toggle_unread"/> + + <item + android:id="@+id/article_set_labels" + app:showAsAction="always" + android:icon="@drawable/baseline_new_label_24" + app:iconTint="?attr/colorControlNormal" + android:title="@string/article_set_labels"/> + + <item + android:id="@+id/article_edit_note" + app:showAsAction="always" + android:icon="@drawable/baseline_note_add_24" + app:iconTint="?attr/colorControlNormal" + android:title="@string/article_edit_note"/> + + <item + android:id="@+id/toggle_attachments" + android:icon="@drawable/baseline_attachment_24" + app:iconTint="?attr/colorControlNormal" + app:showAsAction="always" + android:title="@string/attachments_prompt"/> + +</menu>
\ No newline at end of file diff --git a/org.fox.ttrss/src/main/res/menu/context_headlines.xml b/org.fox.ttrss/src/main/res/menu/context_headlines.xml index dffc9e47..e5a892ab 100644 --- a/org.fox.ttrss/src/main/res/menu/context_headlines.xml +++ b/org.fox.ttrss/src/main/res/menu/context_headlines.xml @@ -18,12 +18,12 @@ app:showAsAction="" android:title="@string/article_mark_read_above"/> <item - android:id="@+id/set_labels" + android:id="@+id/article_set_labels" android:title="@string/article_set_labels"/> <item - android:id="@+id/article_set_note" + android:id="@+id/article_edit_note" app:showAsAction="" - android:title="@string/article_set_note"/> + android:title="@string/article_edit_note"/> <item android:id="@+id/headlines_article_unread" app:showAsAction="" diff --git a/org.fox.ttrss/src/main/res/values/strings.xml b/org.fox.ttrss/src/main/res/values/strings.xml index 0de65e12..6a67013a 100755 --- a/org.fox.ttrss/src/main/res/values/strings.xml +++ b/org.fox.ttrss/src/main/res/values/strings.xml @@ -106,7 +106,7 @@ <string name="dialog_offline_sync_in_progress">Offline sync in progress</string> <string name="dialog_offline_sync_stop">Stop syncing</string> <string name="dialog_offline_sync_continue">Continue</string> - <string name="article_set_note">Publish with note</string> + <string name="article_edit_note">Edit note</string> <string name="dialog_open_preferences">Settings</string> <string name="dialog_need_configure_prompt">Please fill in your tt-rss server information such as URL, login, and password.</string> <!-- <string name="update_headlines">Refresh</string> --> |