Commit 2c5b6347 authored by Cathy Li's avatar Cathy Li Committed by Commit Bot

[ExploreSites]: Connect all explore sites components together.

Does not load images yet. Also looks very ugly.

Bug: 867488
Change-Id: I9acf386718bdd5aefdd1f87f0b31210fc61a102b
Reviewed-on: https://chromium-review.googlesource.com/1242295
Commit-Queue: Cathy Li <chili@chromium.org>
Reviewed-by: default avatarJustin DeWitt <dewittj@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594528}
parent d6151869
......@@ -7,20 +7,22 @@
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" >
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal" >
<TextView
android:id="@+id/category_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:lines="1"
android:textAppearance="@style/BlackTitle1" />
<GridLayout
android:id="@+id/category_sites"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:columnCount="4"
android:rowCount="2" />
......
......@@ -3,15 +3,11 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<org.chromium.chrome.browser.explore_sites.ExploreSitesPageLayout
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/explore_sites_category_recycler"
android:scrollbars="vertical"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.RecyclerView
android:id="@+id/explore_sites_category_recycler"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</org.chromium.chrome.browser.explore_sites.ExploreSitesPageLayout>
android:layout_height="match_parent" />
......@@ -10,11 +10,13 @@ import android.support.v7.widget.RecyclerView;
import android.widget.TextView;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.modelutil.ListObservableImpl;
import org.chromium.chrome.browser.modelutil.ForwardingListObservable;
import org.chromium.chrome.browser.modelutil.PropertyKey;
import org.chromium.chrome.browser.modelutil.PropertyModel;
import org.chromium.chrome.browser.modelutil.PropertyObservable;
import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter;
import org.chromium.chrome.browser.native_page.ContextMenuManager;
import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate;
import org.chromium.chrome.browser.widget.RoundedIconGenerator;
import java.lang.annotation.Retention;
......@@ -23,10 +25,9 @@ import java.lang.annotation.RetentionPolicy;
/**
* Recycler view adapter delegate for a model containing a list of category cards and an error code.
*/
public class ExploreSitesCategoryCardAdapter extends ListObservableImpl<ExploreSitesCategory>
implements RecyclerViewAdapter.Delegate<
ExploreSitesCategoryCardViewHolderFactory.CategoryCardViewHolder,
ExploreSitesCategory>,
class CategoryCardAdapter extends ForwardingListObservable<Void>
implements RecyclerViewAdapter
.Delegate<CategoryCardViewHolderFactory.CategoryCardViewHolder, Void>,
PropertyObservable.PropertyObserver<PropertyKey> {
@IntDef({ViewType.HEADER, ViewType.CATEGORY, ViewType.LOADING, ViewType.ERROR})
@Retention(RetentionPolicy.SOURCE)
......@@ -37,15 +38,24 @@ public class ExploreSitesCategoryCardAdapter extends ListObservableImpl<ExploreS
int ERROR = 3;
}
private final RoundedIconGenerator mIconGenerator;
private final ContextMenuManager mContextMenuManager;
private final NativePageNavigationDelegate mNavDelegate;
private RecyclerView.LayoutManager mLayoutManager;
private PropertyModel mCategoryModel;
private RoundedIconGenerator mIconGenerator;
public ExploreSitesCategoryCardAdapter(PropertyModel model,
RecyclerView.LayoutManager layoutManager, RoundedIconGenerator iconGenerator) {
model.addObserver(this);
public CategoryCardAdapter(PropertyModel model, RecyclerView.LayoutManager layoutManager,
RoundedIconGenerator iconGenerator, ContextMenuManager contextMenuManager,
NativePageNavigationDelegate navDelegate) {
mCategoryModel = model;
mCategoryModel.addObserver(this);
mCategoryModel.get(ExploreSitesPage.CATEGORY_LIST_KEY).addObserver(this);
mLayoutManager = layoutManager;
mIconGenerator = iconGenerator;
mContextMenuManager = contextMenuManager;
mNavDelegate = navDelegate;
}
@Override
......@@ -75,9 +85,8 @@ public class ExploreSitesCategoryCardAdapter extends ListObservableImpl<ExploreS
}
@Override
public void onBindViewHolder(
ExploreSitesCategoryCardViewHolderFactory.CategoryCardViewHolder holder, int position,
@Nullable ExploreSitesCategory payload) {
public void onBindViewHolder(CategoryCardViewHolderFactory.CategoryCardViewHolder holder,
int position, @Nullable Void payload) {
if (holder.getItemViewType() == ViewType.HEADER) {
TextView view = (TextView) holder.itemView;
view.setText(R.string.explore_sites_title);
......@@ -87,10 +96,10 @@ public class ExploreSitesCategoryCardAdapter extends ListObservableImpl<ExploreS
// Populate loading view
} else {
ExploreSitesCategoryCardView view = (ExploreSitesCategoryCardView) holder.itemView;
view.setIconGenerator(mIconGenerator);
// Position - 1 because there is always title.
view.initialize(
mCategoryModel.get(ExploreSitesPage.CATEGORY_LIST_KEY).get(position - 1));
view.setCategory(
mCategoryModel.get(ExploreSitesPage.CATEGORY_LIST_KEY).get(position - 1),
mIconGenerator, mContextMenuManager, mNavDelegate);
}
}
......@@ -106,7 +115,7 @@ public class ExploreSitesCategoryCardAdapter extends ListObservableImpl<ExploreS
}
if (key == ExploreSitesPage.SCROLL_TO_CATEGORY_KEY) {
int pos = mCategoryModel.get(ExploreSitesPage.SCROLL_TO_CATEGORY_KEY);
mLayoutManager.scrollToPosition(pos + 1);
mLayoutManager.scrollToPosition(pos);
}
}
}
......@@ -14,9 +14,8 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter;
/** Factory to create CategoryCardViewHolder objects. */
public class ExploreSitesCategoryCardViewHolderFactory
implements RecyclerViewAdapter.ViewHolderFactory<
ExploreSitesCategoryCardViewHolderFactory.CategoryCardViewHolder> {
class CategoryCardViewHolderFactory implements RecyclerViewAdapter.ViewHolderFactory<
CategoryCardViewHolderFactory.CategoryCardViewHolder> {
/** View holder for the recycler view. */
public static class CategoryCardViewHolder extends RecyclerView.ViewHolder {
public CategoryCardViewHolder(View view) {
......@@ -26,19 +25,20 @@ public class ExploreSitesCategoryCardViewHolderFactory
@Override
public CategoryCardViewHolder createViewHolder(
ViewGroup parent, @ExploreSitesCategoryCardAdapter.ViewType int viewType) {
ViewGroup parent, @CategoryCardAdapter.ViewType int viewType) {
View view;
switch (viewType) {
case ExploreSitesCategoryCardAdapter.ViewType.HEADER:
case CategoryCardAdapter.ViewType.HEADER:
TextView titleView = new TextView(parent.getContext());
view = new TextView(parent.getContext());
break;
case ExploreSitesCategoryCardAdapter.ViewType.CATEGORY:
case CategoryCardAdapter.ViewType.CATEGORY:
view = (ExploreSitesCategoryCardView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.explore_sites_category_card_view, parent);
.inflate(R.layout.explore_sites_category_card_view, null);
break;
case ExploreSitesCategoryCardAdapter.ViewType.LOADING: // inflate loading spinny
case ExploreSitesCategoryCardAdapter.ViewType.ERROR: // inflate error
view = null;
case CategoryCardAdapter.ViewType.LOADING: // inflate loading spinny
case CategoryCardAdapter.ViewType.ERROR: // inflate error
view = new TextView(parent.getContext()); // dummy view.
break;
default:
assert false;
......
......@@ -6,13 +6,22 @@ package org.chromium.chrome.browser.explore_sites;
import android.content.Context;
import android.util.AttributeSet;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.widget.GridLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.native_page.ContextMenuManager;
import org.chromium.chrome.browser.native_page.NativePageNavigationDelegate;
import org.chromium.chrome.browser.widget.RoundedIconGenerator;
import org.chromium.content_public.browser.LoadUrlParams;
import org.chromium.ui.base.PageTransition;
import org.chromium.ui.mojom.WindowOpenDisposition;
import java.util.List;
......@@ -23,6 +32,53 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
private TextView mTitleView;
private GridLayout mTileView;
private RoundedIconGenerator mIconGenerator;
private ContextMenuManager mContextMenuManager;
private NativePageNavigationDelegate mNavigationDelegate;
private class CategoryCardInteractionDelegate
implements ContextMenuManager.Delegate, OnClickListener, OnCreateContextMenuListener {
private ExploreSitesSite mSite;
public CategoryCardInteractionDelegate(ExploreSitesSite site) {
mSite = site;
}
@Override
public void onClick(View view) {
mNavigationDelegate.openUrl(WindowOpenDisposition.CURRENT_TAB,
new LoadUrlParams(getUrl(), PageTransition.AUTO_BOOKMARK));
}
@Override
public void onCreateContextMenu(
ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
mContextMenuManager.createContextMenu(menu, v, this);
}
@Override
public void openItem(int windowDisposition) {
mNavigationDelegate.openUrl(
windowDisposition, new LoadUrlParams(getUrl(), PageTransition.AUTO_BOOKMARK));
}
@Override
public void removeItem() {} // TODO(chili): Add removal method.
@Override
public String getUrl() {
return mSite.getUrl();
}
@Override
public boolean isItemSupported(@ContextMenuManager.ContextMenuItemId int menuItemId) {
if (menuItemId == ContextMenuManager.ContextMenuItemId.LEARN_MORE) {
return false;
}
return true;
}
@Override
public void onContextMenuCreated(){};
}
public ExploreSitesCategoryCardView(Context context, AttributeSet attrs) {
super(context, attrs);
......@@ -35,11 +91,13 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
mTileView = findViewById(R.id.category_sites);
}
public void setIconGenerator(RoundedIconGenerator iconGenerator) {
public void setCategory(ExploreSitesCategory category, RoundedIconGenerator iconGenerator,
ContextMenuManager contextMenuManager,
NativePageNavigationDelegate navigationDelegate) {
mIconGenerator = iconGenerator;
}
mContextMenuManager = contextMenuManager;
mNavigationDelegate = navigationDelegate;
public void initialize(ExploreSitesCategory category) {
updateTitle(category.getTitle());
updateTileViews(category.getSites());
}
......@@ -57,14 +115,19 @@ public class ExploreSitesCategoryCardView extends LinearLayout {
if (mTileView.getChildCount() < sites.size()) {
for (int i = mTileView.getChildCount(); i < sites.size(); i++) {
mTileView.addView(LayoutInflater.from(getContext())
.inflate(R.layout.explore_sites_tile_view, mTileView));
.inflate(R.layout.explore_sites_tile_view, null));
}
}
// Initialize all the tiles again to update.
for (int i = 0; i < sites.size(); i++) {
ExploreSitesTileView tileView = (ExploreSitesTileView) mTileView.getChildAt(i);
tileView.setIconGenerator(mIconGenerator);
tileView.initialize(sites.get(i));
final ExploreSitesSite site = sites.get(i);
tileView.initialize(site, mIconGenerator);
CategoryCardInteractionDelegate interactionDelegate =
new CategoryCardInteractionDelegate(site);
tileView.setOnClickListener(interactionDelegate);
tileView.setOnCreateContextMenuListener(interactionDelegate);
}
}
}
......@@ -4,11 +4,11 @@
package org.chromium.chrome.browser.explore_sites;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
......@@ -18,19 +18,26 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.UrlConstants;
import org.chromium.chrome.browser.modelutil.ListModel;
import org.chromium.chrome.browser.modelutil.PropertyModel;
import org.chromium.chrome.browser.modelutil.RecyclerViewAdapter;
import org.chromium.chrome.browser.native_page.BasicNativePage;
import org.chromium.chrome.browser.native_page.ContextMenuManager;
import org.chromium.chrome.browser.native_page.NativePageHost;
import org.chromium.chrome.browser.native_page.NativePageNavigationDelegateImpl;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.tabmodel.TabModelSelector;
import org.chromium.chrome.browser.widget.RoundedIconGenerator;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
/**
* Provides functionality when the user interacts with the explore sites page.
*/
public class ExploreSitesPage extends BasicNativePage {
private static final String CONTEXT_MENU_USER_ACTION_PREFIX = "ExploreSites";
static final PropertyModel.WritableIntPropertyKey STATUS_KEY =
new PropertyModel.WritableIntPropertyKey();
static final PropertyModel.WritableIntPropertyKey SCROLL_TO_CATEGORY_KEY =
......@@ -47,30 +54,36 @@ public class ExploreSitesPage extends BasicNativePage {
int ERROR = 3;
}
private final TabModelSelector mTabModelSelector;
private NativePageHost mHost;
private ViewGroup mView;
private String mTitle;
private Activity mActivity;
private ExploreSitesPageLayout mLayout;
private PropertyModel mModel;
private CategoryCardAdapter mAdapter;
private ContextMenuManager mContextMenuManager;
private String mNavFragment;
/**
* Create a new instance of the explore sites page.
*/
public ExploreSitesPage(ChromeActivity activity, NativePageHost host) {
super(activity, host);
mTabModelSelector = activity.getTabModelSelector();
}
@Override
protected void initialize(ChromeActivity activity, NativePageHost host) {
mActivity = activity;
mTitle = mActivity.getString(R.string.explore_sites_title);
mView = (ViewGroup) mActivity.getLayoutInflater().inflate(
protected void initialize(ChromeActivity activity, final NativePageHost host) {
mHost = host;
mTitle = activity.getString(R.string.explore_sites_title);
mView = (ViewGroup) activity.getLayoutInflater().inflate(
R.layout.explore_sites_page_layout, null);
mModel = new PropertyModel.Builder(STATUS_KEY, SCROLL_TO_CATEGORY_KEY, CATEGORY_LIST_KEY)
.with(CATEGORY_LIST_KEY, new ListModel<ExploreSitesCategory>())
.with(SCROLL_TO_CATEGORY_KEY, 0)
.with(STATUS_KEY, CatalogLoadingState.LOADING)
.build();
Context context = mView.getContext();
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
int iconSizePx = context.getResources().getDimensionPixelSize(R.dimen.tile_view_icon_size);
......@@ -80,18 +93,43 @@ public class ExploreSitesPage extends BasicNativePage {
context.getResources(), R.color.default_favicon_background_color),
context.getResources().getDimensionPixelSize(R.dimen.headline_size_medium));
ExploreSitesCategoryCardAdapter adapterDelegate =
new ExploreSitesCategoryCardAdapter(mModel, layoutManager, iconGenerator);
Profile profile = host.getActiveTab().getProfile();
NativePageNavigationDelegateImpl navDelegate =
new NativePageNavigationDelegateImpl(activity, profile, host, mTabModelSelector);
// Don't direct reference activity because it might change if tab is reparented.
Runnable closeContextMenuCallback =
() -> host.getActiveTab().getActivity().closeContextMenu();
mContextMenuManager = new ContextMenuManager(navDelegate, this ::setTouchEnabled,
closeContextMenuCallback, CONTEXT_MENU_USER_ACTION_PREFIX);
host.getActiveTab().getWindowAndroid().addContextMenuCloseListener(mContextMenuManager);
CategoryCardAdapter adapterDelegate = new CategoryCardAdapter(
mModel, layoutManager, iconGenerator, mContextMenuManager, navDelegate);
RecyclerView recyclerView =
(RecyclerView) mView.findViewById(R.id.explore_sites_category_recycler);
RecyclerViewAdapter<CategoryCardViewHolderFactory.CategoryCardViewHolder, Void> adapter =
new RecyclerViewAdapter<>(adapterDelegate, new CategoryCardViewHolderFactory());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
ExploreSitesBridge.getEspCatalog(profile, this::translateToModel);
mModel.set(STATUS_KEY, CatalogLoadingState.LOADING);
// TODO(chili): Set layout to be an observer of list model
}
private void translateToModel(@Nullable List<ExploreSitesCategory> categoryList) {
if (categoryList == null) {
mModel.set(STATUS_KEY, CatalogLoadingState.ERROR);
return;
}
mModel.set(STATUS_KEY, CatalogLoadingState.SUCCESS);
ListModel<ExploreSitesCategory> categoryListModel = mModel.get(CATEGORY_LIST_KEY);
categoryListModel.set(categoryList);
if (mNavFragment != null) {
lookupCategoryAndScroll(mNavFragment);
}
}
@Override
......@@ -108,4 +146,45 @@ public class ExploreSitesPage extends BasicNativePage {
public String getTitle() {
return mTitle;
}
@Override
public void updateForUrl(String url) {
super.updateForUrl(url);
String fragment;
try {
fragment = new URI(url).getFragment();
} catch (URISyntaxException e) {
fragment = "";
}
if (mModel.get(STATUS_KEY) == CatalogLoadingState.LOADING) {
mNavFragment = fragment;
} else {
lookupCategoryAndScroll(fragment);
}
}
@Override
public void destroy() {
mHost.getActiveTab().getWindowAndroid().removeContextMenuCloseListener(mContextMenuManager);
super.destroy();
}
private void setTouchEnabled(boolean enabled) {} // Does nothing.
private void lookupCategoryAndScroll(String categoryId) {
int position = 0;
try {
int id = Integer.parseInt(categoryId);
ListModel<ExploreSitesCategory> categoryList = mModel.get(CATEGORY_LIST_KEY);
for (int i = 0; i < categoryList.size(); i++) {
if (categoryList.get(i).getId() == id) {
position = i;
break;
}
}
} catch (NumberFormatException e) {
} // do nothing
mModel.set(SCROLL_TO_CATEGORY_KEY, position);
mNavFragment = null;
}
}
......@@ -29,7 +29,8 @@ public class ExploreSitesTileView extends TileWithTextView {
mIconSizePx = getResources().getDimensionPixelSize(R.dimen.tile_view_icon_size);
}
public void initialize(ExploreSitesSite site) {
public void initialize(ExploreSitesSite site, RoundedIconGenerator generator) {
mIconGenerator = generator;
super.initialize(site.getTitle(), /* showOfflineBadge = */ false,
getDrawableForBitmap(site.getIcon(), site.getTitle()), TITLE_LINES);
}
......@@ -44,12 +45,4 @@ public class ExploreSitesTileView extends TileWithTextView {
}
return ViewUtils.createRoundedBitmapDrawable(image, mIconSizePx / 2);
}
/**
* Sets icon generator. This is to help prevent an instance of icon generator
* being created for each tile.
*/
void setIconGenerator(RoundedIconGenerator generator) {
mIconGenerator = generator;
}
}
......@@ -563,15 +563,15 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/download/ui/OfflineGroupHeaderView.java",
"java/src/org/chromium/chrome/browser/download/ui/SpaceDisplay.java",
"java/src/org/chromium/chrome/browser/engagement/SiteEngagementService.java",
"java/src/org/chromium/chrome/browser/explore_sites/CategoryCardAdapter.java",
"java/src/org/chromium/chrome/browser/explore_sites/CategoryCardViewHolderFactory.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesCategoryTileView.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExperimentalExploreSitesSection.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBackgroundTask.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridge.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesBridgeExperimental.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategory.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardAdapter.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardView.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryCardViewHolderFactory.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTile.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesCategoryTileView.java",
"java/src/org/chromium/chrome/browser/explore_sites/ExploreSitesPage.java",
......
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