Commit be3ce453 authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Content indexing : Added card UI

This CL adds the UI for showing content indexed content.
1- Renames PrefetchViewHolder to PrefetchArticleViewHolder (and the XML files)
2- Adds separate view holders for prefetch grouped item, card header,
  card footer, and prefetch audio
3- Favicon will be added in a followup CL

Bug: 1030924
Change-Id: Ie95f8c1340423218652964b126d9bb09ac6237cb
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1929869
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#721837}
parent 5bddaead
......@@ -565,6 +565,12 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/download/home/list/ListUtils.java",
"java/src/org/chromium/chrome/browser/download/home/list/ShareUtils.java",
"java/src/org/chromium/chrome/browser/download/home/list/UiUtils.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/AudioViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/CardDividerTopViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/CardDividerMiddleViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/CardDividerBottomViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/CardFooterViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/CardHeaderViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/CustomViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/GenericViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/ImageViewHolder.java",
......@@ -575,7 +581,8 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/download/home/list/holder/ListItemViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/OfflineItemViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/PaginationViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/PrefetchViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/PrefetchArticleViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/PrefetchGroupedItemViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/SectionTitleViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/holder/VideoViewHolder.java",
"java/src/org/chromium/chrome/browser/download/home/list/mutator/CardPaginator.java",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="-2dp">
<shape
android:shape="rectangle" >
<solid android:color="@color/modern_primary_color" />
<stroke android:width="1dp" android:color="@color/hairline_stroke_color"/>
<corners android:bottomLeftRadius="@dimen/default_rounded_corner_radius" android:bottomRightRadius="@dimen/default_rounded_corner_radius" />
</shape>
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:bottom="-2dp">
<shape
android:shape="rectangle" >
<solid android:color="@color/modern_primary_color" />
<stroke android:width="1dp" android:color="@color/hairline_stroke_color"/>
<corners android:topLeftRadius="@dimen/default_rounded_corner_radius" android:topRightRadius="@dimen/default_rounded_corner_radius" />
</shape>
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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. -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="-2dp" android:bottom="-2dp">
<shape
android:shape="rectangle" >
<solid android:color="@color/modern_primary_color" />
<stroke android:width="1dp" android:color="@color/hairline_stroke_color"/>
</shape>
</item>
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="114dp"
android:background="@drawable/hairline_border_card_background">
<org.chromium.chrome.browser.download.home.list.view.AsyncImageView
android:id="@+id/thumbnail"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="16dp"
android:layout_marginStart="16dp"
android:scaleType="centerCrop"
app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
app:cornerRadiusBottomStart="@dimen/download_manager_thumbnail_corner_radius"
app:cornerRadiusBottomEnd="@dimen/download_manager_thumbnail_corner_radius"
style="@style/AsyncImageView"
tools:ignore="ContentDescription" />
<org.chromium.ui.widget.ChromeImageButton
android:id="@+id/action_button"
android:elevation="2dp"
android:clickable="false"
android:layout_marginTop="35dp"
android:layout_marginStart="35dp"
style="@style/SmallMediaPlayButton"/>
<include layout="@layout/list_menu_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_alignTop="@id/thumbnail"
android:layout_alignParentEnd="true"
android:paddingTop="12dp" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/thumbnail"
android:layout_toStartOf="@+id/more"
android:layout_marginStart="16dp"
android:layout_alignTop="@id/thumbnail"
android:minHeight="40dp"
android:maxLines="2"
android:ellipsize="end"
android:textAppearance="@style/TextAppearance.BlackTitle1"
android:textAlignment="viewStart"
app:layout_gravity="fill_horizontal" />
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/thumbnail"
android:layout_alignBottom="@id/thumbnail"
android:layout_marginStart="16dp"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/TextAppearance.BlackCaption"
android:textAlignment="viewStart" />
<TextView
android:id="@+id/caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/thumbnail"
android:layout_above="@id/timestamp"
android:layout_marginStart="16dp"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/TextAppearance.BlackCaption"
android:textAlignment="viewStart" />
<!-- Wrap this in a FrameLayout so that if the thumbnail is hidden this view
does not negatively affect layout. The FrameLayout spans the whole
parent so it will not impact the rest of the views. -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_gravity="fill">
<org.chromium.chrome.browser.download.home.view.SelectionView
android:id="@+id/selection"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="24dp"
android:layout_marginStart="24dp"/>
</FrameLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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.
-->
<View
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/bottom_divider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="16dp"
tools:ignore="ContentDescription"
android:background="@drawable/group_card_footer_curved_border"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/middle_divider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="33dp"
android:background="@drawable/group_card_item_border">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_centerVertical="true"
tools:ignore="ContentDescription"
android:background="@color/hairline_stroke_color"/>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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.
-->
<View
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/top_divider"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="16dp"
tools:ignore="ContentDescription"
android:background="@drawable/group_card_header_curved_border"/>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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:id="@+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/group_card_item_border"
android:gravity="center_vertical|start"
android:clickable="true"
style="@style/PaginationHeaderText"
android:text="@string/download_manager_ui_pagination" />
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/group_card_item_border"
android:paddingStart="@dimen/card_padding"
android:paddingEnd="@dimen/card_padding"
android:paddingBottom="@dimen/card_padding">
<org.chromium.ui.widget.ChromeImageButton
android:id="@+id/favicon"
android:layout_width="16dp"
android:layout_height="16dp"
android:src="@drawable/ic_globe_24dp"
android:importantForAccessibility="no"/>
<TextView
android:id="@+id/domain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/favicon"
android:gravity="center_vertical"
android:layout_marginStart="12dp"
android:textAppearance="@style/TextAppearance.BlackCaption" />
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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.
-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/card"
android:layout_width="match_parent"
android:layout_height="114dp"
android:background="@drawable/group_card_item_border"
android:paddingStart="@dimen/card_padding">
<org.chromium.chrome.browser.download.home.list.view.AsyncImageView
android:id="@+id/thumbnail"
android:layout_width="80dp"
android:layout_height="80dp"
android:scaleType="centerCrop"
app:cornerRadiusTopStart="@dimen/download_manager_thumbnail_corner_radius"
app:cornerRadiusTopEnd="@dimen/download_manager_thumbnail_corner_radius"
app:cornerRadiusBottomStart="@dimen/download_manager_thumbnail_corner_radius"
app:cornerRadiusBottomEnd="@dimen/download_manager_thumbnail_corner_radius"
style="@style/AsyncImageView"
tools:ignore="ContentDescription" />
<org.chromium.ui.widget.ChromeImageButton
android:id="@+id/media_button"
android:elevation="2dp"
android:clickable="false"
android:layout_marginTop="20dp"
android:layout_marginStart="20dp"
style="@style/SmallMediaPlayButton"/>
<include layout="@layout/list_menu_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="-12dp"
android:layout_alignParentEnd="true" />
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/thumbnail"
android:layout_toStartOf="@+id/more"
android:layout_marginStart="16dp"
android:layout_alignTop="@id/thumbnail"
android:maxLines="3"
android:ellipsize="end"
android:textAppearance="@style/TextAppearance.BlackBodyDefault"
android:textAlignment="viewStart"
app:layout_gravity="fill_horizontal" />
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_alignStart="@id/title"
android:layout_marginTop="16dp"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/TextAppearance.BlackCaption"
android:textAlignment="viewStart" />
<!-- Wrap this in a FrameLayout so that if the thumbnail is hidden this view
does not negatively affect layout. The FrameLayout spans the whole
parent so it will not impact the rest of the views. -->
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_gravity="fill">
<org.chromium.chrome.browser.download.home.view.SelectionView
android:id="@+id/selection"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="8dp"
android:layout_marginStart="8dp"/>
</FrameLayout>
</RelativeLayout>
......@@ -20,6 +20,12 @@
<item name="android:layout_marginStart">8dp</item>
<item name="android:layout_marginTop">8dp</item>
</style>
<style name="PaginationHeaderText" tools:ignore="UnusedResources">
<item name="android:paddingTop">0dp</item>
<item name="android:paddingBottom">0dp</item>
<item name="android:paddingStart">16dp</item>
<item name="android:textAppearance">@style/TextAppearance.BlueButtonText2</item>
</style>
<!-- Download Home V2 Snowflake Contender Styles -->
<style name="TinyCircularProgress">
......@@ -64,4 +70,11 @@
<item name="android:src">@drawable/ic_play_arrow_white_36dp</item>
<item name="android:tint">@color/modern_grey_800</item>
</style>
<style name="SmallMediaPlayButton">
<item name="android:layout_width">40dp</item>
<item name="android:layout_height">40dp</item>
<item name="android:background">@drawable/circular_progress_bar_background_small</item>
<item name="android:src">@drawable/ic_play_arrow_white_24dp</item>
<item name="android:tint">@color/modern_grey_800</item>
</style>
</resources>
......@@ -233,6 +233,8 @@ class DateOrderedListMediator {
mUiConfig.isRenameEnabled ? this::onRenameItem : null);
mModel.getProperties().set(
ListProperties.CALLBACK_PAGINATION_CLICK, mListMutator::loadMorePages);
mModel.getProperties().set(
ListProperties.CALLBACK_GROUP_PAGINATION_CLICK, this::loadMoreItemsOnCard);
}
/** Tears down this mediator. */
......
......@@ -185,9 +185,11 @@ class DateOrderedListView {
ListItem item = mModel.get(position);
boolean isFullWidthMedia = false;
switch (ListUtils.getViewTypeForItem(mModel.get(position), mConfig)) {
case ListUtils.ViewType.IMAGE:
case ListUtils.ViewType.IMAGE_FULL_WIDTH:
@ListUtils.ViewType
int viewType = ListUtils.getViewTypeForItem(mModel.get(position), mConfig);
switch (viewType) {
case ListUtils.ViewType.IMAGE: // fall through
case ListUtils.ViewType.IMAGE_FULL_WIDTH: // fall through
case ListUtils.ViewType.IN_PROGRESS_IMAGE:
isFullWidthMedia = ((ListItem.OfflineItemListItem) item).spanFullWidth;
if (isFullWidthMedia || mGridLayoutManager.getSpanCount() == 1) {
......@@ -208,12 +210,30 @@ class DateOrderedListView {
outRect.bottom = mPrefetchVerticalPaddingPx / 2;
isFullWidthMedia = true;
break;
case ListUtils.ViewType.PREFETCH:
case ListUtils.ViewType.PREFETCH_ARTICLE: // fall through
case ListUtils.ViewType.AUDIO:
outRect.left = mHorizontalPaddingPx;
outRect.right = mHorizontalPaddingPx;
outRect.top = mPrefetchVerticalPaddingPx / 2;
outRect.bottom = mPrefetchVerticalPaddingPx / 2;
break;
case ListUtils.ViewType.GROUP_CARD_HEADER: // fall through
case ListUtils.ViewType.GROUP_CARD_FOOTER: // fall through
case ListUtils.ViewType.GROUP_CARD_ITEM: // fall through
case ListUtils.ViewType.GROUP_CARD_DIVIDER_MIDDLE:
outRect.left = mHorizontalPaddingPx;
outRect.right = mHorizontalPaddingPx;
break;
case ListUtils.ViewType.GROUP_CARD_DIVIDER_TOP:
outRect.left = mHorizontalPaddingPx;
outRect.right = mHorizontalPaddingPx;
outRect.top = mPrefetchVerticalPaddingPx / 2;
break;
case ListUtils.ViewType.GROUP_CARD_DIVIDER_BOTTOM:
outRect.left = mHorizontalPaddingPx;
outRect.right = mHorizontalPaddingPx;
outRect.bottom = mPrefetchVerticalPaddingPx / 2;
break;
}
if (isFullWidthMedia
......
......@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.download.home.list;
import android.util.Pair;
import org.chromium.base.Callback;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.OfflineItemVisuals;
......@@ -12,6 +14,8 @@ import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
import java.util.Date;
/**
* The properties required to build a {@link ListItem} which contain two types of properties for the
* download manager: (1) A set of properties that act directly on the list view itself. (2) A set of
......@@ -77,8 +81,12 @@ public interface ListProperties {
WritableObjectPropertyKey<Runnable> CALLBACK_PAGINATION_CLICK =
new WritableObjectPropertyKey<>();
/** The callback to trigger when the card pagination is clicked to load more pages. */
WritableObjectPropertyKey<Callback<Pair<Date, String>>> CALLBACK_GROUP_PAGINATION_CLICK =
new WritableObjectPropertyKey<>();
PropertyKey[] ALL_KEYS = new PropertyKey[] {ENABLE_ITEM_ANIMATIONS, CALLBACK_OPEN,
CALLBACK_PAUSE, CALLBACK_RESUME, CALLBACK_CANCEL, CALLBACK_SHARE, CALLBACK_REMOVE,
CALLBACK_RENAME, PROVIDER_VISUALS, CALLBACK_SELECTION, SELECTION_MODE_ACTIVE,
CALLBACK_PAGINATION_CLICK};
CALLBACK_PAGINATION_CLICK, CALLBACK_GROUP_PAGINATION_CLICK};
}
......@@ -25,24 +25,33 @@ import java.util.List;
/** Utility methods for representing {@link ListItem}s in a {@link RecyclerView} list. */
public class ListUtils {
/** The potential types of list items that could be displayed. */
@IntDef({ViewType.DATE, ViewType.IN_PROGRESS, ViewType.GENERIC, ViewType.VIDEO, ViewType.IMAGE,
ViewType.IMAGE_FULL_WIDTH, ViewType.CUSTOM_VIEW, ViewType.PREFETCH,
@IntDef({ViewType.DATE, ViewType.IN_PROGRESS, ViewType.GENERIC, ViewType.VIDEO, ViewType.AUDIO,
ViewType.IMAGE, ViewType.IMAGE_FULL_WIDTH, ViewType.CUSTOM_VIEW,
ViewType.SECTION_HEADER, ViewType.IN_PROGRESS_VIDEO, ViewType.IN_PROGRESS_IMAGE,
ViewType.PAGINATION_HEADER})
ViewType.PREFETCH_ARTICLE, ViewType.GROUP_CARD_ITEM, ViewType.GROUP_CARD_HEADER,
ViewType.GROUP_CARD_FOOTER, ViewType.PAGINATION_HEADER, ViewType.GROUP_CARD_DIVIDER_TOP,
ViewType.GROUP_CARD_DIVIDER_MIDDLE, ViewType.GROUP_CARD_DIVIDER_BOTTOM})
@Retention(RetentionPolicy.SOURCE)
public @interface ViewType {
int DATE = 0;
int IN_PROGRESS = 1;
int GENERIC = 2;
int VIDEO = 3;
int IMAGE = 4;
int IMAGE_FULL_WIDTH = 5;
int CUSTOM_VIEW = 6;
int PREFETCH = 7;
int AUDIO = 4;
int IMAGE = 5;
int IMAGE_FULL_WIDTH = 6;
int CUSTOM_VIEW = 7;
int SECTION_HEADER = 8;
int IN_PROGRESS_VIDEO = 9;
int IN_PROGRESS_IMAGE = 10;
int PAGINATION_HEADER = 11;
int PREFETCH_ARTICLE = 11;
int GROUP_CARD_ITEM = 12;
int GROUP_CARD_HEADER = 13;
int GROUP_CARD_FOOTER = 14;
int GROUP_CARD_DIVIDER_TOP = 15;
int GROUP_CARD_DIVIDER_MIDDLE = 16;
int GROUP_CARD_DIVIDER_BOTTOM = 17;
int PAGINATION_HEADER = 18;
}
/**
......@@ -79,9 +88,27 @@ public class ListUtils {
if (item instanceof ViewListItem) return ViewType.CUSTOM_VIEW;
if (item instanceof ListItem.SectionHeaderListItem) return ViewType.SECTION_HEADER;
if (item instanceof ListItem.PaginationListItem) return ViewType.PAGINATION_HEADER;
if (item instanceof ListItem.CardHeaderListItem) {
return ViewType.GROUP_CARD_HEADER;
}
if (item instanceof ListItem.CardFooterListItem) {
return ViewType.GROUP_CARD_FOOTER;
}
if (item instanceof ListItem.CardDividerListItem) {
switch (((ListItem.CardDividerListItem) item).position) {
case TOP:
return ViewType.GROUP_CARD_DIVIDER_TOP;
case MIDDLE:
return ViewType.GROUP_CARD_DIVIDER_MIDDLE;
case BOTTOM:
return ViewType.GROUP_CARD_DIVIDER_BOTTOM;
}
}
if (item instanceof OfflineItemListItem) {
OfflineItemListItem offlineItem = (OfflineItemListItem) item;
if (offlineItem.isGrouped) return ViewType.GROUP_CARD_ITEM;
boolean inProgress = offlineItem.item.state == OfflineItemState.IN_PROGRESS
|| offlineItem.item.state == OfflineItemState.PAUSED
......@@ -93,7 +120,13 @@ public class ListUtils {
return inProgress ? ViewType.IN_PROGRESS : ViewType.GENERIC;
}
if (offlineItem.item.isSuggested) return ViewType.PREFETCH;
if (offlineItem.item.isSuggested) {
if (offlineItem.item.filter == OfflineItemFilter.PAGE) {
return ViewType.PREFETCH_ARTICLE;
} else if (offlineItem.item.filter == OfflineItemFilter.AUDIO) {
return ViewType.AUDIO;
}
}
switch (offlineItem.item.filter) {
case OfflineItemFilter.VIDEO:
......
......@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.download.home.filter.Filters;
import org.chromium.chrome.browser.download.home.list.view.CircularProgressView;
import org.chromium.chrome.browser.download.home.list.view.CircularProgressView.UiState;
import org.chromium.chrome.browser.util.MathUtils;
import org.chromium.components.offline_items_collection.LegacyHelpers;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.OfflineItem.Progress;
import org.chromium.components.offline_items_collection.OfflineItemFilter;
......@@ -358,6 +359,18 @@ public final class UiUtils {
}
}
/** @return Whether the given {@link OfflineItem} can be played as a media. */
public static boolean isMedia(OfflineItem offlineItem) {
return offlineItem.filter == OfflineItemFilter.AUDIO
|| offlineItem.filter == OfflineItemFilter.VIDEO;
}
/** @return Whether the given {@link OfflineItem} can be shared. */
public static boolean canShare(OfflineItem item) {
return LegacyHelpers.isLegacyDownload(item.id)
|| LegacyHelpers.isLegacyOfflinePage(item.id);
}
/** @return The domain associated with the given {@link OfflineItem}. */
public static String getDomainForItem(OfflineItem offlineItem) {
String formattedUrl =
......
// Copyright 2019 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.download.home.list.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.browser.download.home.list.UiUtils;
import org.chromium.chrome.download.R;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} specifically meant to display a standalone prefetched audio.
*/
public class AudioViewHolder extends OfflineItemViewHolder {
private final TextView mTitle;
private final TextView mCaption;
private final TextView mTimestamp;
/**
* Creates a new instance of a {@link AudioViewHolder}.
*/
public static AudioViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_audio, null);
return new AudioViewHolder(view);
}
private AudioViewHolder(View view) {
super(view);
mTitle = (TextView) itemView.findViewById(R.id.title);
mCaption = (TextView) itemView.findViewById(R.id.caption);
mTimestamp = (TextView) itemView.findViewById(R.id.timestamp);
}
// ThumbnailAwareViewHolder implementation.
@Override
public void bind(PropertyModel properties, ListItem item) {
super.bind(properties, item);
ListItem.OfflineItemListItem offlineItem = (ListItem.OfflineItemListItem) item;
mTitle.setText(offlineItem.item.title);
mCaption.setText(UiUtils.generatePrefetchCaption(offlineItem.item));
mTimestamp.setText(UiUtils.generatePrefetchTimestamp(offlineItem.date));
}
}
// Copyright 2019 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.download.home.list.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.download.R;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} meant to display a divider at the bottom of a group card.
*/
public class CardDividerBottomViewHolder extends ListItemViewHolder {
/**
* Creates a new {@link CardDividerBottomViewHolder} instance.
*/
public static CardDividerBottomViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_card_divider_bottom, null);
return new CardDividerBottomViewHolder(view);
}
private CardDividerBottomViewHolder(View view) {
super(view);
}
@Override
public void bind(PropertyModel properties, ListItem item) {}
}
// Copyright 2019 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.download.home.list.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.download.R;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} meant to display a divider between items of a group card.
*/
public class CardDividerMiddleViewHolder extends ListItemViewHolder {
/**
* Creates a new {@link CardDividerMiddleViewHolder} instance.
*/
public static CardDividerMiddleViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_card_divider_middle, null);
return new CardDividerMiddleViewHolder(view);
}
private CardDividerMiddleViewHolder(View view) {
super(view);
}
@Override
public void bind(PropertyModel properties, ListItem item) {}
}
// Copyright 2019 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.download.home.list.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.download.R;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} meant to display a divider at the top of a group card.
*/
public class CardDividerTopViewHolder extends ListItemViewHolder {
/**
* Creates a new {@link CardDividerTopViewHolder} instance.
*/
public static CardDividerTopViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_card_divider_top, null);
return new CardDividerTopViewHolder(view);
}
private CardDividerTopViewHolder(View view) {
super(view);
}
@Override
public void bind(PropertyModel properties, ListItem item) {}
}
// Copyright 2019 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.download.home.list.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.browser.download.home.list.ListProperties;
import org.chromium.chrome.download.R;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} meant to display a card footer.
*/
public class CardFooterViewHolder extends ListItemViewHolder {
/**
* Creates a new {@link CardFooterViewHolder} instance.
*/
public static CardFooterViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_card_footer, null);
return new CardFooterViewHolder(view);
}
public CardFooterViewHolder(View view) {
super(view);
}
@Override
public void bind(PropertyModel properties, ListItem item) {
ListItem.CardFooterListItem footerListItem = (ListItem.CardFooterListItem) item;
itemView.setOnClickListener(v -> {
properties.get(ListProperties.CALLBACK_GROUP_PAGINATION_CLICK)
.onResult(footerListItem.dateAndDomain);
});
}
}
// Copyright 2019 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.download.home.list.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.download.R;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} specifically meant to display a card header.
*/
public class CardHeaderViewHolder extends ListItemViewHolder {
/**
* Creates a new {@link CardHeaderViewHolder} instance.
*/
public static CardHeaderViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_card_header, null);
return new CardHeaderViewHolder(view);
}
public CardHeaderViewHolder(View view) {
super(view);
}
@Override
public void bind(PropertyModel properties, ListItem item) {
ListItem.CardHeaderListItem headerListItem = (ListItem.CardHeaderListItem) item;
TextView domainView = itemView.findViewById(R.id.domain);
domainView.setText(headerListItem.dateAndDomain.second);
}
}
......@@ -40,8 +40,10 @@ public abstract class ListItemViewHolder extends ViewHolder {
return ImageViewHolder.create(parent);
case ListUtils.ViewType.CUSTOM_VIEW:
return new CustomViewHolder(parent);
case ListUtils.ViewType.PREFETCH:
return PrefetchViewHolder.create(parent);
case ListUtils.ViewType.PREFETCH_ARTICLE:
return PrefetchArticleViewHolder.create(parent);
case ListUtils.ViewType.AUDIO:
return AudioViewHolder.create(parent);
case ListUtils.ViewType.SECTION_HEADER:
return SectionTitleViewHolder.create(parent);
case ListUtils.ViewType.IN_PROGRESS_VIDEO:
......@@ -50,6 +52,18 @@ public abstract class ListItemViewHolder extends ViewHolder {
return InProgressImageViewHolder.create(parent);
case ListUtils.ViewType.PAGINATION_HEADER:
return PaginationViewHolder.create(parent);
case ListUtils.ViewType.GROUP_CARD_ITEM:
return PrefetchGroupedItemViewHolder.create(parent);
case ListUtils.ViewType.GROUP_CARD_HEADER:
return CardHeaderViewHolder.create(parent);
case ListUtils.ViewType.GROUP_CARD_FOOTER:
return CardFooterViewHolder.create(parent);
case ListUtils.ViewType.GROUP_CARD_DIVIDER_TOP:
return CardDividerTopViewHolder.create(parent);
case ListUtils.ViewType.GROUP_CARD_DIVIDER_MIDDLE:
return CardDividerMiddleViewHolder.create(parent);
case ListUtils.ViewType.GROUP_CARD_DIVIDER_BOTTOM:
return CardDividerBottomViewHolder.create(parent);
}
assert false;
......
......@@ -17,6 +17,7 @@ import androidx.annotation.CallSuper;
import org.chromium.chrome.browser.download.home.filter.Filters;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.browser.download.home.list.ListProperties;
import org.chromium.chrome.browser.download.home.list.UiUtils;
import org.chromium.chrome.browser.download.home.list.view.AsyncImageView;
import org.chromium.chrome.browser.download.home.metrics.UmaUtils;
import org.chromium.chrome.browser.download.home.view.SelectionView;
......@@ -50,6 +51,7 @@ class OfflineItemViewHolder extends ListItemViewHolder implements ListMenuButton
// flag to hide rename list menu option for offline pages
private boolean mCanRename;
private boolean mCanShare;
/**
* Creates a new instance of a {@link MoreButtonViewHolder}.
......@@ -123,6 +125,7 @@ class OfflineItemViewHolder extends ListItemViewHolder implements ListMenuButton
}
mCanRename = mRenameCallback != null && offlineItem.canRename;
mCanShare = UiUtils.canShare(offlineItem);
}
@Override
......@@ -135,7 +138,7 @@ class OfflineItemViewHolder extends ListItemViewHolder implements ListMenuButton
@Override
public ListMenu getListMenu() {
ModelList listItems = new ModelList();
listItems.add(buildMenuListItem(R.string.share, 0, 0));
if (mCanShare) listItems.add(buildMenuListItem(R.string.share, 0, 0));
if (mCanRename) listItems.add(buildMenuListItem(R.string.rename, 0, 0));
listItems.add(buildMenuListItem(R.string.delete, 0, 0));
ListMenu.Delegate delegate = (model) -> {
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Copyright 2019 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.
......@@ -15,23 +15,23 @@ import org.chromium.chrome.download.R;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} specifically meant to display a prefetch item.
* A {@link RecyclerView.ViewHolder} specifically meant to display a prefetch article.
*/
public class PrefetchViewHolder extends OfflineItemViewHolder {
public class PrefetchArticleViewHolder extends OfflineItemViewHolder {
private final TextView mTitle;
private final TextView mCaption;
private final TextView mTimestamp;
/**
* Creates a new instance of a {@link PrefetchViewHolder}.
* Creates a new instance of a {@link PrefetchArticleViewHolder}.
*/
public static PrefetchViewHolder create(ViewGroup parent) {
public static PrefetchArticleViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_prefetch_item, null);
return new PrefetchViewHolder(view);
.inflate(R.layout.download_manager_prefetch_article, null);
return new PrefetchArticleViewHolder(view);
}
private PrefetchViewHolder(View view) {
private PrefetchArticleViewHolder(View view) {
super(view);
mTitle = (TextView) itemView.findViewById(R.id.title);
mCaption = (TextView) itemView.findViewById(R.id.caption);
......
// Copyright 2019 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.download.home.list.holder;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.chromium.chrome.browser.download.home.list.ListItem;
import org.chromium.chrome.browser.download.home.list.UiUtils;
import org.chromium.chrome.download.R;
import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.ui.modelutil.PropertyModel;
/**
* A {@link RecyclerView.ViewHolder} specifically meant to display a prefetch item that is part of a
* group card.
*/
public class PrefetchGroupedItemViewHolder extends OfflineItemViewHolder {
private final TextView mTitle;
private final TextView mTimestamp;
/**
* Creates a new instance of a {@link PrefetchGroupedItemViewHolder}.
*/
public static PrefetchGroupedItemViewHolder create(ViewGroup parent) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.download_manager_prefetch_grouped_item, null);
return new PrefetchGroupedItemViewHolder(view);
}
private PrefetchGroupedItemViewHolder(View view) {
super(view);
mTitle = itemView.findViewById(R.id.title);
mTimestamp = (TextView) itemView.findViewById(R.id.timestamp);
}
// ThumbnailAwareViewHolder implementation.
@Override
public void bind(PropertyModel properties, ListItem item) {
super.bind(properties, item);
ListItem.OfflineItemListItem listItem = (ListItem.OfflineItemListItem) item;
mTitle.setText(listItem.item.title);
mTimestamp.setText(UiUtils.generatePrefetchTimestamp(listItem.date));
OfflineItem offlineItem = ((ListItem.OfflineItemListItem) item).item;
View mediaButton = itemView.findViewById(R.id.media_button);
mediaButton.setVisibility(UiUtils.isMedia(offlineItem) ? View.VISIBLE : View.GONE);
}
}
......@@ -19,7 +19,7 @@ import org.chromium.ui.modelutil.PropertyModel;
* A {@link ViewHolder} specifically meant to display a section header.
*/
public class SectionTitleViewHolder extends ListItemViewHolder {
private final View mDivider;
private final View mTopDivider;
private final TextView mDate;
......@@ -32,7 +32,7 @@ public class SectionTitleViewHolder extends ListItemViewHolder {
private SectionTitleViewHolder(View view) {
super(view);
mDivider = view.findViewById(R.id.divider);
mTopDivider = view.findViewById(R.id.divider);
mDate = (TextView) view.findViewById(R.id.date);
}
......@@ -45,6 +45,6 @@ public class SectionTitleViewHolder extends ListItemViewHolder {
R.string.download_manager_just_now)
: UiUtils.dateToHeaderString(sectionItem.date));
mDivider.setVisibility(sectionItem.showTopDivider ? ViewGroup.VISIBLE : ViewGroup.GONE);
mTopDivider.setVisibility(sectionItem.showTopDivider ? ViewGroup.VISIBLE : ViewGroup.GONE);
}
}
......@@ -2507,7 +2507,7 @@ To change this setting, <ph name="BEGIN_LINK">&lt;resetlink&gt;</ph>reset sync<p
Images
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_PAGINATION" desc="Indicates that clicking on this button will show more items in the list.">
Load more…
See more
</message>
<message name="IDS_DOWNLOAD_MANAGER_UI_DOCUMENTS" desc="Indicates that clicking on this button shows only documents.">
Documents
......
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