Mholloway has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/350430 )
Change subject: Add OfflineCard/View to to the feed
......................................................................
Add OfflineCard/View to to the feed
Adds an OfflineClient to the end of the feed content loading script, and
a corresponding card to be added to the bottom of the feed when additional
content cannot be fetched because the user is offline.
TODO: Hook up the retry button.
TODO: Add unit tests for OfflineClient.
Bug: T157381
Change-Id: I3c5375d075fc4ae8f311a67f730835bc0cff3d8b
---
M app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
M app/src/main/java/org/wikipedia/feed/FeedCoordinatorBase.java
M app/src/main/java/org/wikipedia/feed/model/CardType.java
A app/src/main/java/org/wikipedia/feed/offline/OfflineCard.java
A app/src/main/java/org/wikipedia/feed/offline/OfflineCardView.java
A app/src/main/java/org/wikipedia/feed/offline/OfflineClient.java
M app/src/main/java/org/wikipedia/feed/view/FeedAdapter.java
M app/src/main/java/org/wikipedia/util/ThrowableUtil.java
A app/src/main/res/layout/view_card_offline.xml
M app/src/main/res/values-qq/strings.xml
M app/src/main/res/values/strings.xml
11 files changed, 168 insertions(+), 10 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia
refs/changes/30/350430/1
diff --git a/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
b/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
index e8a850a..b675a88 100644
--- a/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
+++ b/app/src/main/java/org/wikipedia/feed/FeedCoordinator.java
@@ -8,6 +8,7 @@
import org.wikipedia.feed.becauseyouread.BecauseYouReadClient;
import org.wikipedia.feed.continuereading.ContinueReadingClient;
import org.wikipedia.feed.mainpage.MainPageClient;
+import org.wikipedia.feed.offline.OfflineClient;
import org.wikipedia.feed.random.RandomClient;
import org.wikipedia.feed.searchbar.SearchClient;
@@ -17,8 +18,7 @@
super(context);
}
- @Override
- protected void buildScript(int age) {
+ @Override protected void buildScript(int age) {
if (age == 0) {
addPendingClient(new SearchClient());
addPendingClient(new AnnouncementClient());
@@ -32,5 +32,10 @@
if (age == 0) {
addPendingClient(new RandomClient());
}
+
+ // OfflineClient must always come last, since we rely on the last
request in the series
+ // being a network request (and not a disk I/O request) to determine
online/offline state
+ // for purposes of updating the feed UI.
+ addPendingClient(new OfflineClient());
}
}
diff --git a/app/src/main/java/org/wikipedia/feed/FeedCoordinatorBase.java
b/app/src/main/java/org/wikipedia/feed/FeedCoordinatorBase.java
index 7ec53d7..18389a1 100644
--- a/app/src/main/java/org/wikipedia/feed/FeedCoordinatorBase.java
+++ b/app/src/main/java/org/wikipedia/feed/FeedCoordinatorBase.java
@@ -7,6 +7,8 @@
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.feed.dataclient.FeedClient;
import org.wikipedia.feed.model.Card;
+import org.wikipedia.feed.offline.OfflineCard;
+import org.wikipedia.feed.offline.OfflineClient;
import org.wikipedia.feed.progress.ProgressCard;
import org.wikipedia.settings.Prefs;
@@ -63,11 +65,15 @@
}
pendingClients.clear();
cards.clear();
- insertCard(progressCard, 0);
}
public void more(@NonNull WikiSite wiki) {
this.wiki = wiki;
+
+ if (cards.size() == 0) {
+ insertCard(progressCard, 0);
+ }
+
if (cards.size() > 1) {
currentAge++;
}
@@ -122,25 +128,30 @@
}
private class ClientRequestCallback implements FeedClient.Callback {
- @Override
- public void success(@NonNull List<? extends Card> cardList) {
+ @Override public void success(@NonNull List<? extends Card> cardList) {
for (Card card : cardList) {
if (!isCardHidden(card)) {
- int progressPos = cards.indexOf(progressCard);
- insertCard(card, progressPos >= 0 ? progressPos :
cards.size());
+ appendCard(card);
}
}
//noinspection ConstantConditions
requestNextCard(wiki);
}
- @Override
- public void error(@NonNull Throwable caught) {
+ @Override public void error(@NonNull Throwable caught) {
+ if (caught instanceof OfflineClient.OfflineException) {
+ appendCard(new OfflineCard());
+ }
//noinspection ConstantConditions
requestNextCard(wiki);
}
}
+ private void appendCard(@NonNull Card card) {
+ int progressPos = cards.indexOf(progressCard);
+ insertCard(card, progressPos >= 0 ? progressPos : cards.size());
+ }
+
private void insertCard(@NonNull Card card, int position) {
cards.add(position, card);
if (updateListener != null) {
diff --git a/app/src/main/java/org/wikipedia/feed/model/CardType.java
b/app/src/main/java/org/wikipedia/feed/model/CardType.java
index e7fd770..d721e97 100644
--- a/app/src/main/java/org/wikipedia/feed/model/CardType.java
+++ b/app/src/main/java/org/wikipedia/feed/model/CardType.java
@@ -11,6 +11,7 @@
import org.wikipedia.feed.mainpage.MainPageCardView;
import org.wikipedia.feed.mostread.MostReadCardView;
import org.wikipedia.feed.news.NewsListCardView;
+import org.wikipedia.feed.offline.OfflineCardView;
import org.wikipedia.feed.progress.ProgressCardView;
import org.wikipedia.feed.random.RandomCardView;
import org.wikipedia.feed.searchbar.SearchCardView;
@@ -83,6 +84,11 @@
return new AnnouncementCardView(ctx);
}
},
+ OFFLINE(98) {
+ @NonNull @Override public FeedCardView<?> newView(@NonNull Context
ctx) {
+ return new OfflineCardView(ctx);
+ }
+ },
PROGRESS(99) {
@NonNull @Override public FeedCardView<?> newView(@NonNull Context
ctx) {
return new ProgressCardView(ctx);
diff --git a/app/src/main/java/org/wikipedia/feed/offline/OfflineCard.java
b/app/src/main/java/org/wikipedia/feed/offline/OfflineCard.java
new file mode 100644
index 0000000..2bd4212
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/feed/offline/OfflineCard.java
@@ -0,0 +1,12 @@
+package org.wikipedia.feed.offline;
+
+import android.support.annotation.NonNull;
+
+import org.wikipedia.feed.model.Card;
+import org.wikipedia.feed.model.CardType;
+
+public class OfflineCard extends Card {
+ @NonNull @Override public CardType type() {
+ return CardType.OFFLINE;
+ }
+}
diff --git a/app/src/main/java/org/wikipedia/feed/offline/OfflineCardView.java
b/app/src/main/java/org/wikipedia/feed/offline/OfflineCardView.java
new file mode 100644
index 0000000..6434173
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/feed/offline/OfflineCardView.java
@@ -0,0 +1,24 @@
+package org.wikipedia.feed.offline;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.widget.LinearLayout;
+
+import org.wikipedia.R;
+import org.wikipedia.feed.model.Card;
+import org.wikipedia.feed.view.FeedAdapter;
+import org.wikipedia.feed.view.FeedCardView;
+
+public class OfflineCardView extends LinearLayout implements
FeedCardView<Card> {
+ public OfflineCardView(Context context) {
+ super(context);
+ inflate(getContext(), R.layout.view_card_offline, this);
+ }
+
+ @Override public void setCard(@NonNull Card card) { }
+ @Override public Card getCard() {
+ return null;
+ }
+ @Override public void setCallback(@Nullable FeedAdapter.Callback callback)
{ }
+}
diff --git a/app/src/main/java/org/wikipedia/feed/offline/OfflineClient.java
b/app/src/main/java/org/wikipedia/feed/offline/OfflineClient.java
new file mode 100644
index 0000000..f8d1d35
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/feed/offline/OfflineClient.java
@@ -0,0 +1,66 @@
+package org.wikipedia.feed.offline;
+
+import android.content.Context;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import org.wikipedia.dataclient.WikiSite;
+import org.wikipedia.dataclient.retrofit.MwCachedService;
+import org.wikipedia.dataclient.retrofit.WikiCachedService;
+import org.wikipedia.feed.dataclient.FeedClient;
+import org.wikipedia.feed.model.Card;
+import org.wikipedia.util.ThrowableUtil;
+
+import java.util.Collections;
+
+import retrofit2.Call;
+import retrofit2.Response;
+import retrofit2.http.GET;
+import retrofit2.http.Headers;
+
+/* Hit an arbitrary known-good test URL to determine the current
online/offline state. */
+public class OfflineClient implements FeedClient {
+ private static final String TEST_URL = "w/api.php";
+
+ @NonNull private final WikiCachedService<Service> cachedService = new
MwCachedService<>(Service.class);
+ @Nullable private Call<Object> call;
+
+ @Override public void request(@NonNull Context context, @NonNull WikiSite
wiki, int age,
+ @NonNull final Callback cb) {
+ cancel();
+ call = cachedService.service(wiki).get();
+ call.enqueue(new retrofit2.Callback<Object>() {
+ @Override public void onResponse(Call<Object> call,
Response<Object> response) {
+ cb.success(Collections.<Card>emptyList());
+ }
+
+ @Override public void onFailure(Call<Object> call, Throwable
caught) {
+ cb.error(ThrowableUtil.isOffline(caught) ? new
OfflineException(caught) : caught);
+ }
+ });
+ }
+
+ @Override public void cancel() {
+ if (call == null) {
+ return;
+ }
+ call.cancel();
+ call = null;
+ }
+
+ public static class OfflineException extends RuntimeException {
+ private Throwable caught;
+ OfflineException(Throwable caught) {
+ this.caught = caught;
+ }
+ public Throwable caught() {
+ return caught;
+ }
+ }
+
+ private interface Service {
+ @Headers("cache-control: no-cache")
+ @GET(TEST_URL)
+ @NonNull Call<Object> get();
+ }
+}
diff --git a/app/src/main/java/org/wikipedia/feed/view/FeedAdapter.java
b/app/src/main/java/org/wikipedia/feed/view/FeedAdapter.java
index 0d6e1e9..2646e4e 100644
--- a/app/src/main/java/org/wikipedia/feed/view/FeedAdapter.java
+++ b/app/src/main/java/org/wikipedia/feed/view/FeedAdapter.java
@@ -13,6 +13,7 @@
import org.wikipedia.feed.model.Card;
import org.wikipedia.feed.model.CardType;
import org.wikipedia.feed.news.NewsListCardView;
+import org.wikipedia.feed.offline.OfflineCard;
import org.wikipedia.feed.searchbar.SearchCardView;
import org.wikipedia.views.DefaultRecyclerAdapter;
import org.wikipedia.views.DefaultViewHolder;
@@ -47,6 +48,7 @@
if (coordinator.finished()
&& position == getItemCount() - 1
+ && !(item instanceof OfflineCard)
&& callback != null) {
callback.onRequestMore();
}
diff --git a/app/src/main/java/org/wikipedia/util/ThrowableUtil.java
b/app/src/main/java/org/wikipedia/util/ThrowableUtil.java
index e2d8ed2..e01ec1a 100644
--- a/app/src/main/java/org/wikipedia/util/ThrowableUtil.java
+++ b/app/src/main/java/org/wikipedia/util/ThrowableUtil.java
@@ -83,7 +83,7 @@
return result;
}
- public static boolean isOffline(@NonNull Throwable caught) {
+ public static boolean isOffline(@Nullable Throwable caught) {
return caught instanceof UnknownHostException
|| caught instanceof SocketException
|| caught instanceof SocketTimeoutException;
diff --git a/app/src/main/res/layout/view_card_offline.xml
b/app/src/main/res/layout/view_card_offline.xml
new file mode 100644
index 0000000..05aace2
--- /dev/null
+++ b/app/src/main/res/layout/view_card_offline.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_margin="12dp"
+ android:orientation="vertical"
+ android:gravity="center">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@string/view_offline_card_text"
+ android:textColor="@color/view_wiki_error_text_color"
+ android:textAlignment="center"
+ android:textSize="16sp" />
+
+ <TextView
+ style="@style/Widget.AppCompat.Button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_margin="8dp"
+ android:background="@android:color/white"
+ android:text="@string/page_error_retry"
+ android:minHeight="36dp"
+ android:textSize="14sp"
+ android:fontFamily="sans-serif-medium"
+ android:textColor="@color/view_wiki_error_text_color"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/values-qq/strings.xml
b/app/src/main/res/values-qq/strings.xml
index ba795cf..b335f91 100644
--- a/app/src/main/res/values-qq/strings.xml
+++ b/app/src/main/res/values-qq/strings.xml
@@ -482,6 +482,7 @@
{{Identical|Today}}</string>
<string name="view_announcement_card_negative_action">Button label that
allows the user to decline the action that this card is requesting.
{{Identical|No thanks}}</string>
+ <string name="view_offline_card_text">Message in the feed informing the user
that additional content cannot be loaded while offline.</string>
<string name="description_edit_text_hint">Hint text that is shown when the
description field is empty.</string>
<string name="description_edit_save">Hint for the button that is pressed for
saving the new description.
{{Identical|Publish}}</string>
diff --git a/app/src/main/res/values/strings.xml
b/app/src/main/res/values/strings.xml
index a6ed98e..96e7674 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -370,6 +370,7 @@
</plurals>
<string name="view_continue_reading_card_subtitle_today">Today</string>
<string name="view_announcement_card_negative_action">No thanks</string>
+ <string name="view_offline_card_text">Content cannot be loaded when
offline.</string>
<!-- /The Feed -->
<!-- Description editing -->
--
To view, visit https://gerrit.wikimedia.org/r/350430
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3c5375d075fc4ae8f311a67f730835bc0cff3d8b
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits