Commit 19aa55ee authored by Shakti Sahu's avatar Shakti Sahu Committed by Chromium LUCI CQ

Video tutorials : Fixed toolbar shadow for video list

Added toolbar shadow for the video tutorial list. Also modified the
change language button text to show a constant string.

Bug: 1168267
Change-Id: I682e527a37a677da0ca40f809c7e19bfddbe8887
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2638414
Commit-Queue: Shakti Sahu <shaktisahu@chromium.org>
Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845292}
parent 7d745b56
......@@ -36,7 +36,7 @@ public class VideoTutorialListActivity extends SynchronousInitializationActivity
ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.IN_MEMORY_WITH_DISK_CACHE,
profile, GlobalDiscardableReferencePool.getReferencePool());
mCoordinator = VideoTutorialServiceFactory.createTutorialListCoordinator(
findViewById(R.id.recycler_view), videoTutorialService, imageFetcher,
findViewById(R.id.video_tutorial_list), videoTutorialService, imageFetcher,
this::onTutorialSelected);
findViewById(R.id.close_button).setOnClickListener(v -> finish());
}
......
......@@ -63,16 +63,17 @@
</RelativeLayout>
<TextView
android:id="@+id/video_length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/thumbnail_wrapper"
android:layout_marginStart="6dp"
android:layout_marginBottom="6dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:background="@color/modern_grey_900"
android:textAppearance="@style/TextAppearance.TextSmall.Primary.Light" />
android:id="@+id/video_length"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/thumbnail_wrapper"
android:layout_marginStart="6dp"
android:layout_marginBottom="6dp"
android:paddingStart="4dp"
android:paddingEnd="4dp"
android:background="@color/modern_grey_900"
android:importantForAccessibility="no"
android:textAppearance="@style/TextAppearance.TextSmall.Primary.Light" />
<TextView
android:id="@+id/title"
......
......@@ -8,11 +8,12 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/video_tutorial_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="20dp" >
android:paddingTop="6dp" >
<LinearLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
......@@ -41,11 +42,19 @@
app:tint="@color/default_icon_color_tint_list" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="16dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp" />
android:layout_marginTop="4dp" >
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<org.chromium.components.browser_ui.widget.FadingShadowView
android:id="@+id/toolbar_shadow"
android:layout_width="match_parent"
android:layout_height="@dimen/action_bar_shadow_height"/>
</FrameLayout>
</LinearLayout>
......@@ -101,6 +101,7 @@ if (is_android) {
"//services/media_session/public/cpp/android:media_session_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_annotation_annotation_java",
"//third_party/android_deps:androidx_core_core_java",
"//third_party/android_deps:androidx_recyclerview_recyclerview_java",
"//third_party/gif_player:gif_player_java",
"//ui/android:ui_java",
......
......@@ -71,6 +71,7 @@
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.TextMediumThick.Primary.Light"
android:text="@string/change_chrome_lang"
style="@style/TextButton" />
</LinearLayout>
......
......@@ -40,6 +40,7 @@
android:layout_height="60dp"
android:src="@drawable/ic_play_arrow_white_36dp"
android:tint="@color/modern_grey_800"
android:contentDescription="@string/accessibility_play_video"
app:layout_column="0"
app:layout_row="0"
app:layout_gravity="center"
......@@ -59,6 +60,7 @@
app:layout_column="0"
app:layout_row="0"
app:layout_gravity="bottom"
android:importantForAccessibility="no"
android:textAppearance="@style/TextAppearance.TextSmall.Primary.Light" />
<TextView
......
......@@ -164,6 +164,9 @@ public class PlaybackStateObserver extends MediaSessionObserver {
long updatedPosition = (long) (mediaPosition.getPosition()
+ (elapsedTime * mediaPosition.getPlaybackRate()));
updatedPosition = Math.min(updatedPosition, mediaPosition.getDuration());
if (mediaPosition.getDuration() - updatedPosition < 100) {
updatedPosition = mediaPosition.getDuration();
}
return updatedPosition;
}
......
......@@ -6,10 +6,9 @@ package org.chromium.chrome.browser.video_tutorials;
import android.content.Context;
import android.util.Pair;
import android.view.ViewGroup;
import android.view.ViewStub;
import androidx.recyclerview.widget.RecyclerView;
import org.chromium.base.Callback;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.supplier.Supplier;
......@@ -61,11 +60,11 @@ public class VideoTutorialServiceFactory {
}
/** See {@link TutorialListCoordinator}.*/
public static TutorialListCoordinator createTutorialListCoordinator(RecyclerView recyclerView,
public static TutorialListCoordinator createTutorialListCoordinator(ViewGroup mainView,
VideoTutorialService videoTutorialService, ImageFetcher imageFetcher,
Callback<Tutorial> clickCallback) {
return new TutorialListCoordinatorImpl(
recyclerView, videoTutorialService, imageFetcher, clickCallback);
mainView, videoTutorialService, imageFetcher, clickCallback);
}
/** @return The tracker to track Try Now button clicks. */
......
......@@ -4,21 +4,31 @@
package org.chromium.chrome.browser.video_tutorials.list;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
import androidx.recyclerview.widget.RecyclerView.State;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.Callback;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.video_tutorials.R;
import org.chromium.chrome.browser.video_tutorials.Tutorial;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
import org.chromium.components.browser_ui.widget.FadingShadow;
import org.chromium.components.browser_ui.widget.FadingShadowView;
import org.chromium.components.browser_ui.widget.displaystyle.HorizontalDisplayStyle;
import org.chromium.components.browser_ui.widget.displaystyle.UiConfig;
import org.chromium.components.browser_ui.widget.displaystyle.UiConfig.DisplayStyle;
import org.chromium.ui.modelutil.MVCListAdapter;
import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
......@@ -27,21 +37,25 @@ import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
*/
public class TutorialListCoordinatorImpl implements TutorialListCoordinator {
private final TutorialListMediator mMediator;
private final ViewGroup mMainView;
private UiConfig mUiConfig;
/**
* Constructor.
* @param recyclerView The {@link RecyclerView} associated with this coordinator.
* @param mainView The {@link View} associated with this coordinator.
* @param videoTutorialService The video tutorial service backend.
* @param imageFetcher An {@link ImageFetcher} to provide thumbnail images.
* @param clickCallback A callback to be invoked when a tutorial is clicked.
*/
public TutorialListCoordinatorImpl(RecyclerView recyclerView,
public TutorialListCoordinatorImpl(ViewGroup mainView,
VideoTutorialService videoTutorialService, ImageFetcher imageFetcher,
Callback<Tutorial> clickCallback) {
mMainView = mainView;
MVCListAdapter.ModelList listModel = new MVCListAdapter.ModelList();
SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(listModel);
adapter.registerType(TutorialCardProperties.VIDEO_TUTORIAL_CARD_VIEW_TYPE,
TutorialCardViewBinder::buildView, TutorialCardViewBinder::bindView);
final RecyclerView recyclerView = mainView.findViewById(R.id.recycler_view);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(
recyclerView.getContext(), LinearLayoutManager.VERTICAL, false));
......@@ -49,19 +63,72 @@ public class TutorialListCoordinatorImpl implements TutorialListCoordinator {
mMediator = new TutorialListMediator(listModel, recyclerView.getContext(),
videoTutorialService, imageFetcher, clickCallback);
FadingShadowView toolbarShadow = mainView.findViewById(R.id.toolbar_shadow);
toolbarShadow.init(ApiCompatibilityUtils.getColor(
toolbarShadow.getResources(), R.color.toolbar_shadow_color),
FadingShadow.POSITION_TOP);
recyclerView.addOnScrollListener(new OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
boolean showShadow = recyclerView.canScrollVertically(-1);
toolbarShadow.setVisibility(showShadow ? View.VISIBLE : View.GONE);
}
});
configureWideDisplayStyle();
}
private void configureWideDisplayStyle() {
mUiConfig = new UiConfig(mMainView);
mUiConfig.addObserver(newDisplayStyle -> {
int padding = getPaddingForDisplayStyle(newDisplayStyle, mMainView.getResources());
View recyclerView = mMainView.findViewById(R.id.recycler_view);
View toolbar = mMainView.findViewById(R.id.toolbar);
ViewCompat.setPaddingRelative(recyclerView, padding, recyclerView.getPaddingTop(),
padding, recyclerView.getPaddingBottom());
ViewCompat.setPaddingRelative(
toolbar, padding, toolbar.getPaddingTop(), padding, toolbar.getPaddingBottom());
});
mMainView.addView(new View(mMainView.getContext()) {
@Override
protected void onConfigurationChanged(Configuration newConfig) {
mUiConfig.updateDisplayStyle();
}
});
}
private static int getPaddingForDisplayStyle(DisplayStyle displayStyle, Resources resources) {
int padding = 0;
if (displayStyle.horizontal == HorizontalDisplayStyle.WIDE) {
int screenWidthDp = resources.getConfiguration().screenWidthDp;
padding = (int) (((screenWidthDp - UiConfig.WIDE_DISPLAY_STYLE_MIN_WIDTH_DP) / 2.f)
* resources.getDisplayMetrics().density);
padding = (int) Math.max(
resources.getDimensionPixelSize(R.dimen.promo_compact_padding), padding);
}
return padding;
}
private class ItemDecorationImpl extends ItemDecoration {
private final int mInterImagePaddingPx;
private final int mVerticalInterCardPaddingPx;
private final int mHorizontalStartPaddingPx;
public ItemDecorationImpl(Resources resources) {
mInterImagePaddingPx = resources.getDimensionPixelOffset(R.dimen.card_padding);
mVerticalInterCardPaddingPx = resources.getDimensionPixelOffset(R.dimen.card_padding);
mHorizontalStartPaddingPx =
resources.getDimensionPixelOffset(R.dimen.promo_compact_padding);
}
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull State state) {
outRect.top = mInterImagePaddingPx / 2;
outRect.bottom = mInterImagePaddingPx / 2;
outRect.top = mVerticalInterCardPaddingPx / 2;
outRect.bottom = mVerticalInterCardPaddingPx / 2;
outRect.left = mHorizontalStartPaddingPx;
outRect.right = mHorizontalStartPaddingPx;
}
}
}
\ No newline at end of file
......@@ -16,7 +16,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.action.ViewActions;
import androidx.test.filters.SmallTest;
......@@ -73,8 +72,8 @@ public class TutorialListCoordinatorTest {
org.chromium.chrome.browser.video_tutorials.R.drawable.btn_close);
TestImageFetcher imageFetcher = new TestImageFetcher(testImage);
mCoordinator = new TutorialListCoordinatorImpl(
(RecyclerView) mContentView.findViewById(R.id.recycler_view),
mTestVideoTutorialService, imageFetcher, mClickCallback);
mContentView.findViewById(R.id.video_tutorial_list), mTestVideoTutorialService,
imageFetcher, mClickCallback);
});
}
......
......@@ -8,11 +8,9 @@ import android.content.Context;
import android.text.TextUtils;
import org.chromium.base.Callback;
import org.chromium.chrome.browser.video_tutorials.Language;
import org.chromium.chrome.browser.video_tutorials.LanguageInfoProvider;
import org.chromium.chrome.browser.video_tutorials.PlaybackStateObserver;
import org.chromium.chrome.browser.video_tutorials.PlaybackStateObserver.WatchStateInfo.State;
import org.chromium.chrome.browser.video_tutorials.R;
import org.chromium.chrome.browser.video_tutorials.Tutorial;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialUtils;
......@@ -140,7 +138,6 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
mModel.set(VideoPlayerProperties.SHOW_TRY_NOW,
VideoTutorialUtils.shouldShowTryNow(mTutorial.featureType));
mModel.set(VideoPlayerProperties.WATCH_STATE_FOR_TRY_NOW, State.ENDED);
updateChangeLanguageButtonText();
}
@Override
......@@ -154,19 +151,8 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.CHANGE_LANGUAGE);
}
private void updateChangeLanguageButtonText() {
String preferredLocale = mVideoTutorialService.getPreferredLocale();
Language language = mLanguageInfoProvider.getLanguageInfo(preferredLocale);
if (language == null) return;
String buttonText = mContext.getResources().getString(
R.string.video_tutorials_change_language, language.nativeName);
mModel.set(VideoPlayerProperties.CHANGE_LANGUAGE_BUTTON_TEXT, buttonText);
}
private void onLanguageSelected() {
mModel.set(VideoPlayerProperties.SHOW_LANGUAGE_PICKER, false);
updateChangeLanguageButtonText();
mVideoTutorialService.getTutorial(mTutorial.featureType, this::startVideo);
}
......
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