зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1308525 - Update activity stream panel to follow new UX mocks. r=Grisha
Okay, this patch is much bigger than I anticipated. However at this point it is impossible to separate all the interweaved changes. * Update sizes and colors * Use a dynamic number of top sites tiles to adjust to the screen size * Do not keep references (to possible outdated) Cursors from every top sites page * Remove unused bottom panel * Add menu button to highlights items MozReview-Commit-ID: 2CeEGCOXBKl --HG-- extra : rebase_source : a780ec20fa6f87520c3418403ae4fe259ff39d69
This commit is contained in:
Родитель
3027242882
Коммит
b600b36c33
|
@ -66,8 +66,10 @@ public class ActivityStream {
|
|||
*
|
||||
* This method implements the proposal from this desktop AS issue:
|
||||
* https://github.com/mozilla/activity-stream/issues/1311
|
||||
*
|
||||
* @param usePath Use the path of the URL to extract a label (if suitable)
|
||||
*/
|
||||
public static String extractLabel(String url) {
|
||||
public static String extractLabel(String url, boolean usePath) {
|
||||
if (TextUtils.isEmpty(url)) {
|
||||
return "";
|
||||
}
|
||||
|
@ -75,21 +77,23 @@ public class ActivityStream {
|
|||
final Uri uri = Uri.parse(url);
|
||||
|
||||
// Use last path segment if suitable
|
||||
final String segment = uri.getLastPathSegment();
|
||||
if (!TextUtils.isEmpty(segment)
|
||||
&& !UNDESIRED_LABELS.contains(segment)
|
||||
&& !segment.matches("^[0-9]+$")) {
|
||||
if (usePath) {
|
||||
final String segment = uri.getLastPathSegment();
|
||||
if (!TextUtils.isEmpty(segment)
|
||||
&& !UNDESIRED_LABELS.contains(segment)
|
||||
&& !segment.matches("^[0-9]+$")) {
|
||||
|
||||
boolean hasUndesiredPrefix = false;
|
||||
for (int i = 0; i < UNDESIRED_LABEL_PREFIXES.size(); i++) {
|
||||
if (segment.startsWith(UNDESIRED_LABEL_PREFIXES.get(i))) {
|
||||
hasUndesiredPrefix = true;
|
||||
break;
|
||||
boolean hasUndesiredPrefix = false;
|
||||
for (int i = 0; i < UNDESIRED_LABEL_PREFIXES.size(); i++) {
|
||||
if (segment.startsWith(UNDESIRED_LABEL_PREFIXES.get(i))) {
|
||||
hasUndesiredPrefix = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasUndesiredPrefix) {
|
||||
return segment;
|
||||
if (!hasUndesiredPrefix) {
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,23 +5,26 @@
|
|||
package org.mozilla.gecko.home.activitystream;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v4.graphics.ColorUtils;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.mozilla.gecko.GeckoProfile;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.db.BrowserDB;
|
||||
import org.mozilla.gecko.home.HomePager;
|
||||
import org.mozilla.gecko.home.SimpleCursorLoader;
|
||||
import org.mozilla.gecko.home.activitystream.topsites.TopSitesPagerAdapter;
|
||||
import org.mozilla.gecko.util.ContextUtils;
|
||||
import org.mozilla.gecko.widget.RecyclerViewClickSupport;
|
||||
|
||||
public class ActivityStream extends FrameLayout {
|
||||
|
@ -30,9 +33,18 @@ public class ActivityStream extends FrameLayout {
|
|||
private static final int LOADER_ID_HIGHLIGHTS = 0;
|
||||
private static final int LOADER_ID_TOPSITES = 1;
|
||||
|
||||
private static final int MINIMUM_TILES = 4;
|
||||
private static final int MAXIMUM_TILES = 6;
|
||||
|
||||
private int desiredTileWidth;
|
||||
private int desiredTilesHeight;
|
||||
private int tileMargin;
|
||||
|
||||
public ActivityStream(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.about_page_header_grey));
|
||||
|
||||
inflate(context, R.layout.as_content, this);
|
||||
|
||||
adapter = new StreamRecyclerAdapter();
|
||||
|
@ -45,6 +57,11 @@ public class ActivityStream extends FrameLayout {
|
|||
|
||||
RecyclerViewClickSupport.addTo(rv)
|
||||
.setOnItemClickListener(adapter);
|
||||
|
||||
final Resources resources = getResources();
|
||||
desiredTileWidth = resources.getDimensionPixelSize(R.dimen.activity_stream_desired_tile_width);
|
||||
desiredTilesHeight = resources.getDimensionPixelSize(R.dimen.activity_stream_desired_tile_height);
|
||||
tileMargin = resources.getDimensionPixelSize(R.dimen.activity_stream_base_margin);
|
||||
}
|
||||
|
||||
void setOnUrlOpenListener(HomePager.OnUrlOpenListener listener) {
|
||||
|
@ -63,6 +80,36 @@ public class ActivityStream extends FrameLayout {
|
|||
adapter.swapTopSitesCursor(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
|
||||
int tiles = (w - tileMargin) / (desiredTileWidth + tileMargin);
|
||||
|
||||
if (tiles < MINIMUM_TILES) {
|
||||
tiles = MINIMUM_TILES;
|
||||
|
||||
setPadding(0, 0, 0, 0);
|
||||
} else if (tiles > MAXIMUM_TILES) {
|
||||
tiles = MAXIMUM_TILES;
|
||||
|
||||
// Use the remaining space as padding
|
||||
int needed = tiles * (desiredTileWidth + tileMargin) + tileMargin;
|
||||
int padding = (w - needed) / 2;
|
||||
w = needed;
|
||||
|
||||
setPadding(padding, 0, padding, 0);
|
||||
} else {
|
||||
setPadding(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
final float ratio = (float) desiredTilesHeight / (float) desiredTileWidth;
|
||||
final int tilesWidth = (w - (tiles * tileMargin) - tileMargin) / tiles;
|
||||
final int tilesHeight = (int) (ratio * tilesWidth);
|
||||
|
||||
adapter.setTileSize(tiles, tilesWidth, tilesHeight);
|
||||
}
|
||||
|
||||
private class CursorLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
|
@ -71,7 +118,7 @@ public class ActivityStream extends FrameLayout {
|
|||
return BrowserDB.from(context).getHighlights(context, 10);
|
||||
} else if (id == LOADER_ID_TOPSITES) {
|
||||
return BrowserDB.from(context).getActivityStreamTopSites(
|
||||
context, TopSitesPagerAdapter.TOTAL_ITEMS);
|
||||
context, TopSitesPagerAdapter.PAGES * MAXIMUM_TILES);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Can't handle loader id " + id);
|
||||
}
|
||||
|
|
|
@ -4,11 +4,18 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.gecko.home.activitystream;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Color;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.TypedValue;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
|
@ -19,21 +26,21 @@ import org.mozilla.gecko.home.activitystream.topsites.TopSitesPagerAdapter;
|
|||
import org.mozilla.gecko.icons.IconCallback;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
import org.mozilla.gecko.icons.Icons;
|
||||
import org.mozilla.gecko.util.DrawableUtil;
|
||||
import org.mozilla.gecko.widget.FaviconView;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import static org.mozilla.gecko.activitystream.ActivityStream.extractLabel;
|
||||
|
||||
public abstract class StreamItem extends RecyclerView.ViewHolder {
|
||||
public StreamItem(View itemView) {
|
||||
super(itemView);
|
||||
}
|
||||
|
||||
public void bind(Cursor cursor) {
|
||||
throw new IllegalStateException("Cannot bind " + this.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
public static class TopPanel extends StreamItem {
|
||||
public static final int LAYOUT_ID = R.layout.activity_stream_main_toppanel;
|
||||
|
||||
private final ViewPager topSitesPager;
|
||||
|
||||
public TopPanel(View itemView, HomePager.OnUrlOpenListener onUrlOpenListener) {
|
||||
|
@ -46,17 +53,18 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
indicator.setViewPager(topSitesPager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Cursor cursor) {
|
||||
((TopSitesPagerAdapter) topSitesPager.getAdapter()).swapCursor(cursor);
|
||||
}
|
||||
}
|
||||
public void bind(Cursor cursor, int tiles, int tilesWidth, int tilesHeight) {
|
||||
final TopSitesPagerAdapter adapter = (TopSitesPagerAdapter) topSitesPager.getAdapter();
|
||||
adapter.setTilesSize(tiles, tilesWidth, tilesHeight);
|
||||
adapter.swapCursor(cursor);
|
||||
|
||||
public static class BottomPanel extends StreamItem {
|
||||
public static final int LAYOUT_ID = R.layout.activity_stream_main_bottompanel;
|
||||
final Resources resources = itemView.getResources();
|
||||
final int tilesMargin = resources.getDimensionPixelSize(R.dimen.activity_stream_base_margin);
|
||||
final int textHeight = resources.getDimensionPixelSize(R.dimen.activity_stream_top_sites_text_height);
|
||||
|
||||
public BottomPanel(View itemView) {
|
||||
super(itemView);
|
||||
ViewGroup.LayoutParams layoutParams = topSitesPager.getLayoutParams();
|
||||
layoutParams.height = tilesHeight + tilesMargin + textHeight;
|
||||
topSitesPager.setLayoutParams(layoutParams);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,19 +75,29 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
final TextView vLabel;
|
||||
final TextView vTimeSince;
|
||||
final TextView vSourceView;
|
||||
final TextView vPageView;
|
||||
|
||||
private Future<IconResponse> ongoingIconLoad;
|
||||
private int tilesMargin;
|
||||
|
||||
public HighlightItem(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
tilesMargin = itemView.getResources().getDimensionPixelSize(R.dimen.activity_stream_base_margin);
|
||||
|
||||
vLabel = (TextView) itemView.findViewById(R.id.card_history_label);
|
||||
vTimeSince = (TextView) itemView.findViewById(R.id.card_history_time_since);
|
||||
vIconView = (FaviconView) itemView.findViewById(R.id.icon);
|
||||
vSourceView = (TextView) itemView.findViewById(R.id.card_history_source);
|
||||
vPageView = (TextView) itemView.findViewById(R.id.page);
|
||||
|
||||
ImageView menuButton = (ImageView) itemView.findViewById(R.id.menu);
|
||||
|
||||
menuButton.setImageDrawable(
|
||||
DrawableUtil.tintDrawable(menuButton.getContext(), R.drawable.menu, Color.LTGRAY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind(Cursor cursor) {
|
||||
public void bind(Cursor cursor, int tilesWidth, int tilesHeight) {
|
||||
final long time = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Highlights.DATE));
|
||||
final String ago = DateUtils.getRelativeTimeSpanString(time, System.currentTimeMillis(), DateUtils.MINUTE_IN_MILLIS, 0).toString();
|
||||
final String url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
|
@ -87,7 +105,13 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
vLabel.setText(cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.History.TITLE)));
|
||||
vTimeSince.setText(ago);
|
||||
|
||||
ViewGroup.LayoutParams layoutParams = vIconView.getLayoutParams();
|
||||
layoutParams.width = tilesWidth - tilesMargin;
|
||||
layoutParams.height = tilesHeight;
|
||||
vIconView.setLayoutParams(layoutParams);
|
||||
|
||||
updateSource(cursor);
|
||||
updatePage(url);
|
||||
|
||||
if (ongoingIconLoad != null) {
|
||||
ongoingIconLoad.cancel(true);
|
||||
|
@ -117,6 +141,16 @@ public abstract class StreamItem extends RecyclerView.ViewHolder {
|
|||
vSourceView.setText(vSourceView.getText());
|
||||
}
|
||||
|
||||
private void updatePage(String url) {
|
||||
final String label = extractLabel(url, false);
|
||||
|
||||
if (!TextUtils.isEmpty(label)) {
|
||||
vPageView.setText(label);
|
||||
} else {
|
||||
vPageView.setText(url);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIconResponse(IconResponse response) {
|
||||
vIconView.updateImage(response);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.home.activitystream;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
@ -12,7 +13,6 @@ import android.view.ViewGroup;
|
|||
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.home.HomePager;
|
||||
import org.mozilla.gecko.home.activitystream.StreamItem.BottomPanel;
|
||||
import org.mozilla.gecko.home.activitystream.StreamItem.HighlightItem;
|
||||
import org.mozilla.gecko.home.activitystream.StreamItem.TopPanel;
|
||||
import org.mozilla.gecko.widget.RecyclerViewClickSupport;
|
||||
|
@ -25,16 +25,26 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
|
||||
private HomePager.OnUrlOpenListener onUrlOpenListener;
|
||||
|
||||
private int tiles;
|
||||
private int tilesWidth;
|
||||
private int tilesHeight;
|
||||
|
||||
void setOnUrlOpenListener(HomePager.OnUrlOpenListener onUrlOpenListener) {
|
||||
this.onUrlOpenListener = onUrlOpenListener;
|
||||
}
|
||||
|
||||
public void setTileSize(int tiles, int tilesWidth, int tilesHeight) {
|
||||
this.tilesWidth = tilesWidth;
|
||||
this.tilesHeight = tilesHeight;
|
||||
this.tiles = tiles;
|
||||
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == 0) {
|
||||
return TopPanel.LAYOUT_ID;
|
||||
} else if (position == getItemCount() - 1) {
|
||||
return BottomPanel.LAYOUT_ID;
|
||||
} else {
|
||||
return HighlightItem.LAYOUT_ID;
|
||||
}
|
||||
|
@ -46,8 +56,6 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
|
||||
if (type == TopPanel.LAYOUT_ID) {
|
||||
return new TopPanel(inflater.inflate(type, parent, false), onUrlOpenListener);
|
||||
} else if (type == BottomPanel.LAYOUT_ID) {
|
||||
return new BottomPanel(inflater.inflate(type, parent, false));
|
||||
} else if (type == HighlightItem.LAYOUT_ID) {
|
||||
return new HighlightItem(inflater.inflate(type, parent, false));
|
||||
} else {
|
||||
|
@ -56,8 +64,7 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
}
|
||||
|
||||
private int translatePositionToCursor(int position) {
|
||||
if (position == 0 ||
|
||||
position == getItemCount() - 1) {
|
||||
if (position == 0) {
|
||||
throw new IllegalArgumentException("Requested cursor position for invalid item");
|
||||
}
|
||||
|
||||
|
@ -73,9 +80,9 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
final int cursorPosition = translatePositionToCursor(position);
|
||||
|
||||
highlightsCursor.moveToPosition(cursorPosition);
|
||||
holder.bind(highlightsCursor);
|
||||
((HighlightItem) holder).bind(highlightsCursor, tilesWidth, tilesHeight);
|
||||
} else if (type == TopPanel.LAYOUT_ID) {
|
||||
holder.bind(topSitesCursor);
|
||||
((TopPanel) holder).bind(topSitesCursor, tiles, tilesWidth, tilesHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +111,7 @@ public class StreamRecyclerAdapter extends RecyclerView.Adapter<StreamItem> impl
|
|||
highlightsCount = 0;
|
||||
}
|
||||
|
||||
return 2 + highlightsCount;
|
||||
return highlightsCount + 1;
|
||||
}
|
||||
|
||||
public void swapHighlightsCursor(Cursor cursor) {
|
||||
|
|
|
@ -4,17 +4,18 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.gecko.home.activitystream.topsites;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.graphics.Color;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
import org.mozilla.gecko.activitystream.ActivityStream;
|
||||
import org.mozilla.gecko.icons.IconCallback;
|
||||
import org.mozilla.gecko.icons.IconResponse;
|
||||
import org.mozilla.gecko.icons.Icons;
|
||||
import org.mozilla.gecko.util.DrawableUtil;
|
||||
import org.mozilla.gecko.widget.FaviconView;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -23,31 +24,28 @@ class TopSitesCard extends RecyclerView.ViewHolder implements IconCallback {
|
|||
private final FaviconView faviconView;
|
||||
|
||||
private final TextView title;
|
||||
private final View menuButton;
|
||||
private final ImageView menuButton;
|
||||
private Future<IconResponse> ongoingIconLoad;
|
||||
|
||||
private String url;
|
||||
|
||||
public TopSitesCard(CardView card) {
|
||||
public TopSitesCard(FrameLayout card) {
|
||||
super(card);
|
||||
|
||||
faviconView = (FaviconView) card.findViewById(R.id.favicon);
|
||||
|
||||
title = (TextView) card.findViewById(R.id.title);
|
||||
menuButton = card.findViewById(R.id.menu);
|
||||
menuButton = (ImageView) card.findViewById(R.id.menu);
|
||||
}
|
||||
|
||||
void bind(Cursor cursor) {
|
||||
this.url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
|
||||
title.setText(cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.TITLE)));
|
||||
void bind(TopSitesPageAdapter.TopSite topSite) {
|
||||
final String label = ActivityStream.extractLabel(topSite.url, true);
|
||||
title.setText(label);
|
||||
|
||||
if (ongoingIconLoad != null) {
|
||||
ongoingIconLoad.cancel(true);
|
||||
}
|
||||
|
||||
ongoingIconLoad = Icons.with(itemView.getContext())
|
||||
.pageUrl(url)
|
||||
.pageUrl(topSite.url)
|
||||
.skipNetwork()
|
||||
.build()
|
||||
.execute(this);
|
||||
|
@ -56,5 +54,10 @@ class TopSitesCard extends RecyclerView.ViewHolder implements IconCallback {
|
|||
@Override
|
||||
public void onIconResponse(IconResponse response) {
|
||||
faviconView.updateImage(response);
|
||||
|
||||
final int tintColor = !response.hasColor() || response.getColor() == Color.WHITE ? Color.LTGRAY : Color.WHITE;
|
||||
|
||||
menuButton.setImageDrawable(
|
||||
DrawableUtil.tintDrawable(menuButton.getContext(), R.drawable.menu, tintColor));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,16 @@ public class TopSitesPage
|
|||
@Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
setLayoutManager(new GridLayoutManager(context, TopSitesPagerAdapter.GRID_WIDTH));
|
||||
setLayoutManager(new GridLayoutManager(context, 1));
|
||||
|
||||
RecyclerViewClickSupport.addTo(this)
|
||||
.setOnItemClickListener(this);
|
||||
}
|
||||
|
||||
public void setTiles(int tiles) {
|
||||
setLayoutManager(new GridLayoutManager(getContext(), tiles));
|
||||
}
|
||||
|
||||
private HomePager.OnUrlOpenListener onUrlOpenListener = null;
|
||||
|
||||
public TopSitesPageAdapter getAdapter() {
|
||||
|
|
|
@ -4,52 +4,51 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
package org.mozilla.gecko.home.activitystream.topsites;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.CursorWrapper;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v7.widget.CardView;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.db.BrowserContract;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TopSitesPageAdapter extends RecyclerView.Adapter<TopSitesCard> {
|
||||
static final class TopSite {
|
||||
public final long id;
|
||||
public final String url;
|
||||
|
||||
/**
|
||||
* Cursor wrapper that handles the offsets and limits that we expect.
|
||||
* This allows most of our code to completely ignore the fact that we're only touching part
|
||||
* of the cursor.
|
||||
*/
|
||||
private static final class SubsetCursor extends CursorWrapper {
|
||||
private final int start;
|
||||
private final int count;
|
||||
|
||||
public SubsetCursor(Cursor cursor, int start, int maxCount) {
|
||||
super(cursor);
|
||||
|
||||
this.start = start;
|
||||
|
||||
if (start + maxCount < cursor.getCount()) {
|
||||
count = maxCount;
|
||||
} else {
|
||||
count = cursor.getCount() - start;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean moveToPosition(int position) {
|
||||
return super.moveToPosition(position + start);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return count;
|
||||
TopSite(long id, String url) {
|
||||
this.id = id;
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
||||
private Cursor cursor;
|
||||
private List<TopSite> topSites;
|
||||
private int tiles;
|
||||
private int tilesWidth;
|
||||
private int tilesHeight;
|
||||
private int textHeight;
|
||||
|
||||
public TopSitesPageAdapter(Context context, int tiles, int tilesWidth, int tilesHeight) {
|
||||
setHasStableIds(true);
|
||||
|
||||
this.topSites = new ArrayList<>();
|
||||
this.tiles = tiles;
|
||||
this.tilesWidth = tilesWidth;
|
||||
this.tilesHeight = tilesHeight;
|
||||
this.textHeight = context.getResources().getDimensionPixelSize(R.dimen.activity_stream_top_sites_text_height);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -58,14 +57,21 @@ public class TopSitesPageAdapter extends RecyclerView.Adapter<TopSitesCard> {
|
|||
* 3 items will be displayed by this adapter.
|
||||
*/
|
||||
public void swapCursor(Cursor cursor, int startIndex) {
|
||||
if (cursor != null) {
|
||||
if (startIndex >= cursor.getCount()) {
|
||||
throw new IllegalArgumentException("startIndex must be within Cursor range");
|
||||
}
|
||||
topSites.clear();
|
||||
|
||||
this.cursor = new SubsetCursor(cursor, startIndex, TopSitesPagerAdapter.ITEMS_PER_PAGE);
|
||||
} else {
|
||||
this.cursor = null;
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < tiles; i++) {
|
||||
cursor.moveToPosition(startIndex + i);
|
||||
|
||||
// The Combined View only contains pages that have been visited at least once, i.e. any
|
||||
// page in the TopSites query will contain a HISTORY_ID. _ID however will be 0 for all rows.
|
||||
final long id = cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Combined.HISTORY_ID));
|
||||
final String url = cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
|
||||
topSites.add(new TopSite(id, url));
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
|
@ -73,46 +79,37 @@ public class TopSitesPageAdapter extends RecyclerView.Adapter<TopSitesCard> {
|
|||
|
||||
@Override
|
||||
public void onBindViewHolder(TopSitesCard holder, int position) {
|
||||
cursor.moveToPosition(position);
|
||||
holder.bind(cursor);
|
||||
}
|
||||
|
||||
public TopSitesPageAdapter() {
|
||||
setHasStableIds(true);
|
||||
holder.bind(topSites.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TopSitesCard onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
|
||||
|
||||
final CardView card = (CardView) inflater.inflate(R.layout.activity_stream_topsites_card, parent, false);
|
||||
final FrameLayout card = (FrameLayout) inflater.inflate(R.layout.activity_stream_topsites_card, parent, false);
|
||||
final View content = card.findViewById(R.id.content);
|
||||
|
||||
ViewGroup.LayoutParams layoutParams = content.getLayoutParams();
|
||||
layoutParams.width = tilesWidth;
|
||||
layoutParams.height = tilesHeight + textHeight;
|
||||
content.setLayoutParams(layoutParams);
|
||||
|
||||
return new TopSitesCard(card);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public String getURLForPosition(int position) {
|
||||
cursor.moveToPosition(position);
|
||||
|
||||
return cursor.getString(cursor.getColumnIndexOrThrow(BrowserContract.Combined.URL));
|
||||
return topSites.get(position).url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (cursor != null) {
|
||||
return cursor.getCount();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return topSites.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@UiThread
|
||||
public long getItemId(int position) {
|
||||
cursor.moveToPosition(position);
|
||||
|
||||
// The Combined View only contains pages that have been visited at least once, i.e. any
|
||||
// page in the TopSites query will contain a HISTORY_ID. _ID however will be 0 for all rows.
|
||||
return cursor.getLong(cursor.getColumnIndexOrThrow(BrowserContract.Combined.HISTORY_ID));
|
||||
return topSites.get(position).id;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,14 +21,11 @@ import java.util.LinkedList;
|
|||
* all lower-level Adapters that populate the individual topsite items.
|
||||
*/
|
||||
public class TopSitesPagerAdapter extends PagerAdapter {
|
||||
// Note: because of RecyclerView limitations we need to also adjust the layout height when
|
||||
// GRID_HEIGHT is changed.
|
||||
public static final int GRID_HEIGHT = 1;
|
||||
public static final int GRID_WIDTH = 4;
|
||||
public static final int PAGES = 4;
|
||||
|
||||
public static final int ITEMS_PER_PAGE = GRID_HEIGHT * GRID_WIDTH;
|
||||
public static final int TOTAL_ITEMS = ITEMS_PER_PAGE * PAGES;
|
||||
private int tiles;
|
||||
private int tilesWidth;
|
||||
private int tilesHeight;
|
||||
|
||||
private LinkedList<TopSitesPage> pages = new LinkedList<>();
|
||||
|
||||
|
@ -42,9 +39,15 @@ public class TopSitesPagerAdapter extends PagerAdapter {
|
|||
this.onUrlOpenListener = onUrlOpenListener;
|
||||
}
|
||||
|
||||
public void setTilesSize(int tiles, int tilesWidth, int tilesHeight) {
|
||||
this.tilesWidth = tilesWidth;
|
||||
this.tilesHeight = tilesHeight;
|
||||
this.tiles = tiles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return count;
|
||||
return Math.min(count, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,30 +64,35 @@ public class TopSitesPagerAdapter extends PagerAdapter {
|
|||
return page;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemPosition(Object object) {
|
||||
return PagerAdapter.POSITION_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
container.removeView((View) object);
|
||||
}
|
||||
|
||||
public void swapCursor(Cursor cursor) {
|
||||
final int oldPages = getCount();
|
||||
|
||||
// Divide while rounding up: 0 items = 0 pages, 1-ITEMS_PER_PAGE items = 1 page, etc.
|
||||
if (cursor != null) {
|
||||
count = (cursor.getCount() - 1) / ITEMS_PER_PAGE + 1;
|
||||
count = (cursor.getCount() - 1) / tiles + 1;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
|
||||
final int pageDelta = count - oldPages;
|
||||
pages.clear();
|
||||
final int pageDelta = count;
|
||||
|
||||
if (pageDelta > 0) {
|
||||
final LayoutInflater inflater = LayoutInflater.from(context);
|
||||
for (int i = 0; i < pageDelta; i++) {
|
||||
final TopSitesPage page = (TopSitesPage) inflater.inflate(R.layout.activity_stream_topsites_page, null, false);
|
||||
|
||||
page.setTiles(tiles);
|
||||
page.setOnUrlOpenListener(onUrlOpenListener);
|
||||
page.setAdapter(new TopSitesPageAdapter());
|
||||
page.setAdapter(new TopSitesPageAdapter(context, tiles, tilesWidth, tilesHeight));
|
||||
pages.add(page);
|
||||
}
|
||||
} else if (pageDelta < 0) {
|
||||
|
@ -103,7 +111,7 @@ public class TopSitesPagerAdapter extends PagerAdapter {
|
|||
int startIndex = 0;
|
||||
for (TopSitesPage page : pages) {
|
||||
page.getAdapter().swapCursor(cursor, startIndex);
|
||||
startIndex += ITEMS_PER_PAGE;
|
||||
startIndex += tiles;
|
||||
}
|
||||
|
||||
notifyDataSetChanged();
|
||||
|
|
|
@ -3,14 +3,15 @@
|
|||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginLeft="12dp"
|
||||
android:layout_marginRight="12dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginEnd="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginLeft="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginRight="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginStart="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginTop="0dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
@ -18,45 +19,87 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp">
|
||||
android:padding="10dp">
|
||||
|
||||
<org.mozilla.gecko.widget.FaviconView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="@dimen/favicon_bg"
|
||||
android:layout_height="@dimen/favicon_bg"
|
||||
android:layout_gravity="center"
|
||||
gecko:enableRoundCorners="false"
|
||||
tools:background="@drawable/favicon_globe" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_gravity="right|top"
|
||||
android:padding="2dp"
|
||||
android:layout_marginLeft="@dimen/activity_stream_base_margin"
|
||||
android:layout_marginBottom="@dimen/activity_stream_base_margin"
|
||||
android:src="@drawable/menu" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/page"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="twitter"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@color/activity_stream_subtitle"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_toLeftOf="@id/menu"
|
||||
android:layout_toStartOf="@id/menu"
|
||||
android:paddingLeft="@dimen/activity_stream_base_margin"
|
||||
android:paddingStart="@dimen/activity_stream_base_margin"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/card_history_label"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:maxLines="2"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingStart="8dp"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"
|
||||
android:paddingLeft="@dimen/activity_stream_base_margin"
|
||||
android:paddingStart="@dimen/activity_stream_base_margin"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="#ff000000"
|
||||
tools:text="Descriptive title of a page..." />
|
||||
android:layout_below="@id/page"
|
||||
android:layout_toLeftOf="@id/menu"
|
||||
android:layout_toStartOf="@id/menu"
|
||||
tools:text="Descriptive title of a page that is veeeeeeery long - maybe even too long?" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingStart="8dp"
|
||||
android:layout_toEndOf="@id/icon"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:paddingLeft="@dimen/activity_stream_base_margin"
|
||||
android:paddingStart="@dimen/activity_stream_base_margin"
|
||||
android:paddingTop="4dp"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_below="@id/card_history_label">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="12dp"
|
||||
android:layout_height="12dp"
|
||||
android:background="#ff8e8e8e" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/card_history_source"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:textSize="12sp"
|
||||
android:layout_weight="1"
|
||||
android:textColor="#ff8e8e8e"
|
||||
android:textColor="@color/activity_stream_subtitle"
|
||||
tools:text="Bookmarked" />
|
||||
|
||||
<TextView
|
||||
|
@ -64,7 +107,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="12sp"
|
||||
android:textColor="#ffd2d2d2"
|
||||
android:textColor="@color/activity_stream_timestamp"
|
||||
tools:text="20m" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</LinearLayout>
|
|
@ -7,8 +7,9 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<android.support.v4.view.ViewPager
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="123dp"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/topsites_pager"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.mozilla.gecko.widget.FilledCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="115dp"
|
||||
xmlns:gecko="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_margin="1dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:id="@+id/content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<org.mozilla.gecko.widget.FaviconView
|
||||
android:id="@+id/favicon"
|
||||
|
@ -19,35 +18,42 @@
|
|||
android:layout_alignParentTop="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_gravity="center"
|
||||
tools:background="@drawable/favicon_globe"
|
||||
gecko:enableRoundCorners="false"/>
|
||||
gecko:enableRoundCorners="false"
|
||||
tools:background="@drawable/favicon_globe" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_below="@id/favicon"
|
||||
android:background="@color/activity_stream_divider" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:padding="4dp"
|
||||
android:textSize="12sp"
|
||||
android:textColor="@android:color/black"
|
||||
tools:text="Lorem Ipsum here is a title"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"/>
|
||||
tools:text="Lorem Ipsum here is a title" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/menu_button"
|
||||
android:id="@+id/menu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_gravity="right|top"
|
||||
android:padding="6dp"
|
||||
android:src="@drawable/menu"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"/>
|
||||
android:src="@drawable/menu" />
|
||||
|
||||
</RelativeLayout>
|
||||
</org.mozilla.gecko.widget.FilledCardView>
|
||||
</android.support.v7.widget.CardView>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.mozilla.gecko.home.activitystream.topsites.TopSitesPage xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="4dp"/>
|
||||
android:paddingLeft="10dp"/>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/activity_stream_main_recyclerview"
|
||||
android:background="@color/about_page_header_grey"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</merge>
|
|
@ -140,4 +140,8 @@
|
|||
|
||||
<color name="action_bar_bg_color">@color/toolbar_grey</color>
|
||||
|
||||
<color name="activity_stream_divider">#FFD2D2D2</color>
|
||||
<color name="activity_stream_subtitle">#FF919191</color>
|
||||
<color name="activity_stream_timestamp">#FFD3D3D3</color>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -216,4 +216,9 @@
|
|||
<item name="firstrun_tab_strip_content_start" type="dimen">15dp</item>
|
||||
|
||||
<item name="notification_media_cover" type="dimen">128dp</item>
|
||||
|
||||
<item name="activity_stream_base_margin" type="dimen">10dp</item>
|
||||
<item name="activity_stream_desired_tile_width" type="dimen">90dp</item>
|
||||
<item name="activity_stream_desired_tile_height" type="dimen">70dp</item>
|
||||
<item name="activity_stream_top_sites_text_height" type="dimen">30dp</item>
|
||||
</resources>
|
||||
|
|
|
@ -18,78 +18,96 @@ public class TestActivityStream {
|
|||
* https://gist.github.com/nchapman/36502ad115e8825d522a66549971a3f0
|
||||
*/
|
||||
@Test
|
||||
public void testExtractLabel() {
|
||||
public void testExtractLabelWithPath() {
|
||||
// Empty values
|
||||
|
||||
assertEquals("", ActivityStream.extractLabel(""));
|
||||
assertEquals("", ActivityStream.extractLabel(null));
|
||||
assertEquals("", ActivityStream.extractLabel("", true));
|
||||
assertEquals("", ActivityStream.extractLabel(null, true));
|
||||
|
||||
// Without path
|
||||
|
||||
assertEquals("news.ycombinator",
|
||||
ActivityStream.extractLabel("https://news.ycombinator.com/"));
|
||||
ActivityStream.extractLabel("https://news.ycombinator.com/", true));
|
||||
|
||||
assertEquals("sql.telemetry.mozilla",
|
||||
ActivityStream.extractLabel("https://sql.telemetry.mozilla.org/"));
|
||||
ActivityStream.extractLabel("https://sql.telemetry.mozilla.org/", true));
|
||||
|
||||
assertEquals("sso.mozilla",
|
||||
ActivityStream.extractLabel("http://sso.mozilla.com/"));
|
||||
ActivityStream.extractLabel("http://sso.mozilla.com/", true));
|
||||
|
||||
assertEquals("youtube",
|
||||
ActivityStream.extractLabel("http://youtube.com/"));
|
||||
ActivityStream.extractLabel("http://youtube.com/", true));
|
||||
|
||||
assertEquals("images.google",
|
||||
ActivityStream.extractLabel("http://images.google.com/"));
|
||||
ActivityStream.extractLabel("http://images.google.com/", true));
|
||||
|
||||
assertEquals("smile.amazon",
|
||||
ActivityStream.extractLabel("http://smile.amazon.com/"));
|
||||
ActivityStream.extractLabel("http://smile.amazon.com/", true));
|
||||
|
||||
assertEquals("localhost",
|
||||
ActivityStream.extractLabel("http://localhost:5000/"));
|
||||
ActivityStream.extractLabel("http://localhost:5000/", true));
|
||||
|
||||
assertEquals("independent",
|
||||
ActivityStream.extractLabel("http://www.independent.co.uk/"));
|
||||
ActivityStream.extractLabel("http://www.independent.co.uk/", true));
|
||||
|
||||
// With path
|
||||
|
||||
assertEquals("firefox",
|
||||
ActivityStream.extractLabel("https://addons.mozilla.org/en-US/firefox/"));
|
||||
ActivityStream.extractLabel("https://addons.mozilla.org/en-US/firefox/", true));
|
||||
|
||||
assertEquals("activity-stream",
|
||||
ActivityStream.extractLabel("https://trello.com/b/KX3hV8XS/activity-stream"));
|
||||
ActivityStream.extractLabel("https://trello.com/b/KX3hV8XS/activity-stream", true));
|
||||
|
||||
assertEquals("activity-stream",
|
||||
ActivityStream.extractLabel("https://github.com/mozilla/activity-stream"));
|
||||
ActivityStream.extractLabel("https://github.com/mozilla/activity-stream", true));
|
||||
|
||||
assertEquals("sidekiq",
|
||||
ActivityStream.extractLabel("https://dispatch-news.herokuapp.com/sidekiq"));
|
||||
ActivityStream.extractLabel("https://dispatch-news.herokuapp.com/sidekiq", true));
|
||||
|
||||
assertEquals("nchapman",
|
||||
ActivityStream.extractLabel("https://github.com/nchapman/"));
|
||||
ActivityStream.extractLabel("https://github.com/nchapman/", true));
|
||||
|
||||
// Unusable paths
|
||||
|
||||
assertEquals("phonebook.mozilla", // instead of "login"
|
||||
ActivityStream.extractLabel("https://phonebook.mozilla.org/mellon/login?ReturnTo=https%3A%2F%2Fphonebook.mozilla.org%2F&IdP=http%3A%2F%2Fwww.okta.com"));
|
||||
ActivityStream.extractLabel("https://phonebook.mozilla.org/mellon/login?ReturnTo=https%3A%2F%2Fphonebook.mozilla.org%2F&IdP=http%3A%2F%2Fwww.okta.com", true));
|
||||
|
||||
assertEquals("ipay.adp", // instead of "index.jsf"
|
||||
ActivityStream.extractLabel("https://ipay.adp.com/iPay/index.jsf"));
|
||||
ActivityStream.extractLabel("https://ipay.adp.com/iPay/index.jsf", true));
|
||||
|
||||
assertEquals("calendar.google", // instead of "render"
|
||||
ActivityStream.extractLabel("https://calendar.google.com/calendar/render?pli=1#main_7"));
|
||||
ActivityStream.extractLabel("https://calendar.google.com/calendar/render?pli=1#main_7", true));
|
||||
|
||||
assertEquals("myworkday", // instead of "home.htmld"
|
||||
ActivityStream.extractLabel("https://www.myworkday.com/vhr_mozilla/d/home.htmld"));
|
||||
ActivityStream.extractLabel("https://www.myworkday.com/vhr_mozilla/d/home.htmld", true));
|
||||
|
||||
assertEquals("mail.google", // instead of "1"
|
||||
ActivityStream.extractLabel("https://mail.google.com/mail/u/1/#inbox"));
|
||||
ActivityStream.extractLabel("https://mail.google.com/mail/u/1/#inbox", true));
|
||||
|
||||
assertEquals("docs.google", // instead of "edit"
|
||||
ActivityStream.extractLabel("https://docs.google.com/presentation/d/11cyrcwhKTmBdEBIZ3szLO0-_Imrx2CGV2B9_LZHDrds/edit#slide=id.g15d41bb0f3_0_82"));
|
||||
ActivityStream.extractLabel("https://docs.google.com/presentation/d/11cyrcwhKTmBdEBIZ3szLO0-_Imrx2CGV2B9_LZHDrds/edit#slide=id.g15d41bb0f3_0_82", true));
|
||||
|
||||
// Special cases
|
||||
|
||||
assertEquals("irccloud.mozilla",
|
||||
ActivityStream.extractLabel("https://irccloud.mozilla.com/#!/ircs://irc1.dmz.scl3.mozilla.com:6697/%23universal-search"));
|
||||
ActivityStream.extractLabel("https://irccloud.mozilla.com/#!/ircs://irc1.dmz.scl3.mozilla.com:6697/%23universal-search", true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExtractLabelWithoutPath() {
|
||||
assertEquals("addons.mozilla",
|
||||
ActivityStream.extractLabel("https://addons.mozilla.org/en-US/firefox/", false));
|
||||
|
||||
assertEquals("trello",
|
||||
ActivityStream.extractLabel("https://trello.com/b/KX3hV8XS/activity-stream", false));
|
||||
|
||||
assertEquals("github",
|
||||
ActivityStream.extractLabel("https://github.com/mozilla/activity-stream", false));
|
||||
|
||||
assertEquals("dispatch-news",
|
||||
ActivityStream.extractLabel("https://dispatch-news.herokuapp.com/sidekiq", false));
|
||||
|
||||
assertEquals("github",
|
||||
ActivityStream.extractLabel("https://github.com/nchapman/", false));
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче