jenkins-bot has submitted this change and it was merged.

Change subject: Integrate most read
......................................................................


Integrate most read

Bug: T129082
Change-Id: I688329f705646d917e00662be57385bc2cd4e50a
---
M app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
M app/src/main/java/org/wikipedia/feed/demo/IntegerListCard.java
A app/src/main/java/org/wikipedia/feed/mostread/MostReadCardView.java
M app/src/main/java/org/wikipedia/feed/mostread/MostReadClient.java
A app/src/main/java/org/wikipedia/feed/mostread/MostReadItemCard.java
A app/src/main/java/org/wikipedia/feed/mostread/MostReadListCard.java
M app/src/main/java/org/wikipedia/feed/view/FeedRecyclerAdapter.java
M app/src/main/res/values/strings_no_translate.xml
M app/src/test/java/org/wikipedia/feed/mostread/MostReadClientTest.java
9 files changed, 214 insertions(+), 23 deletions(-)

Approvals:
  Mholloway: Looks good to me, but someone else must approve
  Dbrant: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java 
b/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
index e8a2326..33ad66e 100644
--- a/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
+++ b/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
@@ -6,6 +6,7 @@
 import org.wikipedia.feed.becauseyouread.BecauseYouReadClient;
 import org.wikipedia.feed.continuereading.ContinueReadingClient;
 import org.wikipedia.feed.demo.IntegerListClient;
+import org.wikipedia.feed.mostread.MostReadClient;
 import org.wikipedia.feed.searchbar.SearchClient;
 
 public class FeedCoordinator extends FeedCoordinatorBase {
@@ -25,6 +26,7 @@
         addPendingClient(new BecauseYouReadClient());
         addPendingClient(new ContinueReadingClient());
         addPendingClient(new IntegerListClient());
+        addPendingClient(new MostReadClient());
 
     }
 
diff --git a/app/src/main/java/org/wikipedia/feed/demo/IntegerListCard.java 
b/app/src/main/java/org/wikipedia/feed/demo/IntegerListCard.java
index b7ade21..f6e7b5d 100644
--- a/app/src/main/java/org/wikipedia/feed/demo/IntegerListCard.java
+++ b/app/src/main/java/org/wikipedia/feed/demo/IntegerListCard.java
@@ -16,7 +16,7 @@
     }
 
     @NonNull @Override public String title() {
-        return "Trending articles";
+        return "In the news";
     }
 
     @Nullable @Override public String subtitle() {
@@ -24,7 +24,7 @@
     }
 
     @Nullable @Override public String footer() {
-        return "All top read articles on Fri, April 08";
+        return "More news from Fri, April 08";
     }
 
     private static List<IntegerListItemCard> newItems() {
@@ -37,4 +37,4 @@
         }
         return items;
     }
-}
\ No newline at end of file
+}
diff --git 
a/app/src/main/java/org/wikipedia/feed/mostread/MostReadCardView.java 
b/app/src/main/java/org/wikipedia/feed/mostread/MostReadCardView.java
new file mode 100644
index 0000000..081bc9b
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/feed/mostread/MostReadCardView.java
@@ -0,0 +1,53 @@
+package org.wikipedia.feed.mostread;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+
+import org.wikipedia.feed.demo.IntegerListCard;
+import org.wikipedia.feed.view.CardFooterView;
+import org.wikipedia.feed.view.CardHeaderView;
+import org.wikipedia.feed.view.ListCardItemView;
+import org.wikipedia.feed.view.ListCardView;
+import org.wikipedia.views.DefaultViewHolder;
+
+import java.util.List;
+
+public class MostReadCardView extends ListCardView<IntegerListCard> {
+    public MostReadCardView(Context context) {
+        super(context);
+    }
+
+    public void set(@NonNull MostReadListCard card) {
+        header(card);
+        footer(card);
+        set(new RecyclerAdapter(card.items()));
+    }
+
+    private void header(@NonNull MostReadListCard card) {
+        CardHeaderView header = new CardHeaderView(getContext())
+                .setTitle(card.title())
+                .setSubtitle(card.subtitle());
+        header(header);
+    }
+
+    private void footer(@NonNull MostReadListCard card) {
+        CardFooterView footer = new CardFooterView(getContext())
+                .setText(card.footer());
+        footer.setVisibility(card.items().size() > 2 ? VISIBLE : GONE);
+        footer(footer);
+    }
+
+    private static class RecyclerAdapter extends 
ListCardView.RecyclerAdapter<MostReadItemCard> {
+        RecyclerAdapter(@NonNull List<MostReadItemCard> items) {
+            super(items);
+        }
+
+        @Override public void 
onBindViewHolder(DefaultViewHolder<ListCardItemView> holder,
+                                               int position) {
+            MostReadItemCard card = item(position);
+            holder.getView().setTitle(card.title());
+            holder.getView().setSubtitle(card.subtitle());
+            holder.getView().setImage(card.image());
+        }
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/wikipedia/feed/mostread/MostReadClient.java 
b/app/src/main/java/org/wikipedia/feed/mostread/MostReadClient.java
index ffce308..c654f7f 100644
--- a/app/src/main/java/org/wikipedia/feed/mostread/MostReadClient.java
+++ b/app/src/main/java/org/wikipedia/feed/mostread/MostReadClient.java
@@ -1,14 +1,20 @@
 package org.wikipedia.feed.mostread;
 
+import android.content.Context;
 import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
 
 import org.apache.commons.lang3.StringUtils;
 import org.wikipedia.Site;
 import org.wikipedia.dataclient.retrofit.RbCachedService;
+import org.wikipedia.feed.FeedClient;
+import org.wikipedia.feed.model.Card;
 import org.wikipedia.util.log.L;
 
 import java.util.Calendar;
+import java.util.Collections;
+import java.util.List;
 import java.util.TimeZone;
 
 import retrofit2.Call;
@@ -16,24 +22,36 @@
 import retrofit2.http.GET;
 import retrofit2.http.Path;
 
-public class MostReadClient {
-    public interface Callback {
-        void success(@NonNull MostReadArticles articles);
-    }
-
+public class MostReadClient implements FeedClient {
     @NonNull private final RbCachedService<Service> cachedService = new 
RbCachedService<>(Service.class);
+    @Nullable private Call<MostReadArticles> call;
 
-    public void request(@NonNull Site site, @NonNull Callback cb) {
-        Calendar now = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
-        request(cachedService.service(site), now, cb);
+    @Override public void request(@NonNull Context context, @NonNull Site 
site, int age,
+                                  @NonNull Callback cb) {
+        cancel();
+        Calendar time = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
+
+        time.add(Calendar.DAY_OF_MONTH, -(age + 1));
+
+        call = request(cachedService.service(site), time, cb);
     }
 
-    @VisibleForTesting void request(@NonNull Service service, @NonNull 
Calendar date,
-                                    @NonNull Callback cb) {
+    // Only handles last request made.
+    @Override public void cancel() {
+        if (call != null) {
+            call.cancel();
+            call = null;
+        }
+    }
+
+    @VisibleForTesting Call<MostReadArticles> request(@NonNull Service 
service, @NonNull Calendar date,
+                                                      @NonNull Callback cb) {
         int year = date.get(Calendar.YEAR);
         String month = leftPad(date.get(Calendar.MONTH) + 1);
         String day = leftPad(date.get(Calendar.DAY_OF_MONTH));
-        service.get(year, month, day).enqueue(new CallbackAdapter(cb));
+        @SuppressWarnings("checkstyle:hiddenfield") Call<MostReadArticles> 
call = service.get(year, month, day);
+        call.enqueue(new CallbackAdapter(cb));
+        return call;
     }
 
     @NonNull private String leftPad(int x) {
@@ -57,7 +75,9 @@
         @Override public void onResponse(Call<MostReadArticles> call,
                                          Response<MostReadArticles> response) {
             if (response.isSuccessful()) {
-                cb.success(response.body());
+                MostReadArticles result = response.body();
+                List<? extends Card> cards = Collections.singletonList(new 
MostReadListCard(result));
+                cb.success(cards);
             } else {
                 L.v(response.message());
             }
@@ -67,4 +87,4 @@
             L.v(t);
         }
     }
-}
\ No newline at end of file
+}
diff --git 
a/app/src/main/java/org/wikipedia/feed/mostread/MostReadItemCard.java 
b/app/src/main/java/org/wikipedia/feed/mostread/MostReadItemCard.java
new file mode 100644
index 0000000..c966acd
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/feed/mostread/MostReadItemCard.java
@@ -0,0 +1,30 @@
+package org.wikipedia.feed.mostread;
+
+import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import org.wikipedia.Constants;
+import org.wikipedia.feed.model.Card;
+import org.wikipedia.util.log.L;
+
+public class MostReadItemCard extends Card {
+    @NonNull private final MostReadArticle article;
+
+    public MostReadItemCard(@NonNull MostReadArticle article) {
+        this.article = article;
+    }
+
+    @NonNull @Override public String title() {
+        return article.normalizedTitle();
+    }
+
+    @Nullable @Override public String subtitle() {
+        return article.description();
+    }
+
+    @Nullable @Override public Uri image() {
+        L.d(article.thumbnails().toString());
+        return article.thumbnails().get(Constants.PREFERRED_THUMB_SIZE);
+    }
+}
\ No newline at end of file
diff --git 
a/app/src/main/java/org/wikipedia/feed/mostread/MostReadListCard.java 
b/app/src/main/java/org/wikipedia/feed/mostread/MostReadListCard.java
new file mode 100644
index 0000000..212d769
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/feed/mostread/MostReadListCard.java
@@ -0,0 +1,70 @@
+package org.wikipedia.feed.mostread;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.annotation.VisibleForTesting;
+
+import org.wikipedia.R;
+import org.wikipedia.WikipediaApp;
+import org.wikipedia.feed.model.ListCard;
+
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class MostReadListCard extends ListCard<MostReadItemCard> {
+    private static final int MAX_SIZE = 5;
+
+    @NonNull private final MostReadArticles articles;
+
+    public MostReadListCard(@NonNull MostReadArticles articles) {
+        super(toItems(articles.articles()));
+        this.articles = articles;
+    }
+
+    @NonNull @Override public String title() {
+        return getString(R.string.most_read_list_card_title, date());
+    }
+
+    @Nullable @Override public String subtitle() {
+        return date();
+    }
+
+    @Nullable @Override public String footer() {
+        // todo: the mocks show a more terse date used here but this will 
probably require TWN
+        //       support. We should investigate localization support in date 
libraries such as
+        //       Joda-Time and how TWN solves this classic problem.
+        return getString(R.string.most_read_list_card_footer, date());
+    }
+
+    @VisibleForTesting @NonNull Date getDate() {
+        return articles.date();
+    }
+
+    @NonNull private static List<MostReadItemCard> toItems(@NonNull 
List<MostReadArticle> articles) {
+        List<MostReadItemCard> cards = new ArrayList<>();
+        for (MostReadArticle article : articles) {
+            cards.add(new MostReadItemCard(article));
+        }
+        return cards.subList(0, Math.min(cards.size(), MAX_SIZE));
+    }
+
+    @NonNull private String date() {
+        // todo: consider allowing TWN date formats. It would be useful to 
have but might be
+        //       difficult for translators to write correct format specifiers 
without being able to
+        //       test them.
+        DateFormat dateFormat = 
android.text.format.DateFormat.getDateFormat(context());
+        return dateFormat.format(articles.date());
+    }
+
+    @NonNull private String getString(@StringRes int id, @Nullable Object... 
formatArgs) {
+        return context().getString(id, formatArgs);
+    }
+
+    @NonNull private Context context() {
+        return WikipediaApp.getInstance();
+    }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/wikipedia/feed/view/FeedRecyclerAdapter.java 
b/app/src/main/java/org/wikipedia/feed/view/FeedRecyclerAdapter.java
index 7771aca..5e4962a 100644
--- a/app/src/main/java/org/wikipedia/feed/view/FeedRecyclerAdapter.java
+++ b/app/src/main/java/org/wikipedia/feed/view/FeedRecyclerAdapter.java
@@ -12,6 +12,8 @@
 import org.wikipedia.feed.demo.IntegerListCard;
 import org.wikipedia.feed.demo.IntegerListCardView;
 import org.wikipedia.feed.model.Card;
+import org.wikipedia.feed.mostread.MostReadCardView;
+import org.wikipedia.feed.mostread.MostReadListCard;
 import org.wikipedia.feed.searchbar.SearchCard;
 import org.wikipedia.feed.searchbar.SearchCardView;
 import org.wikipedia.views.DefaultRecyclerAdapter;
@@ -23,6 +25,7 @@
     private static final int VIEW_TYPE_SEARCH_BAR = 0;
     private static final int VIEW_TYPE_CONTINUE_READING = 1;
     private static final int VIEW_TYPE_BECAUSE_YOU_READ = 2;
+    private static final int VIEW_TYPE_MOST_READ = 3;
     private static final int VIEW_TYPE_INTEGER_LIST = 100;
 
     public FeedRecyclerAdapter(@NonNull List<Card> items) {
@@ -45,6 +48,8 @@
             ((BecauseYouReadCardView) view).set((BecauseYouReadCard) item);
         } else if (view instanceof SearchCardView) {
             ((SearchCardView) view).set((SearchCard) item);
+        } else if (view instanceof MostReadCardView) {
+            ((MostReadCardView) view).set((MostReadListCard) item);
         } else {
             throw new IllegalStateException("Unknown type=" + view.getClass());
         }
@@ -60,6 +65,8 @@
             return VIEW_TYPE_BECAUSE_YOU_READ;
         } else if (item instanceof SearchCard) {
             return VIEW_TYPE_SEARCH_BAR;
+        } else if (item instanceof MostReadListCard) {
+            return VIEW_TYPE_MOST_READ;
         } else {
             throw new IllegalStateException("Unknown type=" + item.getClass());
         }
@@ -75,8 +82,10 @@
                 return new BecauseYouReadCardView(context);
             case VIEW_TYPE_SEARCH_BAR:
                 return new SearchCardView(context);
+            case VIEW_TYPE_MOST_READ:
+                return new MostReadCardView(context);
             default:
                 throw new IllegalArgumentException("viewType=" + viewType);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/app/src/main/res/values/strings_no_translate.xml 
b/app/src/main/res/values/strings_no_translate.xml
index 2bb7eb6..a596a53 100644
--- a/app/src/main/res/values/strings_no_translate.xml
+++ b/app/src/main/res/values/strings_no_translate.xml
@@ -46,6 +46,8 @@
     <string name="activity_feed_title">@string/feed</string>
     <string name="nav_item_feed">@string/feed</string>
     <string name="view_card_footer_button">See more</string>
+    <string name="most_read_list_card_title">Top read on %s</string>
+    <string name="most_read_list_card_footer">All top read articles on English 
Wikipedia</string>
 
     <plurals name="view_continue_reading_card_subtitle">
         <item quantity="one">1 day ago</item>
diff --git 
a/app/src/test/java/org/wikipedia/feed/mostread/MostReadClientTest.java 
b/app/src/test/java/org/wikipedia/feed/mostread/MostReadClientTest.java
index b92866f..2c9bda3 100644
--- a/app/src/test/java/org/wikipedia/feed/mostread/MostReadClientTest.java
+++ b/app/src/test/java/org/wikipedia/feed/mostread/MostReadClientTest.java
@@ -4,21 +4,24 @@
 
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
-import org.wikipedia.feed.mostread.MostReadClient.Callback;
+import org.wikipedia.feed.FeedClient.Callback;
+import org.wikipedia.feed.model.Card;
 import org.wikipedia.feed.mostread.MostReadClient.Service;
 import org.wikipedia.test.MockWebServerTest;
 
 import java.util.Calendar;
 import java.util.GregorianCalendar;
+import java.util.List;
 import java.util.TimeZone;
 
 import okhttp3.mockwebserver.RecordedRequest;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.endsWith;
+import static org.hamcrest.Matchers.greaterThan;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.notNullValue;
-import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
@@ -52,7 +55,7 @@
         RecordedRequest req = server().takeRequest();
         assertRequestIssued(req, "2016/06/01");
 
-        verify(cb, never()).success(any(MostReadArticles.class));
+        verify(cb, never()).success(anyListOf(Card.class));
     }
 
     private void assertRequestIssued(@NonNull RecordedRequest req, @NonNull 
String date) {
@@ -60,12 +63,14 @@
     }
 
     private void assertCallbackSuccess(@NonNull Callback cb, @NonNull Calendar 
date) {
-        ArgumentCaptor<MostReadArticles> captor = 
ArgumentCaptor.forClass(MostReadArticles.class);
+        @SuppressWarnings({"unchecked", "rawtypes"})
+        ArgumentCaptor<List<MostReadListCard>> captor = 
ArgumentCaptor.forClass((Class) List.class);
         verify(cb).success(captor.capture());
 
-        MostReadArticles rsp = captor.getValue();
+        List<MostReadListCard> rsp = captor.getValue();
         assertThat(rsp, notNullValue());
-        assertThat(rsp.date(), is(date.getTime()));
+        assertThat(rsp.size(), greaterThan(0));
+        assertThat(rsp.get(0).getDate(), is(date.getTime()));
     }
 
     @NonNull private Calendar calendar(int year, int month, int day) throws 
Throwable {

-- 
To view, visit https://gerrit.wikimedia.org/r/294380
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I688329f705646d917e00662be57385bc2cd4e50a
Gerrit-PatchSet: 5
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Niedzielski <sniedziel...@wikimedia.org>
Gerrit-Reviewer: BearND <bsitzm...@wikimedia.org>
Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org>
Gerrit-Reviewer: Dbrant <dbr...@wikimedia.org>
Gerrit-Reviewer: Mholloway <mhollo...@wikimedia.org>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to