Commit 35978862 authored by mvanouwerkerk's avatar mvanouwerkerk Committed by Commit bot

Ntp: show footer with learn more link.

BUG=637257

Review-Url: https://codereview.chromium.org/2275693003
Cr-Commit-Position: refs/heads/master@{#414738}
parent 35a95ad0
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2016 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/snippets_text_color"
android:textSize="12sp"
android:textStyle="italic"
android:padding="12dp"
android:gravity="center" />
...@@ -5,7 +5,6 @@ ...@@ -5,7 +5,6 @@
<TextView <TextView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/suggestions_section_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@color/snippets_list_header_text_color" android:textColor="@color/snippets_list_header_text_color"
......
...@@ -249,6 +249,14 @@ public class NewTabPage ...@@ -249,6 +249,14 @@ public class NewTabPage
} }
} }
@Override
public void onLearnMoreClicked() {
if (mIsDestroyed) return;
// TODO(mvanouwerkerk): UMA logging.
String url = "https://support.google.com/chrome/?p=new_tab";
openUrl(WindowOpenDisposition.CURRENT_TAB, url);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @TargetApi(Build.VERSION_CODES.LOLLIPOP)
private boolean switchToExistingTab(String url) { private boolean switchToExistingTab(String url) {
String matchPattern = CommandLine.getInstance().getSwitchValue( String matchPattern = CommandLine.getInstance().getSwitchValue(
......
...@@ -258,6 +258,11 @@ public class NewTabPageView extends FrameLayout ...@@ -258,6 +258,11 @@ public class NewTabPageView extends FrameLayout
* called whenever a ContextMenu is closed. * called whenever a ContextMenu is closed.
*/ */
void removeContextMenuCloseCallback(Callback<Menu> callback); void removeContextMenuCloseCallback(Callback<Menu> callback);
/**
* Handles clicks on the "learn more" link in the footer.
*/
void onLearnMoreClicked();
} }
/** /**
......
...@@ -210,6 +210,7 @@ public class CardViewHolder extends NewTabPageViewHolder { ...@@ -210,6 +210,7 @@ public class CardViewHolder extends NewTabPageViewHolder {
/** /**
* Override this to provide a context menu for the card. This method will not be called if the * Override this to provide a context menu for the card. This method will not be called if the
* card is currently peeking. * card is currently peeking.
* @param menu The menu to add menu items to.
*/ */
protected void createContextMenu(ContextMenu menu) {} protected void createContextMenu(ContextMenu menu) {}
...@@ -291,6 +292,7 @@ public class CardViewHolder extends NewTabPageViewHolder { ...@@ -291,6 +292,7 @@ public class CardViewHolder extends NewTabPageViewHolder {
case NewTabPageItem.VIEW_TYPE_HEADER: case NewTabPageItem.VIEW_TYPE_HEADER:
case NewTabPageItem.VIEW_TYPE_SPACING: case NewTabPageItem.VIEW_TYPE_SPACING:
case NewTabPageItem.VIEW_TYPE_PROGRESS: case NewTabPageItem.VIEW_TYPE_PROGRESS:
case NewTabPageItem.VIEW_TYPE_FOOTER:
return false; return false;
default: default:
assert false; assert false;
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.ntp.cards;
import android.text.method.LinkMovementMethod;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
import org.chromium.ui.text.NoUnderlineClickableSpan;
import org.chromium.ui.text.SpanApplier;
/**
* A footer to show some text and a link to learn more.
*/
public class Footer extends SingleItemGroup {
@Override
public int getType() {
return NewTabPageItem.VIEW_TYPE_FOOTER;
}
/**
* The {@code ViewHolder} for the {@link Footer}.
*/
public static class ViewHolder extends NewTabPageViewHolder {
public ViewHolder(ViewGroup root, final NewTabPageManager manager) {
super(LayoutInflater.from(root.getContext())
.inflate(R.layout.new_tab_page_footer, root, false));
NoUnderlineClickableSpan link = new NoUnderlineClickableSpan() {
@Override
public void onClick(View view) {
// TODO(mvanouwerkerk): Ensure this can be activated when using TalkBack.
manager.onLearnMoreClicked();
}
};
TextView textView = (TextView) itemView;
textView.setText(SpanApplier.applySpans(
root.getResources().getString(R.string.ntp_learn_more_about_suggested_content),
new SpanApplier.SpanInfo("<link>", "</link>", link)));
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
...@@ -59,6 +59,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> ...@@ -59,6 +59,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder>
*/ */
private final List<ItemGroup> mGroups = new ArrayList<>(); private final List<ItemGroup> mGroups = new ArrayList<>();
private final AboveTheFoldItem mAboveTheFold = new AboveTheFoldItem(); private final AboveTheFoldItem mAboveTheFold = new AboveTheFoldItem();
private final Footer mFooter = new Footer();
private final SpacingItem mBottomSpacer = new SpacingItem(); private final SpacingItem mBottomSpacer = new SpacingItem();
/** Maps suggestion categories to sections, with stable iteration ordering. */ /** Maps suggestion categories to sections, with stable iteration ordering. */
...@@ -266,6 +267,10 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> ...@@ -266,6 +267,10 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder>
return new ActionItem.ViewHolder(mRecyclerView, mNewTabPageManager, mUiConfig); return new ActionItem.ViewHolder(mRecyclerView, mNewTabPageManager, mUiConfig);
} }
if (viewType == NewTabPageItem.VIEW_TYPE_FOOTER) {
return new Footer.ViewHolder(mRecyclerView, mNewTabPageManager);
}
return null; return null;
} }
...@@ -299,10 +304,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> ...@@ -299,10 +304,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder>
} }
public int getLastContentItemPosition() { public int getLastContentItemPosition() {
// TODO(mvanouwerkerk): Don't rely on getBottomSpacerPosition() here. return getGroupPositionOffset(mFooter);
int bottomSpacerPosition = getBottomSpacerPosition();
if (bottomSpacerPosition == RecyclerView.NO_POSITION) return RecyclerView.NO_POSITION;
return bottomSpacerPosition - 1;
} }
public int getBottomSpacerPosition() { public int getBottomSpacerPosition() {
...@@ -336,6 +338,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> ...@@ -336,6 +338,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder>
// TODO(treib,bauerb): Preserve the order of categories we got from getCategories. // TODO(treib,bauerb): Preserve the order of categories we got from getCategories.
mGroups.addAll(mSections.values()); mGroups.addAll(mSections.values());
if (!mSections.isEmpty()) { if (!mSections.isEmpty()) {
mGroups.add(mFooter);
mGroups.add(mBottomSpacer); mGroups.add(mBottomSpacer);
} }
......
...@@ -64,6 +64,12 @@ public interface NewTabPageItem { ...@@ -64,6 +64,12 @@ public interface NewTabPageItem {
*/ */
public static final int VIEW_TYPE_ACTION = 7; public static final int VIEW_TYPE_ACTION = 7;
/**
* View type for a {@link Footer}.
* @see Adapter#getItemViewType(int)
*/
public static final int VIEW_TYPE_FOOTER = 8;
/** /**
* Returns the type ({@link ViewType}) of this list item. This is so we can * Returns the type ({@link ViewType}) of this list item. This is so we can
* distinguish between different elements that are held in a single RecyclerView holder. * distinguish between different elements that are held in a single RecyclerView holder.
......
...@@ -246,7 +246,7 @@ public class NewTabPageRecyclerView extends RecyclerView { ...@@ -246,7 +246,7 @@ public class NewTabPageRecyclerView extends RecyclerView {
/** /**
* Finds the view holder for the first header. * Finds the view holder for the first header.
* @return The {@link ViewHolder} of the header, or null if it is not present. * @return The {@code ViewHolder} of the header, or null if it is not present.
*/ */
private SectionHeaderViewHolder findFirstHeader() { private SectionHeaderViewHolder findFirstHeader() {
ViewHolder viewHolder = ViewHolder viewHolder =
...@@ -258,7 +258,7 @@ public class NewTabPageRecyclerView extends RecyclerView { ...@@ -258,7 +258,7 @@ public class NewTabPageRecyclerView extends RecyclerView {
/** /**
* Finds the view holder for the first card. * Finds the view holder for the first card.
* @return The {@link ViewHolder} for the first card, or null if it is not present. * @return The {@code ViewHolder} for the first card, or null if it is not present.
*/ */
private CardViewHolder findFirstCard() { private CardViewHolder findFirstCard() {
ViewHolder viewHolder = ViewHolder viewHolder =
...@@ -269,21 +269,20 @@ public class NewTabPageRecyclerView extends RecyclerView { ...@@ -269,21 +269,20 @@ public class NewTabPageRecyclerView extends RecyclerView {
} }
/** /**
* Finds the view holder for the last content item: a card or status indicator. * Finds the view holder for the last content item: the footer.
* @return The {@link ViewHolder} of the last content item, or null if it is not present. * @return The {@code ViewHolder} of the last content item, or null if it is not present.
*/ */
private ViewHolder findLastContentItem() { private ViewHolder findLastContentItem() {
ViewHolder viewHolder = findViewHolderForAdapterPosition( ViewHolder viewHolder = findViewHolderForAdapterPosition(
getNewTabPageAdapter().getLastContentItemPosition()); getNewTabPageAdapter().getLastContentItemPosition());
if (viewHolder instanceof CardViewHolder) return viewHolder; if (viewHolder instanceof Footer.ViewHolder) return viewHolder;
if (viewHolder instanceof ProgressViewHolder) return viewHolder;
return null; return null;
} }
/** /**
* Finds the view holder for the bottom spacer. * Finds the view holder for the bottom spacer.
* @return The {@link ViewHolder} of the bottom spacer, or null if it is not present. * @return The {@code ViewHolder} of the bottom spacer, or null if it is not present.
*/ */
private ViewHolder findBottomSpacer() { private ViewHolder findBottomSpacer() {
return findViewHolderForAdapterPosition(getNewTabPageAdapter().getBottomSpacerPosition()); return findViewHolderForAdapterPosition(getNewTabPageAdapter().getBottomSpacerPosition());
......
...@@ -23,7 +23,6 @@ public class SectionHeaderViewHolder extends NewTabPageViewHolder { ...@@ -23,7 +23,6 @@ public class SectionHeaderViewHolder extends NewTabPageViewHolder {
private final int mMaxSnippetHeaderHeight; private final int mMaxSnippetHeaderHeight;
private final int mMaxPeekPadding; private final int mMaxPeekPadding;
private final TextView mHeaderTextView;
private final NewTabPageRecyclerView mRecyclerView; private final NewTabPageRecyclerView mRecyclerView;
private SectionHeader mHeaderListItem; private SectionHeader mHeaderListItem;
...@@ -37,7 +36,6 @@ public class SectionHeaderViewHolder extends NewTabPageViewHolder { ...@@ -37,7 +36,6 @@ public class SectionHeaderViewHolder extends NewTabPageViewHolder {
mMaxPeekPadding = itemView.getResources().getDimensionPixelSize( mMaxPeekPadding = itemView.getResources().getDimensionPixelSize(
R.dimen.snippets_padding_and_peeking_card_height); R.dimen.snippets_padding_and_peeking_card_height);
mHeaderTextView = (TextView) itemView.findViewById(R.id.suggestions_section_header);
mRecyclerView = recyclerView; mRecyclerView = recyclerView;
MarginResizer.createWithViewAdapter(itemView, config); MarginResizer.createWithViewAdapter(itemView, config);
} }
...@@ -45,7 +43,7 @@ public class SectionHeaderViewHolder extends NewTabPageViewHolder { ...@@ -45,7 +43,7 @@ public class SectionHeaderViewHolder extends NewTabPageViewHolder {
@Override @Override
public void onBindViewHolder(NewTabPageItem header) { public void onBindViewHolder(NewTabPageItem header) {
mHeaderListItem = (SectionHeader) header; mHeaderListItem = (SectionHeader) header;
mHeaderTextView.setText(mHeaderListItem.getHeaderText()); ((TextView) itemView).setText(mHeaderListItem.getHeaderText());
updateDisplay(0, false); updateDisplay(0, false);
} }
......
...@@ -1979,6 +1979,9 @@ To obtain new licenses, connect to the internet and play your downloaded content ...@@ -1979,6 +1979,9 @@ To obtain new licenses, connect to the internet and play your downloaded content
<message name="IDS_ACCESSIBILITY_NTP_OFFLINE_BADGE" desc="Content description for the badge that indicates offline availability of a most visited item on the new tab page."> <message name="IDS_ACCESSIBILITY_NTP_OFFLINE_BADGE" desc="Content description for the badge that indicates offline availability of a most visited item on the new tab page.">
Available offline Available offline
</message> </message>
<message name="IDS_NTP_LEARN_MORE_ABOUT_SUGGESTED_CONTENT" desc="Text in the footer of the New Tab Page. Part of the text is a link to a help center page where the user can learn more about suggested content.">
<ph name="BEGIN_LINK">&lt;link&gt;</ph>Learn more<ph name="END_LINK">&lt;/link&gt;</ph> about suggested content
</message>
<!-- Toolbar button strings --> <!-- Toolbar button strings -->
<message name="IDS_OPEN_TABS" desc="Text for button to enter the tab switcher and show tabs that are open on this device"> <message name="IDS_OPEN_TABS" desc="Text for button to enter the tab switcher and show tabs that are open on this device">
......
...@@ -546,6 +546,7 @@ chrome_java_sources = [ ...@@ -546,6 +546,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java", "java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java",
"java/src/org/chromium/chrome/browser/ntp/cards/DisplayStyleObserverAdapter.java", "java/src/org/chromium/chrome/browser/ntp/cards/DisplayStyleObserverAdapter.java",
"java/src/org/chromium/chrome/browser/ntp/cards/ItemGroup.java", "java/src/org/chromium/chrome/browser/ntp/cards/ItemGroup.java",
"java/src/org/chromium/chrome/browser/ntp/cards/Footer.java",
"java/src/org/chromium/chrome/browser/ntp/cards/MarginResizer.java", "java/src/org/chromium/chrome/browser/ntp/cards/MarginResizer.java",
"java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java", "java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java",
"java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageItem.java", "java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageItem.java",
......
...@@ -332,5 +332,10 @@ public class ArticleSnippetsTest extends ChromeActivityTestCaseBase<ChromeActivi ...@@ -332,5 +332,10 @@ public class ArticleSnippetsTest extends ChromeActivityTestCaseBase<ChromeActivi
public void removeContextMenuCloseCallback(Callback<Menu> callback) { public void removeContextMenuCloseCallback(Callback<Menu> callback) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public void onLearnMoreClicked() {
throw new UnsupportedOperationException();
}
} }
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment