зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1511946 - Hint about "Switch to tab" option for AwesomeScreen's stream items; r=JanH
The behaviour of switching to an already opened tab for an item in the stream list was already in place, this patch just modifies the item's layout by adding a text hint about this possibility - "Switch to tab", dynamically, depending on if a tab is already opened or not in the current session. Each stream item will implement `Tabs.OnTabsChangedListener` and check if the changed Tab had stream's Url. If so it will pass this event to the list's Adapter which will refresh the stream item's layout. Differential Revision: https://phabricator.services.mozilla.com/D18997 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
7996faf31b
Коммит
60f4606fbe
|
@ -87,15 +87,14 @@
|
|||
tools:text="Descriptive title of a page that is veeeeeeery long - maybe even too long?" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/page_source_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_below="@id/page_title"
|
||||
android:layout_toEndOf="@id/icon_wrapper"
|
||||
android:layout_toRightOf="@id/icon_wrapper"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/activity_stream_base_margin"
|
||||
android:paddingEnd="@dimen/activity_stream_base_margin"
|
||||
android:paddingLeft="@dimen/activity_stream_base_margin"
|
||||
android:paddingRight="@dimen/activity_stream_base_margin"
|
||||
|
@ -126,4 +125,34 @@
|
|||
tools:text="Bookmarked" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/switch_tab_hint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/page_source_layout"
|
||||
android:layout_toEndOf="@id/icon_wrapper"
|
||||
android:layout_toRightOf="@id/icon_wrapper"
|
||||
android:drawableStart="@drawable/ic_url_bar_tab"
|
||||
android:drawableLeft="@drawable/ic_url_bar_tab"
|
||||
android:paddingStart="6dp"
|
||||
android:paddingLeft="6dp"
|
||||
android:paddingEnd="0dp"
|
||||
android:paddingRight="0dp"
|
||||
android:text="@string/switch_to_tab"
|
||||
android:textColor="@color/activity_stream_subtitle"
|
||||
android:textSize="12sp"
|
||||
tools:drawableLeft="@drawable/ic_url_bar_tab"
|
||||
tools:drawableStart="@drawable/ic_url_bar_tab"
|
||||
tools:text="@string/switch_to_tab" />
|
||||
|
||||
<!-- Empty bottom space added irrespective of "switch_tab_hint" or "page_source_layout"
|
||||
being the bottom view. ("switch_tab_hint" can have visibility="gone") -->
|
||||
<View
|
||||
android:id="@+id/layout_bottom_margin"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/activity_stream_base_margin"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_below="@id/switch_tab_hint" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
|
@ -148,12 +148,20 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamViewHolder
|
|||
return new StreamTitleRow(inflater.inflate(StreamTitleRow.LAYOUT_ID, parent, false), R.string.activity_stream_topstories, R.string.activity_stream_link_more, LINK_MORE_POCKET, onUrlOpenListener);
|
||||
} else if (type == RowItemType.TOP_STORIES_ITEM.getViewType() ||
|
||||
type == RowItemType.HIGHLIGHT_ITEM.getViewType()) {
|
||||
return new WebpageItemRow(inflater.inflate(WebpageItemRow.LAYOUT_ID, parent, false), new WebpageItemRow.OnMenuButtonClickListener() {
|
||||
@Override
|
||||
public void onMenuButtonClicked(final WebpageItemRow row, final int position) {
|
||||
openContextMenuForWebpageItemRow(row, position, parent, ActivityStreamTelemetry.Contract.INTERACTION_MENU_BUTTON);
|
||||
}
|
||||
});
|
||||
return new WebpageItemRow(inflater.inflate(WebpageItemRow.LAYOUT_ID, parent, false),
|
||||
new WebpageItemRow.OnMenuButtonClickListener() {
|
||||
@Override
|
||||
public void onMenuButtonClicked(final WebpageItemRow row, final int position) {
|
||||
openContextMenuForWebpageItemRow(
|
||||
row, position, parent, ActivityStreamTelemetry.Contract.INTERACTION_MENU_BUTTON);
|
||||
}
|
||||
}, new WebpageItemRow.OnContentChangedListener() {
|
||||
@Override
|
||||
public void onContentChanged(int itemPosition) {
|
||||
notifyItemChanged(itemPosition);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else if (type == RowItemType.HIGHLIGHTS_TITLE.getViewType()) {
|
||||
return new StreamTitleRow(inflater.inflate(StreamTitleRow.LAYOUT_ID, parent, false), R.string.activity_stream_highlights);
|
||||
} else if (type == RowItemType.HIGHLIGHTS_EMPTY_STATE.getViewType()) {
|
||||
|
@ -216,6 +224,24 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamViewHolder
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewAttachedToWindow(StreamViewHolder holder) {
|
||||
super.onViewAttachedToWindow(holder);
|
||||
|
||||
if (holder instanceof WebpageItemRow) {
|
||||
((WebpageItemRow) holder).initResources();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewDetachedFromWindow(StreamViewHolder holder) {
|
||||
super.onViewDetachedFromWindow(holder);
|
||||
|
||||
if (holder instanceof WebpageItemRow) {
|
||||
((WebpageItemRow) holder).doCleanup();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets a child view of the adapter visible or hidden.
|
||||
*
|
||||
|
|
|
@ -7,6 +7,7 @@ package org.mozilla.gecko.activitystream.homepanel.stream;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
@ -14,8 +15,11 @@ import android.view.ViewGroup;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
import org.mozilla.gecko.activitystream.Utils;
|
||||
import org.mozilla.gecko.activitystream.homepanel.model.WebpageRowModel;
|
||||
import org.mozilla.gecko.reader.ReaderModeUtils;
|
||||
import org.mozilla.gecko.util.DrawableUtil;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.TouchTargetUtil;
|
||||
|
@ -27,13 +31,14 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
import java.util.UUID;
|
||||
|
||||
public class WebpageItemRow extends StreamViewHolder {
|
||||
public class WebpageItemRow extends StreamViewHolder implements Tabs.OnTabsChangedListener {
|
||||
private static final String LOGTAG = "GeckoWebpageItemRow";
|
||||
|
||||
public static final int LAYOUT_ID = R.layout.activity_stream_webpage_item_row;
|
||||
private static final double SIZE_RATIO = 0.75;
|
||||
|
||||
private WebpageRowModel webpageModel;
|
||||
private OnContentChangedListener contentChangedListener;
|
||||
private int position;
|
||||
|
||||
private final StreamOverridablePageIconLayout pageIconLayout;
|
||||
|
@ -42,15 +47,21 @@ public class WebpageItemRow extends StreamViewHolder {
|
|||
private final ImageView pageSourceIconView;
|
||||
private final TextView pageSourceView;
|
||||
private final ImageView menuButton;
|
||||
private final TextView switchToTabHint;
|
||||
|
||||
public WebpageItemRow(final View itemView, final OnMenuButtonClickListener onMenuButtonClickListener) {
|
||||
public WebpageItemRow(final View itemView,
|
||||
final OnMenuButtonClickListener onMenuButtonClickListener,
|
||||
final OnContentChangedListener contentChangedListener) {
|
||||
super(itemView);
|
||||
|
||||
this.contentChangedListener = contentChangedListener;
|
||||
|
||||
pageTitleView = (TextView) itemView.findViewById(R.id.page_title);
|
||||
pageIconLayout = (StreamOverridablePageIconLayout) itemView.findViewById(R.id.page_icon);
|
||||
pageSourceView = (TextView) itemView.findViewById(R.id.page_source);
|
||||
pageDomainView = (TextView) itemView.findViewById(R.id.page_domain);
|
||||
pageSourceIconView = (ImageView) itemView.findViewById(R.id.page_source_icon);
|
||||
switchToTabHint = (TextView) itemView.findViewById(R.id.switch_tab_hint);
|
||||
|
||||
menuButton = (ImageView) itemView.findViewById(R.id.menu);
|
||||
menuButton.setImageDrawable(
|
||||
|
@ -83,6 +94,17 @@ public class WebpageItemRow extends StreamViewHolder {
|
|||
updateUiForSource(model.getSource());
|
||||
updatePageDomain();
|
||||
pageIconLayout.updateIcon(model.getUrl(), model.getImageUrl());
|
||||
|
||||
final boolean isTabOpenedForItem = isTabOpenedForItem();
|
||||
switchToTabHint.setVisibility(isTabOpenedForItem ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
public void initResources() {
|
||||
Tabs.registerOnTabsChangedListener(this);
|
||||
}
|
||||
|
||||
public void doCleanup() {
|
||||
Tabs.unregisterOnTabsChangedListener(this);
|
||||
}
|
||||
|
||||
public void updateUiForSource(Utils.HighlightSource source) {
|
||||
|
@ -172,11 +194,71 @@ public class WebpageItemRow extends StreamViewHolder {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabChanged(Tab tab, Tabs.TabEvents msg, String data) {
|
||||
final String itemUrl = webpageModel.getUrl();
|
||||
if (itemUrl == null || tab == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only interested if a matching tab has been opened/closed/switched to a different page
|
||||
final boolean validEvent = msg.equals(Tabs.TabEvents.ADDED) ||
|
||||
msg.equals(Tabs.TabEvents.CLOSED) ||
|
||||
msg.equals(Tabs.TabEvents.LOCATION_CHANGE);
|
||||
if (!validEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Actually check for any tab change regarding any of the currently displayed stream URLs
|
||||
//
|
||||
// "data" is an empty String for ADDED/CLOSED, and contains the previous/old URL during
|
||||
// LOCATION_CHANGE (the new URL is retrieved using tab.getURL()).
|
||||
//
|
||||
// Normalized tabUrl and data using "ReaderModeUtils.stripAboutReaderUrl"
|
||||
// because they can be about:reader URLs if the current or old tab page was a reader view
|
||||
final String tabUrl = ReaderModeUtils.stripAboutReaderUrl(tab.getURL());
|
||||
final String previousTabUrl = ReaderModeUtils.stripAboutReaderUrl(data);
|
||||
if (itemUrl.equals(tabUrl) || itemUrl.equals(previousTabUrl)) {
|
||||
notifyListenerAboutContentChange();
|
||||
}
|
||||
}
|
||||
|
||||
public View getTabletContextMenuAnchor() {
|
||||
return menuButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if there is an opened tab for this item's {@link #webpageModel} Url.
|
||||
*/
|
||||
private boolean isTabOpenedForItem() {
|
||||
Tab tab = Tabs.getInstance().getFirstTabForUrl(webpageModel.getUrl(), isCurrentTabInPrivateMode());
|
||||
|
||||
return tab != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this view is shown inside a private tab, independent of whether
|
||||
* a private mode theme is applied via <code>setPrivateMode(true)</code>.
|
||||
*/
|
||||
private boolean isCurrentTabInPrivateMode() {
|
||||
final Tab tab = Tabs.getInstance().getSelectedTab();
|
||||
return tab != null && tab.isPrivate();
|
||||
}
|
||||
|
||||
private void notifyListenerAboutContentChange() {
|
||||
if (contentChangedListener != null) {
|
||||
contentChangedListener.onContentChanged(getAdapterPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public interface OnMenuButtonClickListener {
|
||||
void onMenuButtonClicked(WebpageItemRow row, int position);
|
||||
}
|
||||
|
||||
/**
|
||||
* Informs upstream about changes regarding this row's content.
|
||||
*/
|
||||
public interface OnContentChangedListener {
|
||||
void onContentChanged(int itemPosition);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче