Bug 882715 - Implement history/last tabs buttons in VisitedPage (r=bnicholson)
authorLucas Rocha <lucasr@mozilla.com>
Mon, 08 Jul 2013 23:05:51 +0100
changeset 151374 d239a58564cb
parent 151373 6c702f748e20
child 151375 5dd5b41a64b8
push idunknown
push userunknown
push dateunknown
reviewersbnicholson
bugs882715
milestone25.0a1
Bug 882715 - Implement history/last tabs buttons in VisitedPage (r=bnicholson)
mobile/android/base/BrowserApp.java
mobile/android/base/Makefile.in
mobile/android/base/home/HomeFragment.java
mobile/android/base/home/HomePager.java
mobile/android/base/home/VisitedPage.java
mobile/android/base/locales/en-US/android_strings.dtd
mobile/android/base/resources/layout/home_visited_page.xml
mobile/android/base/resources/values/styles.xml
mobile/android/base/strings.xml.in
--- a/mobile/android/base/BrowserApp.java
+++ b/mobile/android/base/BrowserApp.java
@@ -1426,16 +1426,23 @@ abstract public class BrowserApp extends
             return;
         }
 
         final Tab tab = Tabs.getInstance().getSelectedTab();
         if (tab != null && isAboutHome(tab)) {
             return;
         }
 
+        // Hide any visible homepager subpages
+        final FragmentManager fm = getSupportFragmentManager();
+        final Fragment subPage = fm.findFragmentByTag(HomePager.SUBPAGE_TAG);
+        if (subPage != null) {
+            fm.beginTransaction().remove(subPage).commitAllowingStateLoss();
+        }
+
         // FIXME: do animation if animate is true
         mHomePager.hide();
 
         mBrowserToolbar.setShadowVisibility(true);
         mBrowserToolbar.setNextFocusDownId(R.id.layer_view);
 
         // Refresh toolbar height to possibly restore the toolbar padding
         refreshToolbarHeight();
--- a/mobile/android/base/Makefile.in
+++ b/mobile/android/base/Makefile.in
@@ -466,16 +466,17 @@ RES_LAYOUT = \
   res/layout/find_in_page_content.xml \
   res/layout/font_size_preference.xml \
   res/layout/gecko_app.xml \
   res/layout/home_bookmarks_page.xml \
   res/layout/home_item_row.xml \
   res/layout/home_header_row.xml \
   res/layout/home_list_with_title.xml \
   res/layout/home_search_item_row.xml \
+  res/layout/home_visited_page.xml \
   res/layout/web_app.xml \
   res/layout/launch_app_list.xml \
   res/layout/launch_app_listitem.xml \
   res/layout/menu_action_bar.xml \
   res/layout/menu_item_action_view.xml \
   res/layout/menu_popup.xml \
   res/layout/notification_icon_text.xml \
   res/layout/notification_progress.xml \
--- a/mobile/android/base/home/HomeFragment.java
+++ b/mobile/android/base/home/HomeFragment.java
@@ -41,16 +41,22 @@ class HomeFragment extends Fragment {
     private static final String LOGTAG="GeckoHomeFragment";
 
     // Share MIME type.
     private static final String SHARE_MIME_TYPE = "text/plain";
 
     // URL to Title replacement regex.
     private static final String REGEX_URL_TO_TITLE = "^([a-z]+://)?(www\\.)?";
 
+    protected void showSubPage(Fragment subPage) {
+        getActivity().getSupportFragmentManager().beginTransaction()
+                .addToBackStack(null).replace(R.id.home_pager_container, subPage, HomePager.SUBPAGE_TAG)
+                .commitAllowingStateLoss();
+    }
+
     @Override
     public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
         if (!(menuInfo instanceof HomeContextMenuInfo)) {
             return;
         }
 
         HomeContextMenuInfo info = (HomeContextMenuInfo) menuInfo;
 
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -17,16 +17,19 @@ import android.support.v4.view.ViewPager
 import android.util.AttributeSet;
 import android.view.ViewGroup;
 
 import java.util.ArrayList;
 import java.util.EnumMap;
 import java.util.EnumSet;
 
 public class HomePager extends ViewPager {
+    // Subpage fragment tag
+    public static final String SUBPAGE_TAG = "home_pager_subpage";
+
     private final Context mContext;
     private volatile boolean mLoaded;
 
     // List of pages in order.
     private enum Page {
         VISITED,
         BOOKMARKS,
         READING_LIST
--- a/mobile/android/base/home/VisitedPage.java
+++ b/mobile/android/base/home/VisitedPage.java
@@ -38,16 +38,22 @@ public class VisitedPage extends HomeFra
     private static final int FAVICONS_LOADER_ID = 1;
 
     // Adapter for the list of search results
     private VisitedAdapter mAdapter;
 
     // The view shown by the fragment.
     private ListView mList;
 
+    // Empty message view
+    private View mEmptyMessage;
+
+    // Buttons container
+    private View mButtonsContainer;
+
     // Callbacks used for the search and favicon cursor loaders
     private CursorLoaderCallbacks mCursorLoaderCallbacks;
 
     // On URL open listener
     private OnUrlOpenListener mUrlOpenListener;
 
     public VisitedPage() {
         mUrlOpenListener = null;
@@ -69,46 +75,66 @@ public class VisitedPage extends HomeFra
     public void onDetach() {
         super.onDetach();
 
         mUrlOpenListener = null;
     }
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        // All list views are styled to look the same with a global activity theme.
-        // If the style of the list changes, inflate it from an XML.
-        mList = new HomeListView(container.getContext());
-        return mList;
+        return inflater.inflate(R.layout.home_visited_page, container, false);
     }
 
     @Override
     public void onViewCreated(View view, Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
 
+        mList = (HomeListView) view.findViewById(R.id.visited_list);
+
         mList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             @Override
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 final Cursor c = mAdapter.getCursor();
                 if (c == null || !c.moveToPosition(position)) {
                     return;
                 }
 
                 final String url = c.getString(c.getColumnIndexOrThrow(URLColumns.URL));
                 mUrlOpenListener.onUrlOpen(url);
             }
         });
 
         registerForContextMenu(mList);
+
+        mEmptyMessage = view.findViewById(R.id.empty_message);
+        mButtonsContainer = view.findViewById(R.id.buttons_container);
+
+        final View historyButton = view.findViewById(R.id.history_button);
+        historyButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showHistoryPage();
+            }
+        });
+
+        final View tabsButton = view.findViewById(R.id.tabs_button);
+        tabsButton.setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showTabsPage();
+            }
+        });
     }
 
     @Override
     public void onDestroyView() {
         super.onDestroyView();
         mList = null;
+        mButtonsContainer = null;
+        mEmptyMessage = null;
     }
 
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
         // Intialize the search adapter
         mAdapter = new VisitedAdapter(getActivity(), null);
@@ -116,16 +142,26 @@ public class VisitedPage extends HomeFra
 
         // Create callbacks before the initial loader is started
         mCursorLoaderCallbacks = new CursorLoaderCallbacks();
 
         // Reconnect to the loader only if present
         getLoaderManager().initLoader(FRECENCY_LOADER_ID, null, mCursorLoaderCallbacks);
     }
 
+    private void showHistoryPage() {
+        final HistoryPage historyPage = HistoryPage.newInstance();
+        showSubPage(historyPage);
+    }
+
+    private void showTabsPage() {
+        final LastTabsPage lastTabsPage = LastTabsPage.newInstance();
+        showSubPage(lastTabsPage);
+    }
+
     private static class FrecencyCursorLoader extends SimpleCursorLoader {
         // Max number of search results
         private static final int SEARCH_LIMIT = 50;
 
         public FrecencyCursorLoader(Context context) {
             super(context);
         }
 
@@ -167,16 +203,23 @@ public class VisitedPage extends HomeFra
             return null;
         }
 
         @Override
         public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
             final int loaderId = loader.getId();
             switch(loaderId) {
             case FRECENCY_LOADER_ID:
+                // Only set empty view once cursor is loaded to avoid
+                // flashing the empty message before loading.
+                mList.setEmptyView(mEmptyMessage);
+
+                final int buttonsVisibility = (c.getCount() == 0 ? View.GONE : View.VISIBLE);
+                mButtonsContainer.setVisibility(buttonsVisibility);
+
                 mAdapter.swapCursor(c);
 
                 FaviconsLoader.restartFromCursor(getLoaderManager(), FAVICONS_LOADER_ID,
                         mCursorLoaderCallbacks, c);
                 break;
 
             case FAVICONS_LOADER_ID:
                 // Causes the listview to recreate its children and use the
--- a/mobile/android/base/locales/en-US/android_strings.dtd
+++ b/mobile/android/base/locales/en-US/android_strings.dtd
@@ -269,16 +269,17 @@ size. -->
 <!ENTITY abouthome_addons_title "Add-ons for your &brandShortName;">
 <!ENTITY abouthome_addons_browse "Browse all &brandShortName; add-ons">
 <!ENTITY abouthome_last_tabs_title "Your tabs from last time">
 <!ENTITY abouthome_last_tabs_open "Open all tabs from last time">
 <!ENTITY abouthome_top_sites_title "Top sites">
 <!ENTITY abouthome_topsites_edit "Edit">
 <!ENTITY abouthome_topsites_pin "Pin Site">
 <!ENTITY abouthome_topsites_unpin "Unpin Site">
+<!ENTITY abouthome_visited_empty "Websites you visited go here">
 
 <!-- Localization note (abouthome_about_sync3, abouthome_about_apps2): The
      chevron (ex: "»"; unicode= U+00BB) is used as an arrow to show that
      clicking this text in the promotions box will perform some action. Note
      that a non-breaking space (unicode= U+00A0) should be used between this
      character and the remainder of the string to prevent word wrap. -->
 <!ENTITY abouthome_about_sync3 "Set up Firefox Sync to access bookmarks, history and tabs from your other devices&#x00A0;»">
 <!ENTITY abouthome_about_apps3 "Get apps from the Firefox Marketplace and discover the best the Web has to offer&#x00A0;»">
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/resources/layout/home_visited_page.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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/. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:orientation="vertical">
+
+    <TextView android:id="@+id/empty_message"
+              style="@style/AboutHome.EmptyMessage"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+              android:text="@string/abouthome_visited_empty"
+              android:visibility="gone"/>
+
+    <org.mozilla.gecko.home.HomeListView
+            android:id="@+id/visited_list"
+            android:layout_width="fill_parent"
+            android:layout_height="fill_parent"
+            android:layout_weight="1"/>
+
+    <LinearLayout android:id="@+id/buttons_container"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+                  android:orientation="vertical"
+                  android:background="@color/background_light"
+                  android:visibility="gone">
+
+        <Button android:id="@+id/history_button"
+                style="@style/AboutHome.PageButton"
+                android:text="@string/history_title"/>
+
+        <View android:layout_width="fill_parent"
+              android:layout_height="1dip"
+              android:background="#FFD1D5DA"/>
+
+        <Button android:id="@+id/tabs_button"
+                style="@style/AboutHome.PageButton"
+                android:text="@string/abouthome_last_tabs_title"/>
+
+    </LinearLayout>
+
+</LinearLayout>
\ No newline at end of file
--- a/mobile/android/base/resources/values/styles.xml
+++ b/mobile/android/base/resources/values/styles.xml
@@ -497,16 +497,35 @@
     </style>
 
     <style name="AboutHome.LastTabRow.Url">
         <item name="android:textSize">12sp</item>
         <item name="android:singleLine">true</item>
         <item name="android:textColor">@color/abouthome_section_subtitle</item>
     </style>
 
+    <style name="AboutHome.EmptyMessage">
+        <item name="android:textAppearance">@style/AboutHome.TextAppearance.PageTitle</item>
+        <item name="android:gravity">center</item>
+        <item name="android:focusable">false</item>
+        <item name="android:paddingLeft">10dip</item>
+        <item name="android:paddingRight">10dip</item>
+    </style>
+
+    <style name="AboutHome.PageButton">
+        <item name="android:layout_width">fill_parent</item>
+        <item name="android:layout_height">40dip</item>
+        <item name="android:textAppearance">@style/AboutHome.TextAppearance.PageTitle</item>
+        <item name="android:background">@drawable/action_bar_button</item>
+        <item name="android:focusable">true</item>
+        <item name="android:gravity">center|left</item>
+        <item name="android:paddingLeft">10dip</item>
+        <item name="android:paddingRight">10dip</item>
+    </style>
+
     <style name="AboutHome.PageTitle">
         <item name="android:layout_width">fill_parent</item>
         <item name="android:layout_height">32dp</item>
         <item name="android:textAppearance">@style/AboutHome.TextAppearance.PageTitle</item>
         <item name="android:background">@color/background_light</item>
         <item name="android:focusable">false</item>
         <item name="android:gravity">center|left</item>
         <item name="android:paddingLeft">10dip</item>
--- a/mobile/android/base/strings.xml.in
+++ b/mobile/android/base/strings.xml.in
@@ -244,16 +244,18 @@
   <string name="abouthome_about_apps">&abouthome_about_apps3;</string>
   <string name="abouthome_sync_bold_name">&abouthome_sync_bold_name;</string>
   <string name="abouthome_apps_bold_name">&abouthome_apps_bold_name2;</string>
   
   <string name="abouthome_topsites_edit">&abouthome_topsites_edit;</string>
   <string name="abouthome_topsites_pin">&abouthome_topsites_pin;</string>
   <string name="abouthome_topsites_unpin">&abouthome_topsites_unpin;</string>
 
+  <string name="abouthome_visited_empty">&abouthome_visited_empty;</string>
+
   <string name="filepicker_title">&filepicker_title;</string>
   <string name="filepicker_audio_title">&filepicker_audio_title;</string>
   <string name="filepicker_image_title">&filepicker_image_title;</string>
   <string name="filepicker_video_title">&filepicker_video_title;</string>
 
   <!-- Default bookmarks. Use bookmarks titles shared with XUL from mobile's
        profile/bookmarks.inc. Don't expose the URLs to L10N. -->
   <string name="bookmarkdefaults_title_aboutfirefox">@bookmarks_aboutBrowser@</string>