Commit 1073af05 authored by David Trainor's avatar David Trainor Committed by Commit Bot

Download Home - Build new prefetch view

This is the initial implementation of a prefetch view item for the new
download home UI.  This change includes the following:
- Builds out the ViewHolder that can handle thumbnails (automatically
processes it and pushes it to the view).
- Builds out the ViewHolder that can handle a 3-dot menu (automatically
handles the callback information).
- Adds the initial XML for the prefetched item.

BUG=849584

Change-Id: I965df4b6bdffc73f084f2f18c15588488b4beb0f
Reviewed-on: https://chromium-review.googlesource.com/1087319
Commit-Queue: David Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Reviewed-by: default avatarShakti Sahu <shaktisahu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#565079}
parent 717c1c29
...@@ -110,6 +110,7 @@ android_resources("chrome_java_resources") { ...@@ -110,6 +110,7 @@ android_resources("chrome_java_resources") {
"//third_party/android_media:android_media_resources", "//third_party/android_media:android_media_resources",
"//third_party/android_tools:android_support_design_java", "//third_party/android_tools:android_support_design_java",
"//third_party/android_tools:android_support_v7_appcompat_java", "//third_party/android_tools:android_support_v7_appcompat_java",
"//third_party/android_tools:android_support_v7_gridlayout_java",
"//third_party/android_tools:android_support_v7_recyclerview_java", "//third_party/android_tools:android_support_v7_recyclerview_java",
] ]
custom_package = "org.chromium.chrome" custom_package = "org.chromium.chrome"
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 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.
-->
<android.support.v7.widget.GridLayout
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:clickable="true"
android:background="@android:color/white"
app:columnCount="4"
app:rowCount="4">
<ImageView
android:id="@+id/thumbnail"
android:layout_width="114dp"
android:layout_height="114dp"
android:layout_marginEnd="9dp"
android:scaleType="fitCenter"
android:background="@color/google_grey_100"
app:layout_column="0"
app:layout_row="0"
app:layout_rowSpan="4"
tools:ignore="ContentDescription" />
<Space
android:layout_width="wrap_content"
android:layout_height="0dp"
app:layout_gravity="fill"
app:layout_column="0"
app:layout_row="3"
app:layout_columnSpan="4" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:minHeight="40dp"
android:maxLines="2"
android:ellipsize="end"
android:textAppearance="@style/BlackBodyDefault"
android:textAlignment="viewStart"
app:layout_column="1"
app:layout_row="0"
app:layout_columnSpan="2"
app:layout_gravity="fill_horizontal" />
<TextView
android:id="@+id/caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/BlackCaption"
android:textAlignment="viewStart"
app:layout_column="1"
app:layout_row="1"
app:layout_columnSpan="3"
app:layout_gravity="fill_horizontal" />
<TextView
android:id="@+id/timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="@style/BlackCaption"
android:textAlignment="viewStart"
app:layout_column="1"
app:layout_row="2"
app:layout_gravity="center_vertical" />
<ImageView
android:layout_width="12dp"
android:layout_height="12dp"
android:layout_marginStart="4dp"
android:src="@drawable/offline_pin_round"
android:scaleType="centerInside"
android:tint="@color/black_alpha_65"
app:layout_column="2"
app:layout_row="2"
app:layout_columnSpan="2"
app:layout_gravity="start|center_vertical"
tools:ignore="ContentDescription" />
<include layout="@layout/list_menu_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:paddingTop="12dp"
app:layout_column="3"
app:layout_row="0" />
</android.support.v7.widget.GridLayout>
\ No newline at end of file
...@@ -573,4 +573,8 @@ ...@@ -573,4 +573,8 @@
<!-- Download manager dimensions --> <!-- Download manager dimensions -->
<dimen name="download_manager_image_width">150dp</dimen> <dimen name="download_manager_image_width">150dp</dimen>
<dimen name="download_manager_image_padding">1dp</dimen> <dimen name="download_manager_image_padding">1dp</dimen>
<dimen name="download_manager_generic_thumbnail_size">48dp</dimen>
<dimen name="download_manager_prefetch_thumbnail_size">114dp</dimen>
<dimen name="download_manager_prefetch_horizontal_margin">16dp</dimen>
<dimen name="download_manager_prefetch_vertical_margin">12dp</dimen>
</resources> </resources>
...@@ -73,7 +73,7 @@ public class OfflineContentProviderGlue implements OfflineContentProvider.Observ ...@@ -73,7 +73,7 @@ public class OfflineContentProviderGlue implements OfflineContentProvider.Observ
if (LegacyHelpers.isLegacyDownload(item.id)) { if (LegacyHelpers.isLegacyDownload(item.id)) {
mDownloadProvider.removeItem(item); mDownloadProvider.removeItem(item);
} else { } else {
mProvider.openItem(item.id); mProvider.removeItem(item.id);
} }
} }
......
...@@ -27,6 +27,8 @@ class DateOrderedListView { ...@@ -27,6 +27,8 @@ class DateOrderedListView {
private final int mImageWidthPx; private final int mImageWidthPx;
private final int mImagePaddingPx; private final int mImagePaddingPx;
private final int mPrefetchVerticalPaddingPx;
private final int mPrefetchHorizontalPaddingPx;
private final RecyclerView mView; private final RecyclerView mView;
...@@ -38,6 +40,10 @@ class DateOrderedListView { ...@@ -38,6 +40,10 @@ class DateOrderedListView {
context.getResources().getDimensionPixelSize(R.dimen.download_manager_image_width); context.getResources().getDimensionPixelSize(R.dimen.download_manager_image_width);
mImagePaddingPx = context.getResources().getDimensionPixelOffset( mImagePaddingPx = context.getResources().getDimensionPixelOffset(
R.dimen.download_manager_image_padding); R.dimen.download_manager_image_padding);
mPrefetchHorizontalPaddingPx = context.getResources().getDimensionPixelSize(
R.dimen.download_manager_prefetch_horizontal_margin);
mPrefetchVerticalPaddingPx = context.getResources().getDimensionPixelSize(
R.dimen.download_manager_prefetch_vertical_margin);
DateOrderedListViewBinder listViewBinder = new DateOrderedListViewBinder(); DateOrderedListViewBinder listViewBinder = new DateOrderedListViewBinder();
DateOrderedListViewAdapter adapter = new DateOrderedListViewAdapter(mModel, listViewBinder); DateOrderedListViewAdapter adapter = new DateOrderedListViewAdapter(mModel, listViewBinder);
...@@ -107,6 +113,12 @@ class DateOrderedListView { ...@@ -107,6 +113,12 @@ class DateOrderedListView {
outRect.top = mImagePaddingPx; outRect.top = mImagePaddingPx;
outRect.bottom = mImagePaddingPx; outRect.bottom = mImagePaddingPx;
break; break;
case ListUtils.PREFETCH:
outRect.left = mPrefetchHorizontalPaddingPx;
outRect.right = mPrefetchHorizontalPaddingPx;
outRect.top = mPrefetchVerticalPaddingPx / 2;
outRect.bottom = mPrefetchVerticalPaddingPx / 2;
break;
} }
} }
} }
......
...@@ -23,13 +23,15 @@ class DateOrderedListViewBinder implements ViewBinder<DecoratedListItemModel, Li ...@@ -23,13 +23,15 @@ class DateOrderedListViewBinder implements ViewBinder<DecoratedListItemModel, Li
case ListUtils.IN_PROGRESS: case ListUtils.IN_PROGRESS:
return new ListItemViewHolder.InProgressViewHolder(parent); return new ListItemViewHolder.InProgressViewHolder(parent);
case ListUtils.GENERIC: case ListUtils.GENERIC:
return new ListItemViewHolder.GenericViewHolder(parent); return ListItemViewHolder.GenericViewHolder.create(parent);
case ListUtils.VIDEO: case ListUtils.VIDEO:
return new ListItemViewHolder.VideoViewHolder(parent); return new ListItemViewHolder.VideoViewHolder(parent);
case ListUtils.IMAGE: case ListUtils.IMAGE:
return new ListItemViewHolder.ImageViewHolder(parent); return new ListItemViewHolder.ImageViewHolder(parent);
case ListUtils.CUSTOM_VIEW: case ListUtils.CUSTOM_VIEW:
return new ListItemViewHolder.CustomViewHolder(parent); return new ListItemViewHolder.CustomViewHolder(parent);
case ListUtils.PREFETCH:
return ListItemViewHolder.PrefetchViewHolder.create(parent);
} }
assert false; assert false;
......
...@@ -19,7 +19,7 @@ import java.lang.annotation.RetentionPolicy; ...@@ -19,7 +19,7 @@ import java.lang.annotation.RetentionPolicy;
class ListUtils { class ListUtils {
/** The potential types of list items that could be displayed. */ /** The potential types of list items that could be displayed. */
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
@IntDef({DATE, IN_PROGRESS, GENERIC, VIDEO, IMAGE, CUSTOM_VIEW}) @IntDef({DATE, IN_PROGRESS, GENERIC, VIDEO, IMAGE, CUSTOM_VIEW, PREFETCH})
public @interface ViewType {} public @interface ViewType {}
public static final int DATE = 0; public static final int DATE = 0;
public static final int IN_PROGRESS = 1; public static final int IN_PROGRESS = 1;
...@@ -27,6 +27,7 @@ class ListUtils { ...@@ -27,6 +27,7 @@ class ListUtils {
public static final int VIDEO = 3; public static final int VIDEO = 3;
public static final int IMAGE = 4; public static final int IMAGE = 4;
public static final int CUSTOM_VIEW = 5; public static final int CUSTOM_VIEW = 5;
public static final int PREFETCH = 6;
private ListUtils() {} private ListUtils() {}
...@@ -43,6 +44,7 @@ class ListUtils { ...@@ -43,6 +44,7 @@ class ListUtils {
if (item instanceof OfflineItemListItem) { if (item instanceof OfflineItemListItem) {
OfflineItemListItem offlineItem = (OfflineItemListItem) item; OfflineItemListItem offlineItem = (OfflineItemListItem) item;
if (offlineItem.item.isSuggested) return ListUtils.PREFETCH;
if (offlineItem.item.state == OfflineItemState.IN_PROGRESS) { if (offlineItem.item.state == OfflineItemState.IN_PROGRESS) {
return ListUtils.IN_PROGRESS; return ListUtils.IN_PROGRESS;
} }
......
...@@ -9,11 +9,15 @@ import android.text.format.DateUtils; ...@@ -9,11 +9,15 @@ import android.text.format.DateUtils;
import org.chromium.base.ContextUtils; import org.chromium.base.ContextUtils;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.download.DownloadUtils;
import org.chromium.chrome.browser.util.MathUtils;
import org.chromium.components.offline_items_collection.OfflineItem; import org.chromium.components.offline_items_collection.OfflineItem;
import org.chromium.components.offline_items_collection.OfflineItemFilter; import org.chromium.components.offline_items_collection.OfflineItemFilter;
import org.chromium.components.url_formatter.UrlFormatter;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.concurrent.TimeUnit;
/** A set of helper utility methods for the UI. */ /** A set of helper utility methods for the UI. */
public final class UiUtils { public final class UiUtils {
...@@ -50,6 +54,45 @@ public final class UiUtils { ...@@ -50,6 +54,45 @@ public final class UiUtils {
return builder; return builder;
} }
/**
* Converts {@code date} to a string meant to be used as a prefetched item timestamp.
* @param date The {@link Date} to convert.
* @return The {@link CharSequence} representing the timestamp.
*/
public static CharSequence generatePrefetchTimestamp(Date date) {
Context context = ContextUtils.getApplicationContext();
Calendar calendar1 = CalendarFactory.get();
Calendar calendar2 = CalendarFactory.get();
calendar1.setTimeInMillis(System.currentTimeMillis());
calendar2.setTime(date);
if (CalendarUtils.isSameDay(calendar1, calendar2)) {
int hours =
(int) MathUtils.clamp(TimeUnit.MILLISECONDS.toHours(calendar1.getTimeInMillis()
- calendar2.getTimeInMillis()),
1, 23);
return context.getResources().getQuantityString(
R.plurals.download_manager_n_hours, hours, hours);
} else {
return DateUtils.formatDateTime(context, date.getTime(), DateUtils.FORMAT_SHOW_YEAR);
}
}
/**
* Generates a caption for a prefetched item.
* @param item The {@link OfflineItem} to generate a caption for.
* @return The {@link CharSequence} representing the caption.
*/
public static CharSequence generatePrefetchCaption(OfflineItem item) {
Context context = ContextUtils.getApplicationContext();
String displaySize = DownloadUtils.getStringForBytes(context, item.totalSizeBytes);
String displayUrl = UrlFormatter.formatUrlForSecurityDisplayOmitScheme(item.pageUrl);
return context.getString(
R.string.download_manager_prefetch_caption, displayUrl, displaySize);
}
/** @return Whether or not {@code item} can show a thumbnail in the UI. */ /** @return Whether or not {@code item} can show a thumbnail in the UI. */
public static boolean canHaveThumbnails(OfflineItem item) { public static boolean canHaveThumbnails(OfflineItem item) {
switch (item.filter) { switch (item.filter) {
......
...@@ -2333,6 +2333,12 @@ To obtain new licenses, connect to the internet and play your downloaded content ...@@ -2333,6 +2333,12 @@ To obtain new licenses, connect to the internet and play your downloaded content
<message name="IDS_DOWNLOAD_MANAGER_PREFETCH_TAB" desc="Tab text for showing downloaded popular content."> <message name="IDS_DOWNLOAD_MANAGER_PREFETCH_TAB" desc="Tab text for showing downloaded popular content.">
Popular Content Popular Content
</message> </message>
<message name="IDS_DOWNLOAD_MANAGER_PREFETCH_CAPTION" desc="Text containing the prefetched article description.">
<ph name="DESCRIPTION">%1$s<ex>www.example.com</ex></ph> - <ph name="FILE_SIZE">%2$s<ex>1.56 MB</ex></ph>
</message>
<message name="IDS_DOWNLOAD_MANAGER_N_HOURS" desc="How many hours ago an item was downloaded (if downloaded on the same day). [ICU Syntax]">
{HOURS, plural, =1 {# hr} other {# hrs}}
</message>
<!-- Browsing History UI --> <!-- Browsing History UI -->
<message name="IDS_HISTORY_MANAGER_EMPTY" desc="Indicates that there are no browsing history items."> <message name="IDS_HISTORY_MANAGER_EMPTY" desc="Indicates that there are no browsing history items.">
......
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