Commit 367bfa1d authored by Shakti Sahu's avatar Shakti Sahu Committed by Commit Bot

Video Tutorials : Replaced thumbnails to use AsyncImageView

This CL adds :
1- Replaces thumbnails to use AsyncImageView on IPH card, and list view.
2- Removes the dependency on LargeMediaPlayButton style from downloads.

Bug: 1134412
Change-Id: Ibd9e5dbaeddd47564406ce201e10ec207df785b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2444536
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarCalder Kitagawa <ckitagawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#814764}
parent c1183175
......@@ -92,7 +92,6 @@ if (is_android) {
]
deps = [
"//chrome/browser/download/android:java_resources",
"//chrome/browser/ui/android/strings:ui_strings_grd",
"//components/browser_ui/widget/android:java_resources",
"//ui/android:ui_java_resources",
......
......@@ -16,12 +16,14 @@
android:paddingEnd="@dimen/promo_compact_padding"
android:paddingBottom="@dimen/promo_compact_padding">
<org.chromium.components.browser_ui.widget.RoundedCornerImageView
<org.chromium.components.browser_ui.widget.async_image.AsyncImageView
android:id="@+id/thumbnail"
android:layout_width="80dp"
android:layout_height="58dp"
android:layout_gravity="center_vertical"
android:importantForAccessibility="no"
app:unavailableSrc="@color/image_loading_color"
app:waitingSrc="@color/image_loading_color"
app:roundedfillColor="@color/modern_grey_300"
app:cornerRadiusBottomStart="@dimen/default_rounded_corner_radius"
app:cornerRadiusBottomEnd="@dimen/default_rounded_corner_radius"
......
......@@ -91,6 +91,7 @@ if (is_android) {
"//chrome/browser/image_fetcher:java",
"//chrome/browser/profiles/android:java",
"//chrome/browser/video_tutorials:java",
"//components/browser_ui/widget/android:java",
"//components/embedder_support/android:content_view_java",
"//components/embedder_support/android:web_contents_delegate_java",
"//components/thin_webview:factory_java",
......@@ -110,6 +111,7 @@ if (is_android) {
android_resources("java_resources") {
create_srcjar = false
sources = [
"android/java/res/drawable/circular_media_button_background.xml",
"android/java/res/drawable/radio_button.xml",
"android/java/res/drawable/radio_button_default.xml",
"android/java/res/drawable/radio_button_selected.xml",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2020 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>
<shape
android:shape="oval">
<solid android:color="@android:color/white" />
<size android:width="48dp"
android:height="48dp" />
</shape>
</item>
</layer-list>
\ No newline at end of file
......@@ -15,7 +15,7 @@
app:columnCount="1"
app:rowCount="2">
<org.chromium.ui.widget.ChromeImageView
<org.chromium.components.browser_ui.widget.async_image.AsyncImageView
android:id="@+id/thumbnail"
android:layout_width="match_parent"
android:layout_height="200dp"
......@@ -24,6 +24,9 @@
android:layout_marginEnd="1dp"
android:scaleType="centerCrop"
android:adjustViewBounds="true"
android:importantForAccessibility="no"
app:unavailableSrc="@color/image_loading_color"
app:waitingSrc="@color/image_loading_color"
app:layout_column="0"
app:layout_row="0"
app:layout_gravity="center"
......@@ -33,12 +36,16 @@
<org.chromium.ui.widget.ChromeImageButton
android:id="@+id/action_button"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/ic_play_arrow_white_36dp"
android:tint="@color/modern_grey_800"
app:layout_column="0"
app:layout_row="0"
app:layout_gravity="center"
android:elevation="2dp"
android:clickable="false"
style="@style/LargeMediaPlayButton"/>
android:background="@drawable/circular_media_button_background" />
<TextView
android:id="@+id/video_length"
......
......@@ -4,6 +4,9 @@
package org.chromium.chrome.browser.video_tutorials.iph;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.ViewStub;
import org.chromium.base.Callback;
......@@ -17,6 +20,7 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
* inflate when the IPH is shown.
*/
public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator {
private final Context mContext;
private final PropertyModel mModel;
private final VideoIPHView mView;
private final ImageFetcher mImageFetcher;
......@@ -32,6 +36,7 @@ public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator {
*/
public VideoIPHCoordinatorImpl(ViewStub viewStub, ImageFetcher imageFetcher,
Callback<Tutorial> onClickListener, Callback<Tutorial> onDismissListener) {
mContext = viewStub.getContext();
mImageFetcher = imageFetcher;
mOnClickListener = onClickListener;
mOnDismissListener = onDismissListener;
......@@ -51,10 +56,17 @@ public class VideoIPHCoordinatorImpl implements VideoIPHCoordinator {
mModel.set(
VideoIPHProperties.DISMISS_LISTENER, () -> mOnDismissListener.onResult(tutorial));
mModel.set(VideoIPHProperties.THUMBNAIL, null);
ImageFetcher.Params params = ImageFetcher.Params.create(
tutorial.posterUrl, ImageFetcher.VIDEO_TUTORIALS_IPH_UMA_CLIENT_NAME);
mImageFetcher.fetchImage(
params, bitmap -> mModel.set(VideoIPHProperties.THUMBNAIL, bitmap));
mModel.set(VideoIPHProperties.THUMBNAIL_PROVIDER, (consumer, widthPx, heightPx) -> {
return () -> {
ImageFetcher.Params params = ImageFetcher.Params.create(tutorial.posterUrl,
ImageFetcher.VIDEO_TUTORIALS_IPH_UMA_CLIENT_NAME, widthPx, heightPx);
mImageFetcher.fetchImage(params, bitmap -> {
Drawable drawable = bitmap == null
? null
: new BitmapDrawable(mContext.getResources(), bitmap);
consumer.onResult(drawable);
});
};
});
}
}
\ No newline at end of file
......@@ -4,8 +4,7 @@
package org.chromium.chrome.browser.video_tutorials.iph;
import android.graphics.Bitmap;
import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableBooleanPropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
......@@ -23,8 +22,8 @@ class VideoIPHProperties {
public static final WritableObjectPropertyKey<String> VIDEO_LENGTH =
new WritableObjectPropertyKey<>();
/** The thumbnail associated with the tutorial. */
public static final WritableObjectPropertyKey<Bitmap> THUMBNAIL =
/** The thumbnail provider to supply thumbnail images. */
public static final WritableObjectPropertyKey<AsyncImageView.Factory> THUMBNAIL_PROVIDER =
new WritableObjectPropertyKey<>();
/** The listener to be invoked when the IPH is clicked. */
......@@ -36,6 +35,6 @@ class VideoIPHProperties {
new WritableObjectPropertyKey<>();
/** All keys associated with the model. */
public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {
VISIBILITY, DISPLAY_TITLE, VIDEO_LENGTH, THUMBNAIL, CLICK_LISTENER, DISMISS_LISTENER};
public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {VISIBILITY, DISPLAY_TITLE,
VIDEO_LENGTH, THUMBNAIL_PROVIDER, CLICK_LISTENER, DISMISS_LISTENER};
}
......@@ -4,16 +4,12 @@
package org.chromium.chrome.browser.video_tutorials.iph;
import android.graphics.Bitmap;
import android.graphics.drawable.ColorDrawable;
import android.view.View;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.Nullable;
import org.chromium.chrome.browser.video_tutorials.R;
import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
......@@ -46,14 +42,8 @@ class VideoIPHView {
view.setText(videoLength);
}
private void setThumbnail(@Nullable Bitmap bitmap) {
ImageView view = mCardView.findViewById(R.id.thumbnail);
if (bitmap == null) {
view.setImageDrawable(
new ColorDrawable(view.getResources().getColor(R.color.image_loading_color)));
} else {
view.setImageBitmap(bitmap);
}
private View getThumbnailView() {
return mCardView.findViewById(R.id.thumbnail);
}
private void setClickListener(Runnable clickListener) {
......@@ -76,12 +66,14 @@ class VideoIPHView {
view.setTitle(model.get(VideoIPHProperties.DISPLAY_TITLE));
} else if (propertyKey == VideoIPHProperties.VIDEO_LENGTH) {
view.setVideoLength(model.get(VideoIPHProperties.VIDEO_LENGTH));
} else if (propertyKey == VideoIPHProperties.THUMBNAIL) {
view.setThumbnail(model.get(VideoIPHProperties.THUMBNAIL));
} else if (propertyKey == VideoIPHProperties.CLICK_LISTENER) {
view.setClickListener(model.get(VideoIPHProperties.CLICK_LISTENER));
} else if (propertyKey == VideoIPHProperties.DISMISS_LISTENER) {
view.setDismissListener(model.get(VideoIPHProperties.DISMISS_LISTENER));
} else if (propertyKey == VideoIPHProperties.THUMBNAIL_PROVIDER) {
AsyncImageView thumbnailView = (AsyncImageView) view.getThumbnailView();
thumbnailView.setAsyncImageDrawable(
model.get(VideoIPHProperties.THUMBNAIL_PROVIDER), null);
}
}
}
......@@ -4,9 +4,7 @@
package org.chromium.chrome.browser.video_tutorials.list;
import android.graphics.drawable.Drawable;
import org.chromium.base.Callback;
import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey;
......@@ -17,12 +15,6 @@ class TutorialCardProperties {
/** The view type used by the recycler view to show the tutorial cards. */
public static final int VIDEO_TUTORIAL_CARD_VIEW_TYPE = 3;
/** An interface to provide thumbnails for the videos. */
interface VisualsProvider {
/** Method to get visuals to display the thumbnail image. */
void getVisuals(Callback<Drawable> callback);
}
/** The title to be shown.*/
static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>();
......@@ -33,8 +25,8 @@ class TutorialCardProperties {
static final WritableObjectPropertyKey<Runnable> CLICK_CALLBACK =
new WritableObjectPropertyKey<>();
/** The provider to retrieve the visuals for the video thumbnail.*/
static final WritableObjectPropertyKey<VisualsProvider> VISUALS_PROVIDER =
/** The thumbnail provider to supply thumbnail images. */
public static final WritableObjectPropertyKey<AsyncImageView.Factory> VISUALS_PROVIDER =
new WritableObjectPropertyKey<>();
static final PropertyKey[] ALL_KEYS =
......
......@@ -4,14 +4,13 @@
package org.chromium.chrome.browser.video_tutorials.list;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import org.chromium.chrome.browser.video_tutorials.R;
import org.chromium.components.browser_ui.widget.async_image.AsyncImageView;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModel;
......@@ -37,11 +36,9 @@ class TutorialCardViewBinder {
view.setOnClickListener(
v -> { model.get(TutorialCardProperties.CLICK_CALLBACK).run(); });
} else if (propertyKey == TutorialCardProperties.VISUALS_PROVIDER) {
final ImageView thumbnail = view.findViewById(R.id.thumbnail);
thumbnail.setImageDrawable(new ColorDrawable(thumbnail.getResources().getColor(
org.chromium.components.browser_ui.widget.R.color.image_loading_color)));
model.get(TutorialCardProperties.VISUALS_PROVIDER)
.getVisuals(thumbnail::setImageDrawable);
AsyncImageView thumbnailView = (AsyncImageView) view.findViewById(R.id.thumbnail);
thumbnailView.setAsyncImageDrawable(
model.get(TutorialCardProperties.VISUALS_PROVIDER), null);
} else {
throw new IllegalArgumentException(
"Cannot update the view for propertyKey: " + propertyKey);
......
......@@ -12,6 +12,7 @@ import org.chromium.base.Callback;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.video_tutorials.Tutorial;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
import org.chromium.chrome.browser.video_tutorials.iph.VideoTutorialIPHUtils;
import org.chromium.ui.modelutil.MVCListAdapter;
import org.chromium.ui.modelutil.MVCListAdapter.ListItem;
import org.chromium.ui.modelutil.PropertyModel;
......@@ -54,23 +55,24 @@ public class TutorialListMediator {
}
private PropertyModel buildModelFromTutorial(Tutorial tutorial) {
return new PropertyModel.Builder(TutorialCardProperties.ALL_KEYS)
.with(TutorialCardProperties.TITLE, tutorial.displayTitle)
// TODO(shaktisahu): Provide a string in mm:ss format.
.with(TutorialCardProperties.VIDEO_LENGTH, Integer.toString(tutorial.videoLength))
.with(TutorialCardProperties.CLICK_CALLBACK,
() -> mClickCallback.onResult(tutorial))
.with(TutorialCardProperties.VISUALS_PROVIDER,
callback -> getBitmap(tutorial, callback))
.build();
}
PropertyModel.Builder builder =
new PropertyModel.Builder(TutorialCardProperties.ALL_KEYS)
.with(TutorialCardProperties.TITLE, tutorial.displayTitle)
.with(TutorialCardProperties.VIDEO_LENGTH,
VideoTutorialIPHUtils.getVideoLengthString(tutorial.videoLength))
.with(TutorialCardProperties.CLICK_CALLBACK,
() -> mClickCallback.onResult(tutorial));
private void getBitmap(Tutorial tutorial, Callback<Drawable> callback) {
ImageFetcher.Params params = ImageFetcher.Params.create(
tutorial.posterUrl, ImageFetcher.VIDEO_TUTORIALS_LIST_UMA_CLIENT_NAME);
mImageFetcher.fetchImage(params, bitmap -> {
Drawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
callback.onResult(drawable);
builder.with(TutorialCardProperties.VISUALS_PROVIDER, (consumer, widthPx, heightPx) -> {
return () -> {
ImageFetcher.Params params = ImageFetcher.Params.create(tutorial.posterUrl,
ImageFetcher.VIDEO_TUTORIALS_LIST_UMA_CLIENT_NAME, widthPx, heightPx);
mImageFetcher.fetchImage(params, bitmap -> {
Drawable drawable = new BitmapDrawable(mContext.getResources(), bitmap);
consumer.onResult(drawable);
});
};
});
return builder.build();
}
}
\ No newline at end of file
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