Commit 9960a1b2 authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Download Home : Added EmptyViewCoordinator to supply empty views

We need to show separate empty views for downloads and prefetch tabs. Also
on prefetch tab, the message will be different if prefetch is disabled.
Added EmptyViewCoordinator which will supply the empty view to the
DecoratedListItemModel. The exact UI for views will be added later.

Bug: 850607
Change-Id: If7c40d1964a7b13f92e272d632493f5c23749f57
Reviewed-on: https://chromium-review.googlesource.com/1144458
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarTheresa <twellington@chromium.org>
Cr-Commit-Position: refs/heads/master@{#577071}
parent 91815ebd
<?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. -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/empty_view"
android:layout_marginTop="100dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:drawablePadding="3dp"
android:textAppearance="@style/BlackDisabledText1"/>
</FrameLayout>
......@@ -13,7 +13,6 @@ import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.chromium.base.ObserverList;
import org.chromium.base.metrics.RecordHistogram;
......@@ -56,7 +55,6 @@ class DownloadManagerCoordinatorImpl
private boolean mMuteFilterChanges;
private boolean mIsSeparateActivity;
private int mSearchMenuId;
private TextView mEmptyView;
private SelectionDelegate<ListItem> mSelectionDelegate;
......@@ -89,7 +87,10 @@ class DownloadManagerCoordinatorImpl
(ViewGroup) LayoutInflater.from(mActivity).inflate(R.layout.download_main, null);
mSelectableListLayout =
(SelectableListLayout<ListItem>) mMainView.findViewById(R.id.selectable_list);
mEmptyView = mSelectableListLayout.initializeEmptyView(
// TODO(shaktisahu): Maybe refactor SelectableListLayout to work without supplying empty
// view.
mSelectableListLayout.initializeEmptyView(
VectorDrawableCompat.create(
mActivity.getResources(), R.drawable.downloads_big, mActivity.getTheme()),
R.string.download_manager_ui_empty, R.string.download_manager_no_results);
......
......@@ -44,7 +44,7 @@ public class DateOrderedListCoordinator {
}
private final FilterCoordinator mFilterCoordinator;
private final EmptyViewCoordinator mEmptyViewCoordinator;
private final DateOrderedListMediator mMediator;
private final DateOrderedListView mView;
......@@ -74,6 +74,10 @@ public class DateOrderedListCoordinator {
: new FilterCoordinatorWithNoTabs(context, mMediator.getFilterSource());
mFilterCoordinator.addObserver(mMediator::onFilterTypeSelected);
mFilterCoordinator.addObserver(filterObserver);
mEmptyViewCoordinator =
new EmptyViewCoordinator(context, decoratedModel, mMediator.getFilterSource());
mFilterCoordinator.addObserver(mEmptyViewCoordinator::onFilterTypeSelected);
decoratedModel.setHeader(new ViewListItem(Long.MAX_VALUE, mFilterCoordinator.getView()));
}
......
......@@ -21,6 +21,7 @@ class DecoratedListItemModel
private final ListItemModel mModel;
private ViewListItem mHeaderItem;
private ViewListItem mEmptyViewItem;
/** Creates a {@link DecoratedListItemModel} instance that wraos {@code model}. */
public DecoratedListItemModel(ListItemModel model) {
......@@ -49,15 +50,41 @@ class DecoratedListItemModel
}
}
/**
* Adds {@code item} as a empty view for the list. Clears the empty view if it is {@code
* null}. Empty view must be the second item in the list after the header. If there is no
* header, it must be the first item in the list.
*/
public void setEmptyView(ViewListItem item) {
if (mEmptyViewItem == item) return;
int index = mHeaderItem == null ? 0 : 1;
ViewListItem oldEmptyView = mEmptyViewItem;
mEmptyViewItem = item;
if (oldEmptyView != null && item == null) {
notifyItemRemoved(index);
} else if (oldEmptyView == null && item != null) {
notifyItemInserted(index);
} else {
notifyItemRangeChanged(index, 1);
}
}
// SimpleList implementation.
@Override
public int size() {
return mModel.size() + (mHeaderItem == null ? 0 : 1);
return mModel.size() + (mHeaderItem == null ? 0 : 1) + (mEmptyViewItem == null ? 0 : 1);
}
@Override
public ListItem get(int index) {
if (index == 0 && mHeaderItem != null) return mHeaderItem;
if (mHeaderItem != null || mEmptyViewItem != null) {
if (index == 0) return mHeaderItem != null ? mHeaderItem : mEmptyViewItem;
if (index == 1 && mEmptyViewItem != null) return mEmptyViewItem;
}
return mModel.get(convertIndexForSource(index));
}
......@@ -80,10 +107,12 @@ class DecoratedListItemModel
}
private int convertIndexForSource(int index) {
return mHeaderItem == null ? index : index - 1;
int offset = (mHeaderItem == null ? 0 : 1) + (mEmptyViewItem == null ? 0 : 1);
return index - offset;
}
private int convertIndexFromSource(int index) {
return mHeaderItem == null ? index : index + 1;
int offset = (mHeaderItem == null ? 0 : 1) + (mEmptyViewItem == null ? 0 : 1);
return index + offset;
}
}
// 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.
package org.chromium.chrome.browser.download.home.list;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.download.home.filter.Filters;
import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterObserver;
import org.chromium.chrome.browser.download.home.filter.OfflineItemFilterSource;
import org.chromium.chrome.browser.download.home.list.ListItem.ViewListItem;
import org.chromium.components.offline_items_collection.OfflineItem;
import java.util.Collection;
/**
* A class that determines whether an empty view should be shown and inserts into the model.
*/
class EmptyViewCoordinator implements OfflineItemFilterObserver {
private final Context mContext;
private final DecoratedListItemModel mDecoratedModel;
private final OfflineItemFilterSource mSource;
private final Handler mHandler = new Handler();
private ViewListItem mEmptyViewItem;
private @Filters.FilterType int mCurrentFilter;
/** Creates a {@link EmptyViewCoordinator} instance that wraos {@code model}. */
public EmptyViewCoordinator(Context context, DecoratedListItemModel decoratedModel,
OfflineItemFilterSource source) {
mContext = context;
mDecoratedModel = decoratedModel;
mSource = source;
mSource.addObserver(this);
mHandler.post(() -> onFilterTypeSelected(mCurrentFilter));
}
public void onFilterTypeSelected(@Filters.FilterType int filter) {
boolean hasEmptyView = mEmptyViewItem != null;
if (filter == mCurrentFilter && hasEmptyView == isEmpty()) return;
mCurrentFilter = filter;
updateForEmptyView();
}
private boolean isEmpty() {
boolean showingPrefetch = mCurrentFilter == Filters.FilterType.PREFETCHED;
for (OfflineItem item : mSource.getItems()) {
if (showingPrefetch && item.isSuggested) return false;
if (!showingPrefetch && !item.isSuggested) return false;
}
return true;
}
private void updateForEmptyView() {
mEmptyViewItem = isEmpty() ? createEmptyView() : null;
mDecoratedModel.setEmptyView(mEmptyViewItem);
}
private ViewListItem createEmptyView() {
boolean showingPrefetch = mCurrentFilter == Filters.FilterType.PREFETCHED;
// TODO(shaktisahu): Supply correct value for prefetch settings.
boolean prefetchEnabled = true;
View emptyView = LayoutInflater.from(mContext).inflate(R.layout.downloads_empty_view, null);
Drawable emptyDrawable = VectorDrawableCompat.create(mContext.getResources(),
showingPrefetch ? R.drawable.ic_library_news_feed : R.drawable.downloads_big,
mContext.getTheme());
TextView emptyTextView = emptyView.findViewById(R.id.empty_view);
emptyTextView.setText(showingPrefetch
? (prefetchEnabled ? R.string.download_manager_prefetch_tab_empty
: R.string.download_manager_enable_prefetch_message)
: R.string.download_manager_ui_empty);
emptyTextView.setCompoundDrawablesWithIntrinsicBounds(null, emptyDrawable, null, null);
return new ViewListItem(Long.MAX_VALUE - 1, emptyView);
}
// OfflineItemFilterObserver implementation.
@Override
public void onItemsAdded(Collection<OfflineItem> items) {
mHandler.post(() -> onFilterTypeSelected(mCurrentFilter));
}
@Override
public void onItemsRemoved(Collection<OfflineItem> items) {
mHandler.post(() -> onFilterTypeSelected(mCurrentFilter));
}
@Override
public void onItemUpdated(OfflineItem oldItem, OfflineItem item) {
mHandler.post(() -> onFilterTypeSelected(mCurrentFilter));
}
}
......@@ -2432,6 +2432,12 @@ To obtain new licenses, connect to the internet and play your downloaded content
<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_PREFETCH_TAB_EMPTY" desc="Tab text indicating that there is no prefetched content.">
No content here
</message>
<message name="IDS_DOWNLOAD_MANAGER_ENABLE_PREFETCH_MESSAGE" desc="Tab text indicating that users can enable prefetch to allow chrome to download articles on Wi-Fi.">
Allow Chrome to download articles for you when on Wi-Fi under settings.
</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>
......
......@@ -475,6 +475,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListView.java",
"java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListViewAdapter.java",
"java/src/org/chromium/chrome/browser/download/home/list/DecoratedListItemModel.java",
"java/src/org/chromium/chrome/browser/download/home/list/EmptyViewCoordinator.java",
"java/src/org/chromium/chrome/browser/download/home/list/ItemUtils.java",
"java/src/org/chromium/chrome/browser/download/home/list/ListItem.java",
"java/src/org/chromium/chrome/browser/download/home/list/ListItemModel.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