From 2c25280ec467d1ee21496cbc9502f1817a31be82 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Wed, 4 May 2016 21:10:41 -0400 Subject: [PATCH 001/106] First pass at adding toolbar above reader post list --- .../ui/reader/ReaderPostListFragment.java | 23 ++++++++++++-- ...filtered_recyclerview_settings_control.xml | 8 ----- .../reader_filtered_recyclerview_controls.xml | 31 +++++++++++++++++++ 3 files changed, 51 insertions(+), 11 deletions(-) delete mode 100644 WordPress/src/main/res/layout/filtered_recyclerview_settings_control.xml create mode 100644 WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index 0edfb543cd43..bb2695306ecf 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -459,16 +459,33 @@ public void onShowCustomEmptyView (EmptyViewMessageType emptyViewMsgType) { int spacingVertical = context.getResources().getDimensionPixelSize(R.dimen.reader_card_gutters); mRecyclerView.addItemDecoration(new RecyclerItemDecoration(spacingHorizontal, spacingVertical, false)); + // add buttons to the filtered recyclerview's toolbar if (!ReaderUtils.isLoggedOutReader()) { - View settingsControl = inflater.inflate(R.layout.filtered_recyclerview_settings_control, null); - mRecyclerView.addToolbarCustomControl(settingsControl, new View.OnClickListener() { + ViewGroup controls = (ViewGroup) inflater.inflate(R.layout.reader_filtered_recyclerview_controls, null); + + // settings - shows tags & followed sites + View btnSettings = controls.findViewById(R.id.btn_settings); + ReaderUtils.setBackgroundToRoundRipple(btnSettings); + btnSettings.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ReaderActivityLauncher.showReaderSubs(v.getContext()); } }); - ReaderUtils.setBackgroundToRoundRipple(settingsControl); + + // search - a work in progress + View btnSearch = controls.findViewById(R.id.btn_search); + ReaderUtils.setBackgroundToRoundRipple(btnSearch); + btnSearch.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + // TODO + } + }); + + mRecyclerView.addToolbarCustomControl(controls, null); } + // the following will change the look and feel of the toolbar to match the current design mRecyclerView.setToolbarBackgroundColor(getResources().getColor(R.color.blue_medium)); mRecyclerView.setToolbarSpinnerTextColor(getResources().getColor(R.color.white)); diff --git a/WordPress/src/main/res/layout/filtered_recyclerview_settings_control.xml b/WordPress/src/main/res/layout/filtered_recyclerview_settings_control.xml deleted file mode 100644 index 606ba8dcc8a9..000000000000 --- a/WordPress/src/main/res/layout/filtered_recyclerview_settings_control.xml +++ /dev/null @@ -1,8 +0,0 @@ - - diff --git a/WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml b/WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml new file mode 100644 index 000000000000..05a2be2a6cee --- /dev/null +++ b/WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file From 56f0beea99528dd2368b955ea17c0b51dab932c5 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 5 May 2016 06:53:58 -0400 Subject: [PATCH 002/106] Replaced filtered recycler's ability to add components with a simpler approach - just add a menu --- .../android/ui/FilteredRecyclerView.java | 18 ++++----- .../ui/reader/ReaderPostListFragment.java | 36 +++++++---------- .../res/layout/filtered_list_component.xml | 40 +++++-------------- .../reader_filtered_recyclerview_controls.xml | 31 -------------- WordPress/src/main/res/menu/reader_list.xml | 18 +++++++++ 5 files changed, 50 insertions(+), 93 deletions(-) delete mode 100644 WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml create mode 100644 WordPress/src/main/res/menu/reader_list.xml diff --git a/WordPress/src/main/java/org/wordpress/android/ui/FilteredRecyclerView.java b/WordPress/src/main/java/org/wordpress/android/ui/FilteredRecyclerView.java index e41604179971..c1350e1fd0e4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/FilteredRecyclerView.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/FilteredRecyclerView.java @@ -1,6 +1,7 @@ package org.wordpress.android.ui; import android.content.Context; +import android.support.annotation.MenuRes; import android.support.design.widget.AppBarLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -12,7 +13,6 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.BaseAdapter; -import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.Spinner; @@ -41,7 +41,6 @@ public class FilteredRecyclerView extends RelativeLayout { private RecyclerView mRecyclerView; private TextView mEmptyView; private View mCustomEmptyView; - private LinearLayout mCustomComponentsContainer; private Toolbar mToolbar; private AppBarLayout mAppBarLayout; @@ -124,7 +123,6 @@ private void init() { mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); mRecyclerView.addItemDecoration(new RecyclerItemDecoration(spacingHorizontal, spacingVertical)); - mCustomComponentsContainer = (LinearLayout) findViewById(R.id.custom_components_toolbar_container); mToolbar = (Toolbar) findViewById(R.id.toolbar_with_spinner); mAppBarLayout = (AppBarLayout) findViewById(R.id.app_bar_layout); @@ -278,14 +276,12 @@ public void hideLoadingProgress() { } /* - * use this to add custom control/component views to your toolbar. Components are added on the right side of the - * toolbar */ - public void addToolbarCustomControl(View v, OnClickListener clickListener){ - if (v != null){ - mCustomComponentsContainer.addView(v); - if (clickListener != null){ - v.setOnClickListener(clickListener); - } + * add a menu to the right side of the toolbar + */ + public void addToolbarMenu(@MenuRes int menuResId, Toolbar.OnMenuItemClickListener listener) { + mToolbar.inflateMenu(menuResId); + if (listener != null) { + mToolbar.setOnMenuItemClickListener(listener); } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index bb2695306ecf..09d0ea8d754d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -7,7 +7,10 @@ import android.support.design.widget.Snackbar; import android.support.v7.widget.ListPopupWindow; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; @@ -461,29 +464,20 @@ public void onShowCustomEmptyView (EmptyViewMessageType emptyViewMsgType) { // add buttons to the filtered recyclerview's toolbar if (!ReaderUtils.isLoggedOutReader()) { - ViewGroup controls = (ViewGroup) inflater.inflate(R.layout.reader_filtered_recyclerview_controls, null); - - // settings - shows tags & followed sites - View btnSettings = controls.findViewById(R.id.btn_settings); - ReaderUtils.setBackgroundToRoundRipple(btnSettings); - btnSettings.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - ReaderActivityLauncher.showReaderSubs(v.getContext()); - } - }); - - // search - a work in progress - View btnSearch = controls.findViewById(R.id.btn_search); - ReaderUtils.setBackgroundToRoundRipple(btnSearch); - btnSearch.setOnClickListener(new View.OnClickListener() { + Toolbar.OnMenuItemClickListener toolbarListener = new Toolbar.OnMenuItemClickListener() { @Override - public void onClick(View v) { - // TODO + public boolean onMenuItemClick(MenuItem item) { + if (item.getItemId() == R.id.menu_settings) { + ReaderActivityLauncher.showReaderSubs(getActivity()); + return true; + } else if (item.getItemId() == R.id.menu_search) { + // TODO + return true; + } + return false; } - }); - - mRecyclerView.addToolbarCustomControl(controls, null); + }; + mRecyclerView.addToolbarMenu(R.menu.reader_list, toolbarListener); } // the following will change the look and feel of the toolbar to match the current design diff --git a/WordPress/src/main/res/layout/filtered_list_component.xml b/WordPress/src/main/res/layout/filtered_list_component.xml index 42bb96442589..41a7fec7f182 100644 --- a/WordPress/src/main/res/layout/filtered_list_component.xml +++ b/WordPress/src/main/res/layout/filtered_list_component.xml @@ -1,6 +1,5 @@ - + android:layout_width="match_parent" + android:layout_height="@dimen/toolbar_subtitle_height"> - - - - - - - - + android:layout_centerVertical="true" + android:overlapAnchor="false" /> diff --git a/WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml b/WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml deleted file mode 100644 index 05a2be2a6cee..000000000000 --- a/WordPress/src/main/res/layout/reader_filtered_recyclerview_controls.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/WordPress/src/main/res/menu/reader_list.xml b/WordPress/src/main/res/menu/reader_list.xml new file mode 100644 index 000000000000..aab3f4983684 --- /dev/null +++ b/WordPress/src/main/res/menu/reader_list.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file From f9e5ca3d9dfa9fccc4582e70bb40013735eb5fd6 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 5 May 2016 07:00:51 -0400 Subject: [PATCH 003/106] Check isAdded() in toolbar listener --- .../wordpress/android/ui/reader/ReaderPostListFragment.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index 09d0ea8d754d..ffc4d32c3413 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -467,6 +467,9 @@ public void onShowCustomEmptyView (EmptyViewMessageType emptyViewMsgType) { Toolbar.OnMenuItemClickListener toolbarListener = new Toolbar.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { + if (!isAdded()) { + return false; + } if (item.getItemId() == R.id.menu_settings) { ReaderActivityLauncher.showReaderSubs(getActivity()); return true; From 518db3355258e566a5d34d19242c29ab5a8db5c7 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 5 May 2016 19:04:51 -0400 Subject: [PATCH 004/106] First pass at adding SearchView --- WordPress/src/main/AndroidManifest.xml | 6 +- .../android/ui/FilteredRecyclerView.java | 7 +- .../ui/reader/ReaderPostListFragment.java | 68 +++++++++++++------ WordPress/src/main/res/menu/reader_list.xml | 4 +- 4 files changed, 58 insertions(+), 27 deletions(-) diff --git a/WordPress/src/main/AndroidManifest.xml b/WordPress/src/main/AndroidManifest.xml index 3985170bcd6c..5676e33c18bb 100644 --- a/WordPress/src/main/AndroidManifest.xml +++ b/WordPress/src/main/AndroidManifest.xml @@ -256,7 +256,11 @@ + android:theme="@style/Calypso.NoActionBar"> + + + + + app:actionViewClass="android.support.v7.widget.SearchView" + app:showAsAction="always|collapseActionView" /> \ No newline at end of file From ca0890d049a55e4489a7c56e729164315a52e36b Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 5 May 2016 20:55:41 -0400 Subject: [PATCH 005/106] Fixed centering of menu items in toolbar --- .../android/ui/reader/ReaderPostListFragment.java | 11 ++++++----- .../src/main/res/layout/filtered_list_component.xml | 4 ++-- WordPress/src/main/res/values/strings.xml | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index b6390cc69f49..ac2abf9e0990 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -510,27 +510,28 @@ public boolean onMenuItemClick(MenuItem item) { if (item.getItemId() == R.id.menu_settings) { ReaderActivityLauncher.showReaderSubs(getActivity()); return true; - } else if (item.getItemId() == R.id.menu_search) { - // TODO - return true; } return false; } }; - Menu menu = mRecyclerView.addToolbarMenu(R.menu.reader_list, toolbarListener); + Menu menu = mRecyclerView.addToolbarMenu(R.menu.reader_list, toolbarListener); + MenuItem settingsItem = menu.findItem(R.id.menu_settings); MenuItem searchItem = menu.findItem(R.id.menu_search); + mSearchView = (SearchView) searchItem.getActionView(); SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); - mSearchView.setQueryHint("Search hint"); + mSearchView.setQueryHint(getString(R.string.reader_hint_post_search)); mSearchView.setIconifiedByDefault(false); mSearchView.setSubmitButtonEnabled(false); mSearchView.setIconified(true); mSearchView.setFocusable(false); + + //mSearchView.setOnQueryTextListener(this); } diff --git a/WordPress/src/main/res/layout/filtered_list_component.xml b/WordPress/src/main/res/layout/filtered_list_component.xml index 41a7fec7f182..23dad694fed5 100644 --- a/WordPress/src/main/res/layout/filtered_list_component.xml +++ b/WordPress/src/main/res/layout/filtered_list_component.xml @@ -8,13 +8,13 @@ + android:layout_height="wrap_content"> diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 89aa349a6779..f18067fd0f5f 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -1095,6 +1095,7 @@ Reply to post… Reply to comment… Enter a URL or tag to follow + Search for posts New posts From 56669422c59875a0472c1b7455f137011cdb28f0 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 5 May 2016 21:15:10 -0400 Subject: [PATCH 006/106] Toggle settings icon with search --- .../ui/reader/ReaderPostListFragment.java | 22 ++++++++++++++++--- .../res/layout/filtered_list_component.xml | 1 - 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index ac2abf9e0990..2f1599c4f0a5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -6,6 +6,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.support.design.widget.Snackbar; +import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.ListPopupWindow; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; @@ -84,7 +85,10 @@ public class ReaderPostListFragment extends Fragment private View mNewPostsBar; private View mEmptyView; private ProgressBar mProgress; + private SearchView mSearchView; + private MenuItem mSettingsMenuItem; + private MenuItem mSearchMenuItem; private ReaderTag mCurrentTag; private long mCurrentBlogId; @@ -517,10 +521,10 @@ public boolean onMenuItemClick(MenuItem item) { Menu menu = mRecyclerView.addToolbarMenu(R.menu.reader_list, toolbarListener); - MenuItem settingsItem = menu.findItem(R.id.menu_settings); - MenuItem searchItem = menu.findItem(R.id.menu_search); + mSettingsMenuItem = menu.findItem(R.id.menu_settings); + mSearchMenuItem = menu.findItem(R.id.menu_search); - mSearchView = (SearchView) searchItem.getActionView(); + mSearchView = (SearchView) mSearchMenuItem.getActionView(); SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); @@ -530,7 +534,19 @@ public boolean onMenuItemClick(MenuItem item) { mSearchView.setIconified(true); mSearchView.setFocusable(false); + MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, new MenuItemCompat.OnActionExpandListener() { + @Override + public boolean onMenuItemActionExpand(MenuItem item) { + mSettingsMenuItem.setVisible(false); + return true; + } + @Override + public boolean onMenuItemActionCollapse(MenuItem item) { + mSettingsMenuItem.setVisible(true); + return true; + } + }); //mSearchView.setOnQueryTextListener(this); } diff --git a/WordPress/src/main/res/layout/filtered_list_component.xml b/WordPress/src/main/res/layout/filtered_list_component.xml index 23dad694fed5..358dc1e73667 100644 --- a/WordPress/src/main/res/layout/filtered_list_component.xml +++ b/WordPress/src/main/res/layout/filtered_list_component.xml @@ -24,7 +24,6 @@ style="@style/FilteredRecyclerViewSpinner.WordPress" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_centerVertical="true" android:overlapAnchor="false" /> From b295c041bfb9e3bae2dfcfab702df030aa3cb45e Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Thu, 5 May 2016 21:27:17 -0400 Subject: [PATCH 007/106] Removed toolbar listener from addToolbarMenu --- WordPress/src/main/AndroidManifest.xml | 3 -- .../android/ui/FilteredRecyclerView.java | 5 +-- .../ui/reader/ReaderPostListFragment.java | 38 ++++++++++--------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/WordPress/src/main/AndroidManifest.xml b/WordPress/src/main/AndroidManifest.xml index 5676e33c18bb..429fd210a423 100644 --- a/WordPress/src/main/AndroidManifest.xml +++ b/WordPress/src/main/AndroidManifest.xml @@ -257,9 +257,6 @@ android:name=".ui.reader.ReaderPostListActivity" android:label="@string/reader" android:theme="@style/Calypso.NoActionBar"> - - - Date: Thu, 5 May 2016 21:31:10 -0400 Subject: [PATCH 008/106] Simplified search view config --- .../android/ui/reader/ReaderPostListFragment.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index a791840c54a6..e0b2d6ca823e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -1,7 +1,6 @@ package org.wordpress.android.ui.reader; import android.app.Fragment; -import android.app.SearchManager; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; @@ -517,14 +516,10 @@ public boolean onMenuItemClick(MenuItem item) { }); mSearchView = (SearchView) mSearchMenuItem.getActionView(); - SearchManager searchManager = (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE); - mSearchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName())); - mSearchView.setQueryHint(getString(R.string.reader_hint_post_search)); - mSearchView.setIconifiedByDefault(false); mSearchView.setSubmitButtonEnabled(false); + mSearchView.setIconifiedByDefault(false); mSearchView.setIconified(true); - mSearchView.setFocusable(false); MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, new MenuItemCompat.OnActionExpandListener() { @Override From ec694f25e2b11506d1540100bbfe542168533855 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Fri, 6 May 2016 14:13:04 -0400 Subject: [PATCH 009/106] Added bare-bones SearchViewStyle --- .../android/ui/reader/ReaderActivityLauncher.java | 14 ++++++++++++++ .../android/ui/reader/ReaderConstants.java | 1 + .../android/ui/reader/ReaderPostListFragment.java | 8 +++++++- .../wordpress/android/ui/reader/ReaderTypes.java | 5 +++-- WordPress/src/main/res/values/styles.xml | 4 ++++ 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java index f79347c1d6b8..3ec16df08c3b 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java @@ -134,6 +134,20 @@ public static void showReaderTagPreview(Context context, ReaderTag tag) { context.startActivity(intent); } + // TODO: implement search in ReaderPostListActivity for a future PR + public static void showReaderSearchResults(Context context, String query) { + if (TextUtils.isEmpty(query)) { + return; + } + + // TODO: track this + //AnalyticsTracker.track(AnalyticsTracker.Stat.READER_BLOG_PREVIEWED); + Intent intent = new Intent(context, ReaderPostListActivity.class); + intent.putExtra(ReaderConstants.ARG_SEARCH_QUERY, query); + intent.putExtra(ReaderConstants.ARG_POST_LIST_TYPE, ReaderPostListType.SEARCH_RESULTS); + context.startActivity(intent); + } + /* * show comments for the passed Ids diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderConstants.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderConstants.java index b5f7181799bf..f4732f21ec5c 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderConstants.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderConstants.java @@ -23,6 +23,7 @@ public class ReaderConstants { static final String ARG_POST_LIST_TYPE = "post_list_type"; static final String ARG_CONTENT = "content"; static final String ARG_IS_SINGLE_POST = "is_single_post"; + static final String ARG_SEARCH_QUERY = "search_query"; static final String KEY_ALREADY_UPDATED = "already_updated"; static final String KEY_ALREADY_REQUESTED = "already_requested"; diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index e0b2d6ca823e..500a99d47129 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -521,6 +521,7 @@ public boolean onMenuItemClick(MenuItem item) { mSearchView.setIconifiedByDefault(false); mSearchView.setIconified(true); + // toggle settings icon when search expands/collapses MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, new MenuItemCompat.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { @@ -539,7 +540,12 @@ public boolean onMenuItemActionCollapse(MenuItem item) { @Override public boolean onQueryTextSubmit(String query) { // TODO: perform search - return false; + if (getPostListType() == ReaderPostListType.SEARCH_RESULTS) { + // reuse existing fragment + } else { + ReaderActivityLauncher.showReaderSearchResults(getActivity(), query); + } + return true; } @Override diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderTypes.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderTypes.java index 74718bddd643..9b94773dada6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderTypes.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderTypes.java @@ -5,10 +5,11 @@ public class ReaderTypes { public static final ReaderPostListType DEFAULT_POST_LIST_TYPE = ReaderPostListType.TAG_FOLLOWED; - public static enum ReaderPostListType { + public enum ReaderPostListType { TAG_FOLLOWED, // list posts in a followed tag TAG_PREVIEW, // list posts in a specific tag - BLOG_PREVIEW; // list posts in a specific blog/feed + BLOG_PREVIEW, // list posts in a specific blog/feed + SEARCH_RESULTS; // list posts matching a specific search keyword or phrase public boolean isTagType() { return this.equals(TAG_FOLLOWED) || this.equals(TAG_PREVIEW); diff --git a/WordPress/src/main/res/values/styles.xml b/WordPress/src/main/res/values/styles.xml index 56ee2b3ce2d7..1edaff040e9b 100644 --- a/WordPress/src/main/res/values/styles.xml +++ b/WordPress/src/main/res/values/styles.xml @@ -27,8 +27,12 @@ true @style/WordPress.SwipeToRefresh + @style/WordPress.SearchViewStyle + + From 5b1463e272f6038e4f6be4efe72c277ff67b82a8 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Fri, 6 May 2016 15:26:59 -0400 Subject: [PATCH 010/106] Implemented shell for search results, including empty message --- .../ui/reader/ReaderActivityLauncher.java | 3 +- .../ui/reader/ReaderPostListActivity.java | 21 ++++++ .../ui/reader/ReaderPostListFragment.java | 67 ++++++++++++------- .../ui/reader/adapters/ReaderPostAdapter.java | 19 ++++++ WordPress/src/main/res/values/strings.xml | 5 +- 5 files changed, 89 insertions(+), 26 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java index 3ec16df08c3b..b666e8cc0ca8 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderActivityLauncher.java @@ -134,14 +134,13 @@ public static void showReaderTagPreview(Context context, ReaderTag tag) { context.startActivity(intent); } - // TODO: implement search in ReaderPostListActivity for a future PR public static void showReaderSearchResults(Context context, String query) { if (TextUtils.isEmpty(query)) { return; } // TODO: track this - //AnalyticsTracker.track(AnalyticsTracker.Stat.READER_BLOG_PREVIEWED); + //AnalyticsTracker.track(AnalyticsTracker.Stat.???); Intent intent = new Intent(context, ReaderPostListActivity.class); intent.putExtra(ReaderConstants.ARG_SEARCH_QUERY, query); intent.putExtra(ReaderConstants.ARG_POST_LIST_TYPE, ReaderPostListType.SEARCH_RESULTS); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java index b1ea96be4c1f..6b0277ee7acb 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListActivity.java @@ -8,6 +8,7 @@ import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.text.TextUtils; import android.view.MenuItem; import org.wordpress.android.R; @@ -58,6 +59,12 @@ public void onCreate(Bundle savedInstanceState) { if (tag != null && savedInstanceState == null) { showListFragmentForTag(tag, mPostListType); } + } else if (getPostListType() == ReaderPostListType.SEARCH_RESULTS) { + String query = getIntent().getStringExtra(ReaderConstants.ARG_SEARCH_QUERY); + if (!TextUtils.isEmpty(query) && savedInstanceState == null) { + setTitle(String.format(getString(R.string.reader_title_search_results), query)); + showListFragmentForSearch(query); + } } } @@ -158,6 +165,20 @@ private void showListFragmentForFeed(long feedId) { .commit(); } + /* + * show fragment containing list of posts matching the passed search query + */ + private void showListFragmentForSearch(@NonNull String query) { + if (isFinishing()) { + return; + } + Fragment fragment = ReaderPostListFragment.newInstanceForSearch(query); + getFragmentManager() + .beginTransaction() + .replace(R.id.fragment_container, fragment, getString(R.string.fragment_tag_reader_post_list)) + .commit(); + } + private ReaderPostListFragment getListFragment() { Fragment fragment = getFragmentManager().findFragmentByTag(getString(R.string.fragment_tag_reader_post_list)); if (fragment == null) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index 500a99d47129..89bc772a9803 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -4,6 +4,7 @@ import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.design.widget.Snackbar; import android.support.v4.view.MenuItemCompat; import android.support.v7.widget.ListPopupWindow; @@ -91,6 +92,7 @@ public class ReaderPostListFragment extends Fragment private ReaderTag mCurrentTag; private long mCurrentBlogId; private long mCurrentFeedId; + private String mCurrentSearchQuery; private ReaderPostListType mPostListType; private int mRestorePosition; @@ -182,6 +184,19 @@ public static ReaderPostListFragment newInstanceForFeed(long feedId) { return fragment; } + public static ReaderPostListFragment newInstanceForSearch(@NonNull String query) { + AppLog.d(T.READER, "reader post list > newInstance (search)"); + + Bundle args = new Bundle(); + args.putString(ReaderConstants.ARG_SEARCH_QUERY, query); + args.putSerializable(ReaderConstants.ARG_POST_LIST_TYPE, ReaderPostListType.SEARCH_RESULTS); + + ReaderPostListFragment fragment = new ReaderPostListFragment(); + fragment.setArguments(args); + + return fragment; + } + @Override public void setArguments(Bundle args) { super.setArguments(args); @@ -196,6 +211,7 @@ public void setArguments(Bundle args) { mCurrentBlogId = args.getLong(ReaderConstants.ARG_BLOG_ID); mCurrentFeedId = args.getLong(ReaderConstants.ARG_FEED_ID); + mCurrentSearchQuery = args.getString(ReaderConstants.ARG_SEARCH_QUERY); if (getPostListType() == ReaderPostListType.TAG_PREVIEW && hasCurrentTag()) { mTagPreviewHistory.push(getCurrentTagName()); @@ -218,6 +234,9 @@ public void onCreate(Bundle savedInstanceState) { if (savedInstanceState.containsKey(ReaderConstants.ARG_FEED_ID)) { mCurrentFeedId = savedInstanceState.getLong(ReaderConstants.ARG_FEED_ID); } + if (savedInstanceState.containsKey(ReaderConstants.ARG_SEARCH_QUERY)) { + mCurrentSearchQuery = savedInstanceState.getString(ReaderConstants.ARG_SEARCH_QUERY); + } if (savedInstanceState.containsKey(ReaderConstants.ARG_POST_LIST_TYPE)) { mPostListType = (ReaderPostListType) savedInstanceState.getSerializable(ReaderConstants.ARG_POST_LIST_TYPE); } @@ -352,6 +371,7 @@ public void onSaveInstanceState(Bundle outState) { outState.putLong(ReaderConstants.ARG_BLOG_ID, mCurrentBlogId); outState.putLong(ReaderConstants.ARG_FEED_ID, mCurrentFeedId); + outState.putString(ReaderConstants.ARG_SEARCH_QUERY, mCurrentSearchQuery); outState.putBoolean(ReaderConstants.KEY_WAS_PAUSED, mWasPaused); outState.putBoolean(ReaderConstants.KEY_ALREADY_UPDATED, mHasUpdatedPosts); outState.putBoolean(ReaderConstants.KEY_FIRST_LOAD, mFirstLoad); @@ -637,9 +657,7 @@ private boolean shouldShowBoxAndPagesAnimation() { return getPostListType().isTagType(); } private void startBoxAndPagesAnimation() { - if (!isAdded()) { - return; - } + if (!isAdded()) return; ImageView page1 = (ImageView) mEmptyView.findViewById(R.id.empty_tags_box_page1); ImageView page2 = (ImageView) mEmptyView.findViewById(R.id.empty_tags_box_page2); @@ -651,49 +669,50 @@ private void startBoxAndPagesAnimation() { } private void setEmptyTitleAndDescription(boolean requestFailed) { - if (!isAdded()) { - return; - } + if (!isAdded()) return; - int titleResId; - int descriptionResId = 0; + String title; + String description = null; if (!NetworkUtils.isNetworkAvailable(getActivity())) { - titleResId = R.string.reader_empty_posts_no_connection; + title = getString(R.string.reader_empty_posts_no_connection); } else if (requestFailed) { - titleResId = R.string.reader_empty_posts_request_failed; + title = getString(R.string.reader_empty_posts_request_failed); } else if (isUpdating()) { - titleResId = R.string.reader_empty_posts_in_tag_updating; + title = getString(R.string.reader_empty_posts_in_tag_updating); } else if (getPostListType() == ReaderPostListType.BLOG_PREVIEW) { - titleResId = R.string.reader_empty_posts_in_blog; + title = getString(R.string.reader_empty_posts_in_blog); } else if (getPostListType() == ReaderPostListType.TAG_FOLLOWED && hasCurrentTag()) { if (getCurrentTag().isFollowedSites()) { if (ReaderBlogTable.hasFollowedBlogs()) { - titleResId = R.string.reader_empty_followed_blogs_no_recent_posts_title; - descriptionResId = R.string.reader_empty_followed_blogs_no_recent_posts_description; + title = getString(R.string.reader_empty_followed_blogs_no_recent_posts_title); + description = getString(R.string.reader_empty_followed_blogs_no_recent_posts_description); } else { - titleResId = R.string.reader_empty_followed_blogs_title; - descriptionResId = R.string.reader_empty_followed_blogs_description; + title = getString(R.string.reader_empty_followed_blogs_title); + description = getString(R.string.reader_empty_followed_blogs_description); } } else if (getCurrentTag().isPostsILike()) { - titleResId = R.string.reader_empty_posts_liked; + title = getString(R.string.reader_empty_posts_liked); } else if (getCurrentTag().tagType == ReaderTagType.CUSTOM_LIST) { - titleResId = R.string.reader_empty_posts_in_custom_list; + title = getString(R.string.reader_empty_posts_in_custom_list); } else { - titleResId = R.string.reader_empty_posts_in_tag; + title = getString(R.string.reader_empty_posts_in_tag); } + } else if (getPostListType() == ReaderPostListType.SEARCH_RESULTS) { + title = getString(R.string.reader_empty_posts_in_search_title); + description = String.format(getString(R.string.reader_empty_posts_in_search_description), mCurrentSearchQuery); } else { - titleResId = R.string.reader_empty_posts_in_tag; + title = getString(R.string.reader_empty_posts_in_tag); } TextView titleView = (TextView) mEmptyView.findViewById(R.id.title_empty); - titleView.setText(getString(titleResId)); + titleView.setText(title); TextView descriptionView = (TextView) mEmptyView.findViewById(R.id.description_empty); - if (descriptionResId == 0) { + if (description == null) { descriptionView.setVisibility(View.INVISIBLE); } else { - descriptionView.setText(getString(descriptionResId)); + descriptionView.setText(description); descriptionView.setVisibility(View.VISIBLE); } } @@ -780,6 +799,8 @@ private ReaderPostAdapter getPostAdapter() { mPostAdapter.setCurrentTag(getCurrentTag()); } else if (getPostListType() == ReaderPostListType.BLOG_PREVIEW) { mPostAdapter.setCurrentBlogAndFeed(mCurrentBlogId, mCurrentFeedId); + } else if (getPostListType() == ReaderPostListType.SEARCH_RESULTS) { + mPostAdapter.setCurrentSearchQuery(mCurrentSearchQuery); } } return mPostAdapter; diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java index 5d18ea78917e..08f422170f2e 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/adapters/ReaderPostAdapter.java @@ -2,6 +2,7 @@ import android.content.Context; import android.os.AsyncTask; +import android.support.annotation.NonNull; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.text.TextUtils; @@ -46,6 +47,7 @@ public class ReaderPostAdapter extends RecyclerView.AdapterTags & Blogs %1$d of %2$d @string/comments + Search for %s Followed tags @@ -1095,7 +1096,7 @@ Reply to post… Reply to comment… Enter a URL or tag to follow - Search for posts + Search on WordPress.com New posts @@ -1177,6 +1178,8 @@ You haven\'t liked any posts No comments yet This blog is empty + No Results + No posts found for \"%s\" for your language Originally posted by %1$s on %2$s From d1594cae8e0e8c87eff86c1578f0d81ae77bfd88 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Fri, 6 May 2016 15:55:21 -0400 Subject: [PATCH 011/106] Clear the post list when search is expanded, reload the list when search is collapsed --- .../android/ui/reader/ReaderPostListFragment.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java index 89bc772a9803..aa17a871de61 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/reader/ReaderPostListFragment.java @@ -541,17 +541,20 @@ public boolean onMenuItemClick(MenuItem item) { mSearchView.setIconifiedByDefault(false); mSearchView.setIconified(true); - // toggle settings icon when search expands/collapses MenuItemCompat.setOnActionExpandListener(mSearchMenuItem, new MenuItemCompat.OnActionExpandListener() { @Override public boolean onMenuItemActionExpand(MenuItem item) { + // hide settings icon and clear post list when search input is expanded mSettingsMenuItem.setVisible(false); + getPostAdapter().clear(); return true; } @Override public boolean onMenuItemActionCollapse(MenuItem item) { + // redisplay settings icon and reload post list when search input is collapsed mSettingsMenuItem.setVisible(true); + reloadPosts(); return true; } }); @@ -576,6 +579,12 @@ public boolean onQueryTextChange(String newText) { ); } + /* + * is the search input showing? + */ + private boolean isSearchViewExpanded() { + return mSearchView != null && !mSearchView.isIconified(); + } /* * called when user taps follow item in popup menu for a post */ @@ -1258,9 +1267,7 @@ private void trackTagLoaded(ReaderTag tag) { */ @Override public void onShowPostPopup(View view, final ReaderPost post) { - if (view == null || post == null || !isAdded()) { - return; - } + if (view == null || post == null || !isAdded()) return; Context context = view.getContext(); final ListPopupWindow listPopup = new ListPopupWindow(context); From 5bdb33d45147f6741a9ecef95c9ac4936f0e2d01 Mon Sep 17 00:00:00 2001 From: Nick Bradbury Date: Fri, 6 May 2016 16:06:07 -0400 Subject: [PATCH 012/106] Renamed FilteredRecyclerViewFilterContainer style to FilteredRecyclerViewToolbar --- WordPress/src/main/res/layout-sw720dp/stats_activity.xml | 2 +- WordPress/src/main/res/layout/filtered_list_component.xml | 2 +- WordPress/src/main/res/layout/stats_activity.xml | 2 +- WordPress/src/main/res/values/styles.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/WordPress/src/main/res/layout-sw720dp/stats_activity.xml b/WordPress/src/main/res/layout-sw720dp/stats_activity.xml index 68c844301037..54585e28cd93 100644 --- a/WordPress/src/main/res/layout-sw720dp/stats_activity.xml +++ b/WordPress/src/main/res/layout-sw720dp/stats_activity.xml @@ -21,7 +21,7 @@ android:id="@+id/toolbar_filter" android:layout_width="match_parent" android:layout_height="wrap_content" - style="@style/FilteredRecyclerViewFilterContainer" + style="@style/FilteredRecyclerViewToolbar" app:layout_scrollFlags="scroll|enterAlways"> diff --git a/WordPress/src/main/res/values/styles.xml b/WordPress/src/main/res/values/styles.xml index 1edaff040e9b..2d3b127415bc 100644 --- a/WordPress/src/main/res/values/styles.xml +++ b/WordPress/src/main/res/values/styles.xml @@ -90,7 +90,7 @@ @dimen/text_sz_large - -