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 ...@@ -36,7 +36,7 @@ public class VideoTutorialListActivity extends SynchronousInitializationActivity
ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.IN_MEMORY_WITH_DISK_CACHE, ImageFetcherFactory.createImageFetcher(ImageFetcherConfig.IN_MEMORY_WITH_DISK_CACHE,
profile, GlobalDiscardableReferencePool.getReferencePool()); profile, GlobalDiscardableReferencePool.getReferencePool());
mCoordinator = VideoTutorialServiceFactory.createTutorialListCoordinator( mCoordinator = VideoTutorialServiceFactory.createTutorialListCoordinator(
findViewById(R.id.recycler_view), videoTutorialService, imageFetcher, findViewById(R.id.video_tutorial_list), videoTutorialService, imageFetcher,
this::onTutorialSelected); this::onTutorialSelected);
findViewById(R.id.close_button).setOnClickListener(v -> finish()); findViewById(R.id.close_button).setOnClickListener(v -> finish());
} }
......
...@@ -63,16 +63,17 @@ ...@@ -63,16 +63,17 @@
</RelativeLayout> </RelativeLayout>
<TextView <TextView
android:id="@+id/video_length" android:id="@+id/video_length"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignBottom="@id/thumbnail_wrapper" android:layout_alignBottom="@id/thumbnail_wrapper"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:layout_marginBottom="6dp" android:layout_marginBottom="6dp"
android:paddingStart="4dp" android:paddingStart="4dp"
android:paddingEnd="4dp" android:paddingEnd="4dp"
android:background="@color/modern_grey_900" android:background="@color/modern_grey_900"
android:textAppearance="@style/TextAppearance.TextSmall.Primary.Light" /> android:importantForAccessibility="no"
android:textAppearance="@style/TextAppearance.TextSmall.Primary.Light" />
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
......
...@@ -8,11 +8,12 @@ ...@@ -8,11 +8,12 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/video_tutorial_list" android:id="@+id/video_tutorial_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:paddingTop="20dp" > android:paddingTop="6dp" >
<LinearLayout <LinearLayout
android:id="@+id/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" > android:orientation="horizontal" >
...@@ -41,11 +42,19 @@ ...@@ -41,11 +42,19 @@
app:tint="@color/default_icon_color_tint_list" /> app:tint="@color/default_icon_color_tint_list" />
</LinearLayout> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView <FrameLayout
android:id="@+id/recycler_view"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginTop="16dp" android:layout_marginTop="4dp" >
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp" /> <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> </LinearLayout>
...@@ -101,6 +101,7 @@ if (is_android) { ...@@ -101,6 +101,7 @@ if (is_android) {
"//services/media_session/public/cpp/android:media_session_java", "//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_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/android_deps:androidx_recyclerview_recyclerview_java",
"//third_party/gif_player:gif_player_java", "//third_party/gif_player:gif_player_java",
"//ui/android:ui_java", "//ui/android:ui_java",
......
...@@ -71,6 +71,7 @@ ...@@ -71,6 +71,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:textAppearance="@style/TextAppearance.TextMediumThick.Primary.Light" android:textAppearance="@style/TextAppearance.TextMediumThick.Primary.Light"
android:text="@string/change_chrome_lang"
style="@style/TextButton" /> style="@style/TextButton" />
</LinearLayout> </LinearLayout>
......
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
android:layout_height="60dp" android:layout_height="60dp"
android:src="@drawable/ic_play_arrow_white_36dp" android:src="@drawable/ic_play_arrow_white_36dp"
android:tint="@color/modern_grey_800" android:tint="@color/modern_grey_800"
android:contentDescription="@string/accessibility_play_video"
app:layout_column="0" app:layout_column="0"
app:layout_row="0" app:layout_row="0"
app:layout_gravity="center" app:layout_gravity="center"
...@@ -59,6 +60,7 @@ ...@@ -59,6 +60,7 @@
app:layout_column="0" app:layout_column="0"
app:layout_row="0" app:layout_row="0"
app:layout_gravity="bottom" app:layout_gravity="bottom"
android:importantForAccessibility="no"
android:textAppearance="@style/TextAppearance.TextSmall.Primary.Light" /> android:textAppearance="@style/TextAppearance.TextSmall.Primary.Light" />
<TextView <TextView
......
...@@ -164,6 +164,9 @@ public class PlaybackStateObserver extends MediaSessionObserver { ...@@ -164,6 +164,9 @@ public class PlaybackStateObserver extends MediaSessionObserver {
long updatedPosition = (long) (mediaPosition.getPosition() long updatedPosition = (long) (mediaPosition.getPosition()
+ (elapsedTime * mediaPosition.getPlaybackRate())); + (elapsedTime * mediaPosition.getPlaybackRate()));
updatedPosition = Math.min(updatedPosition, mediaPosition.getDuration()); updatedPosition = Math.min(updatedPosition, mediaPosition.getDuration());
if (mediaPosition.getDuration() - updatedPosition < 100) {
updatedPosition = mediaPosition.getDuration();
}
return updatedPosition; return updatedPosition;
} }
......
...@@ -6,10 +6,9 @@ package org.chromium.chrome.browser.video_tutorials; ...@@ -6,10 +6,9 @@ package org.chromium.chrome.browser.video_tutorials;
import android.content.Context; import android.content.Context;
import android.util.Pair; import android.util.Pair;
import android.view.ViewGroup;
import android.view.ViewStub; import android.view.ViewStub;
import androidx.recyclerview.widget.RecyclerView;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.base.annotations.NativeMethods; import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.supplier.Supplier; import org.chromium.base.supplier.Supplier;
...@@ -61,11 +60,11 @@ public class VideoTutorialServiceFactory { ...@@ -61,11 +60,11 @@ public class VideoTutorialServiceFactory {
} }
/** See {@link TutorialListCoordinator}.*/ /** See {@link TutorialListCoordinator}.*/
public static TutorialListCoordinator createTutorialListCoordinator(RecyclerView recyclerView, public static TutorialListCoordinator createTutorialListCoordinator(ViewGroup mainView,
VideoTutorialService videoTutorialService, ImageFetcher imageFetcher, VideoTutorialService videoTutorialService, ImageFetcher imageFetcher,
Callback<Tutorial> clickCallback) { Callback<Tutorial> clickCallback) {
return new TutorialListCoordinatorImpl( return new TutorialListCoordinatorImpl(
recyclerView, videoTutorialService, imageFetcher, clickCallback); mainView, videoTutorialService, imageFetcher, clickCallback);
} }
/** @return The tracker to track Try Now button clicks. */ /** @return The tracker to track Try Now button clicks. */
......
...@@ -4,21 +4,31 @@ ...@@ -4,21 +4,31 @@
package org.chromium.chrome.browser.video_tutorials.list; package org.chromium.chrome.browser.video_tutorials.list;
import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Rect; import android.graphics.Rect;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ItemDecoration; import androidx.recyclerview.widget.RecyclerView.ItemDecoration;
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
import androidx.recyclerview.widget.RecyclerView.State; import androidx.recyclerview.widget.RecyclerView.State;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.Callback; import org.chromium.base.Callback;
import org.chromium.chrome.browser.image_fetcher.ImageFetcher; import org.chromium.chrome.browser.image_fetcher.ImageFetcher;
import org.chromium.chrome.browser.video_tutorials.R; import org.chromium.chrome.browser.video_tutorials.R;
import org.chromium.chrome.browser.video_tutorials.Tutorial; import org.chromium.chrome.browser.video_tutorials.Tutorial;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialService; 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.MVCListAdapter;
import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter; import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
...@@ -27,21 +37,25 @@ import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter; ...@@ -27,21 +37,25 @@ import org.chromium.ui.modelutil.SimpleRecyclerViewAdapter;
*/ */
public class TutorialListCoordinatorImpl implements TutorialListCoordinator { public class TutorialListCoordinatorImpl implements TutorialListCoordinator {
private final TutorialListMediator mMediator; private final TutorialListMediator mMediator;
private final ViewGroup mMainView;
private UiConfig mUiConfig;
/** /**
* Constructor. * 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 videoTutorialService The video tutorial service backend.
* @param imageFetcher An {@link ImageFetcher} to provide thumbnail images. * @param imageFetcher An {@link ImageFetcher} to provide thumbnail images.
* @param clickCallback A callback to be invoked when a tutorial is clicked. * @param clickCallback A callback to be invoked when a tutorial is clicked.
*/ */
public TutorialListCoordinatorImpl(RecyclerView recyclerView, public TutorialListCoordinatorImpl(ViewGroup mainView,
VideoTutorialService videoTutorialService, ImageFetcher imageFetcher, VideoTutorialService videoTutorialService, ImageFetcher imageFetcher,
Callback<Tutorial> clickCallback) { Callback<Tutorial> clickCallback) {
mMainView = mainView;
MVCListAdapter.ModelList listModel = new MVCListAdapter.ModelList(); MVCListAdapter.ModelList listModel = new MVCListAdapter.ModelList();
SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(listModel); SimpleRecyclerViewAdapter adapter = new SimpleRecyclerViewAdapter(listModel);
adapter.registerType(TutorialCardProperties.VIDEO_TUTORIAL_CARD_VIEW_TYPE, adapter.registerType(TutorialCardProperties.VIDEO_TUTORIAL_CARD_VIEW_TYPE,
TutorialCardViewBinder::buildView, TutorialCardViewBinder::bindView); TutorialCardViewBinder::buildView, TutorialCardViewBinder::bindView);
final RecyclerView recyclerView = mainView.findViewById(R.id.recycler_view);
recyclerView.setAdapter(adapter); recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager( recyclerView.setLayoutManager(new LinearLayoutManager(
recyclerView.getContext(), LinearLayoutManager.VERTICAL, false)); recyclerView.getContext(), LinearLayoutManager.VERTICAL, false));
...@@ -49,19 +63,72 @@ public class TutorialListCoordinatorImpl implements TutorialListCoordinator { ...@@ -49,19 +63,72 @@ public class TutorialListCoordinatorImpl implements TutorialListCoordinator {
mMediator = new TutorialListMediator(listModel, recyclerView.getContext(), mMediator = new TutorialListMediator(listModel, recyclerView.getContext(),
videoTutorialService, imageFetcher, clickCallback); 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 class ItemDecorationImpl extends ItemDecoration {
private final int mInterImagePaddingPx; private final int mVerticalInterCardPaddingPx;
private final int mHorizontalStartPaddingPx;
public ItemDecorationImpl(Resources resources) { 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 @Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
@NonNull RecyclerView parent, @NonNull State state) { @NonNull RecyclerView parent, @NonNull State state) {
outRect.top = mInterImagePaddingPx / 2; outRect.top = mVerticalInterCardPaddingPx / 2;
outRect.bottom = mInterImagePaddingPx / 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; ...@@ -16,7 +16,6 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.action.ViewActions; import androidx.test.espresso.action.ViewActions;
import androidx.test.filters.SmallTest; import androidx.test.filters.SmallTest;
...@@ -73,8 +72,8 @@ public class TutorialListCoordinatorTest { ...@@ -73,8 +72,8 @@ public class TutorialListCoordinatorTest {
org.chromium.chrome.browser.video_tutorials.R.drawable.btn_close); org.chromium.chrome.browser.video_tutorials.R.drawable.btn_close);
TestImageFetcher imageFetcher = new TestImageFetcher(testImage); TestImageFetcher imageFetcher = new TestImageFetcher(testImage);
mCoordinator = new TutorialListCoordinatorImpl( mCoordinator = new TutorialListCoordinatorImpl(
(RecyclerView) mContentView.findViewById(R.id.recycler_view), mContentView.findViewById(R.id.video_tutorial_list), mTestVideoTutorialService,
mTestVideoTutorialService, imageFetcher, mClickCallback); imageFetcher, mClickCallback);
}); });
} }
......
...@@ -8,11 +8,9 @@ import android.content.Context; ...@@ -8,11 +8,9 @@ import android.content.Context;
import android.text.TextUtils; import android.text.TextUtils;
import org.chromium.base.Callback; 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.LanguageInfoProvider;
import org.chromium.chrome.browser.video_tutorials.PlaybackStateObserver; 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.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.Tutorial;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialService; import org.chromium.chrome.browser.video_tutorials.VideoTutorialService;
import org.chromium.chrome.browser.video_tutorials.VideoTutorialUtils; import org.chromium.chrome.browser.video_tutorials.VideoTutorialUtils;
...@@ -140,7 +138,6 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer { ...@@ -140,7 +138,6 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
mModel.set(VideoPlayerProperties.SHOW_TRY_NOW, mModel.set(VideoPlayerProperties.SHOW_TRY_NOW,
VideoTutorialUtils.shouldShowTryNow(mTutorial.featureType)); VideoTutorialUtils.shouldShowTryNow(mTutorial.featureType));
mModel.set(VideoPlayerProperties.WATCH_STATE_FOR_TRY_NOW, State.ENDED); mModel.set(VideoPlayerProperties.WATCH_STATE_FOR_TRY_NOW, State.ENDED);
updateChangeLanguageButtonText();
} }
@Override @Override
...@@ -154,19 +151,8 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer { ...@@ -154,19 +151,8 @@ class VideoPlayerMediator implements PlaybackStateObserver.Observer {
VideoTutorialMetrics.recordUserAction(mTutorial.featureType, UserAction.CHANGE_LANGUAGE); 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() { private void onLanguageSelected() {
mModel.set(VideoPlayerProperties.SHOW_LANGUAGE_PICKER, false); mModel.set(VideoPlayerProperties.SHOW_LANGUAGE_PICKER, false);
updateChangeLanguageButtonText();
mVideoTutorialService.getTutorial(mTutorial.featureType, this::startVideo); 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