Bug 1291751 - Implement ASSearchActivity for bookmarks/history search
MozReview-Commit-ID: 9NyLP6PtKmJ
--- a/mobile/android/base/AndroidManifest.xml.in
+++ b/mobile/android/base/AndroidManifest.xml.in
@@ -273,16 +273,19 @@
<activity android:name="org.mozilla.gecko.preferences.GeckoPreferences"
android:theme="@style/Gecko.Preferences"
android:configChanges="orientation|screenSize|locale|layoutDirection"
android:excludeFromRecents="true"/>
<activity android:name="org.mozilla.gecko.home.activitystream.ASDetailActivity"
android:theme="@style/Gecko"/>
+ <activity android:name="org.mozilla.gecko.home.activitystream.search.ASSearchActivity"
+ android:theme="@style/Gecko"/>
+
<provider android:name="org.mozilla.gecko.db.BrowserProvider"
android:authorities="@ANDROID_PACKAGE_NAME@.db.browser"
android:exported="false"/>
<provider android:name="org.mozilla.gecko.distribution.PartnerBookmarksProviderProxy"
android:authorities="@ANDROID_PACKAGE_NAME@.partnerbookmarks"
android:exported="false"/>
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/search/ASSearchActivity.java
@@ -0,0 +1,141 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.mozilla.gecko.home.activitystream.search;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.app.LoaderManager;
+import android.support.v4.content.CursorLoader;
+import android.support.v4.content.Loader;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.widget.LinearLayoutManager;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.EditText;
+
+import org.mozilla.gecko.GeckoProfile;
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.db.BrowserDB;
+import org.mozilla.gecko.home.CombinedHistoryRecyclerView;
+import org.mozilla.gecko.home.HomePager;
+import org.mozilla.gecko.home.activitystream.ASOpenURLDelegate;
+import org.mozilla.gecko.widget.RecyclerViewClickSupport;
+
+import java.util.EnumSet;
+
+public class ASSearchActivity extends AppCompatActivity implements HomePager.OnUrlOpenListener {
+ public static final String ACTIVITY_ARG_BOOKMARKS_MODE = "mode_bookmarks";
+
+ private static final String LOADER_ARG_KEY_CONSTRAINT = "constraint";
+
+ private CombinedHistoryRecyclerView resultsList;
+
+ @Override
+ public void onUrlOpen(String url, EnumSet<Flags> flags) {
+ ASOpenURLDelegate.openURL(this, url, flags);
+ }
+
+ private static class SearchLoader extends CursorLoader {
+ final String constraint;
+
+ public SearchLoader(Context context, String constraint) {
+ super(context);
+
+ this.constraint = constraint;
+ }
+
+ @Override
+ public Cursor loadInBackground() {
+ if (constraint == null || constraint.length() == 0) {
+ // We don't want to show any results when the query string is empty
+ return null;
+ }
+
+ return GeckoProfile.get(getContext()).getDB().filter(getContext().getContentResolver(),
+ constraint,
+ 50,
+ EnumSet.noneOf(BrowserDB.FilterFlags.class));
+ }
+ }
+
+ private class CursorLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
+ @Override
+ public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+ final String constraint;
+ if (args != null) {
+ constraint = args.getString(LOADER_ARG_KEY_CONSTRAINT);
+ } else {
+ constraint = null;
+ }
+
+ return new SearchLoader(getApplicationContext(), constraint);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
+ ((ASSearchResultsAdapter) resultsList.getAdapter()).swapCursor(data);
+ }
+
+ @Override
+ public void onLoaderReset(Loader<Cursor> loader) {
+ ((ASSearchResultsAdapter) resultsList.getAdapter()).swapCursor(null);
+ }
+ }
+
+
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.as_search_activity);
+
+ findViewById(R.id.as_search_back).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ finish();
+ }
+ });
+
+ resultsList = (CombinedHistoryRecyclerView) findViewById(R.id.as_search_results);
+
+ resultsList.setOnHistoryClickedListener(this);
+ resultsList.setLayoutManager(new LinearLayoutManager(this));
+ resultsList.setAdapter(new ASSearchResultsAdapter());
+
+ // The long click support in CombineddHistoryRecyclerView makes various assumptions
+ // which do not apply to our view and adapter. We don't need long-click support
+ // for search results so we can just disable it completely for now.
+ RecyclerViewClickSupport.addTo(resultsList).setOnItemLongClickListener(null);
+
+ final CursorLoaderCallbacks callbacks = new CursorLoaderCallbacks();
+ getSupportLoaderManager().initLoader(0, null, callbacks);
+
+ final EditText searchEntry = (EditText) findViewById(R.id.as_search_entry);
+
+ if (getIntent().getBooleanExtra(ACTIVITY_ARG_BOOKMARKS_MODE, false)) {
+ searchEntry.setHint(R.string.as_search_in_bookmarks);
+ } else {
+ searchEntry.setHint(R.string.as_search_in_history);
+ }
+
+ searchEntry.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+ Bundle data = new Bundle();
+ data.putString(LOADER_ARG_KEY_CONSTRAINT, s.toString());
+
+ getSupportLoaderManager().restartLoader(0, data, callbacks);
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+ });
+ }
+}
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/home/activitystream/search/ASSearchResultsAdapter.java
@@ -0,0 +1,52 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+package org.mozilla.gecko.home.activitystream.search;
+
+import android.database.Cursor;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.ViewGroup;
+
+import org.mozilla.gecko.R;
+import org.mozilla.gecko.home.CombinedHistoryItem;
+import org.mozilla.gecko.home.TwoLinePageRow;
+
+class ASSearchResultsAdapter extends RecyclerView.Adapter<CombinedHistoryItem.BookmarkHistoryItem> {
+ private Cursor cursor = null;
+
+ @Override
+ public CombinedHistoryItem.BookmarkHistoryItem onCreateViewHolder(ViewGroup parent, int viewType) {
+ final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
+
+ final TwoLinePageRow row = (TwoLinePageRow) inflater.inflate(R.layout.home_item_row, parent, false);
+ return new CombinedHistoryItem.BookmarkHistoryItem(row);
+ }
+
+ @Override
+ public void onBindViewHolder(CombinedHistoryItem.BookmarkHistoryItem holder, int position) {
+ cursor.moveToPosition(position);
+ holder.bind(cursor);
+ }
+
+ @Override
+ public int getItemCount() {
+ if (cursor != null) {
+ return cursor.getCount();
+ } else {
+ return 0;
+ }
+ }
+
+ public void swapCursor(Cursor c) {
+ cursor = c;
+
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return CombinedHistoryItem.ItemType.HISTORY.ordinal();
+ }
+}
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -826,8 +826,10 @@ just addresses the organization to follo
<!ENTITY helper_first_offline_bookmark_title "Read offline">
<!ENTITY helper_first_offline_bookmark_message "Find your Reader View items in Bookmarks, even offline.">
<!ENTITY helper_first_offline_bookmark_button "Go to Bookmarks">
<!ENTITY helper_triple_readerview_open_title "Available offline">
<!ENTITY helper_triple_readerview_open_message "Bookmark Reader View items to read them offline.">
<!ENTITY helper_triple_readerview_open_button "Add to Bookmarks">
+<!ENTITY as_search_in_bookmarks "Search in Bookmarks">
+<!ENTITY as_search_in_history "Search in History">
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -438,16 +438,18 @@ gbjar.sources += ['java/org/mozilla/geck
'health/HealthRecorder.java',
'health/SessionInformation.java',
'health/StubbedHealthRecorder.java',
'home/activitystream/ActivityStream.java',
'home/activitystream/ASCombinedHistoryAdapter.java',
'home/activitystream/ASCombinedHistoryPanel.java',
'home/activitystream/ASDetailActivity.java',
'home/activitystream/ASOpenURLDelegate.java',
+ 'home/activitystream/search/ASSearchActivity.java',
+ 'home/activitystream/search/ASSearchResultsAdapter.java',
'home/BookmarkFolderView.java',
'home/BookmarkScreenshotRow.java',
'home/BookmarksListAdapter.java',
'home/BookmarksListView.java',
'home/BookmarksPanel.java',
'home/BrowserSearch.java',
'home/ClientsAdapter.java',
'home/CombinedHistoryAdapter.java',
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/drawable/as_search_bg.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#363B40"/>
+ <corners android:radius="2dip"/>
+</shape>
\ No newline at end of file
copy from mobile/android/base/resources/layout/as_detail_activity.xml
copy to mobile/android/base/resources/layout/as_search_activity.xml
--- a/mobile/android/base/resources/layout/as_detail_activity.xml
+++ b/mobile/android/base/resources/layout/as_search_activity.xml
@@ -1,51 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/topbar"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/about_page_header_grey"
android:layout_gravity="top"
android:layout_marginBottom="1dp">
- <android.support.design.widget.TabLayout
- android:id="@+id/as_detail_tablayout"
- android:layout_width="0dp"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:layout_gravity="left"
- android:paddingLeft="12dp"
- android:paddingRight="12dp"
- app:tabSelectedTextColor="@color/placeholder_grey"
- app:tabTextColor="@color/tab_text_color"
- app:tabMode="scrollable"
- app:tabIndicatorHeight="4dp"
- app:tabIndicatorColor="#ff9400" />
-
<ImageView
android:layout_width="42dp"
android:layout_height="42dp"
android:padding="10dp"
- android:src="@drawable/ab_search"
- android:id="@+id/as_search_button"/>
+ android:src="@drawable/ic_menu_back"
+ android:id="@+id/as_search_back"/>
- <ImageView
- android:layout_width="42dp"
- android:layout_height="42dp"
- android:padding="14dp"
- android:src="@drawable/tab_close"
- android:id="@+id/as_close_button"/>
+ <EditText
+ android:id="@+id/as_search_entry"
+ style="@style/UrlBar.Button"
+ android:layout_margin="3dp"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:paddingLeft="8dp"
+ android:background="@drawable/as_search_bg"
+ android:textColor="@android:color/white"
+ android:textColorHint="@color/about_page_header_grey"
+ android:paddingRight="8dp"/>
</LinearLayout>
- <android.support.v4.view.ViewPager
- android:id="@+id/as_pager"
+ <org.mozilla.gecko.home.CombinedHistoryRecyclerView
+ android:id="@+id/as_search_results"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="wrap_content"/>
</LinearLayout>
\ No newline at end of file
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -629,9 +629,11 @@
<string name="helper_first_offline_bookmark_title">&helper_first_offline_bookmark_title;</string>
<string name="helper_first_offline_bookmark_message">&helper_first_offline_bookmark_message;</string>
<string name="helper_first_offline_bookmark_button">&helper_first_offline_bookmark_button;</string>
<string name="helper_triple_readerview_open_title">&helper_triple_readerview_open_title;</string>
<string name="helper_triple_readerview_open_message">&helper_triple_readerview_open_message;</string>
<string name="helper_triple_readerview_open_button">&helper_triple_readerview_open_button;</string>
+ <string name="as_search_in_bookmarks">&as_search_in_bookmarks;</string>
+ <string name="as_search_in_history">&as_search_in_history;</string>
</resources>