Skip to content

Commit 3bdaf9c

Browse files
author
maskara
committed
Gracefully handling various error situations
1 parent 09fe2fe commit 3bdaf9c

File tree

4 files changed

+91
-35
lines changed

4 files changed

+91
-35
lines changed

app/src/main/java/fr/free/nrw/commons/category/CategoryImagesListFragment.java

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
import android.widget.GridView;
1313
import android.widget.ListAdapter;
1414
import android.widget.ProgressBar;
15+
import android.widget.TextView;
1516

1617
import java.util.List;
18+
import java.util.concurrent.TimeUnit;
1719

1820
import javax.inject.Inject;
1921
import javax.inject.Named;
@@ -23,19 +25,28 @@
2325
import dagger.android.support.DaggerFragment;
2426
import fr.free.nrw.commons.Media;
2527
import fr.free.nrw.commons.R;
28+
import fr.free.nrw.commons.utils.NetworkUtils;
2629
import fr.free.nrw.commons.utils.ViewUtil;
2730
import io.reactivex.Observable;
2831
import io.reactivex.android.schedulers.AndroidSchedulers;
2932
import io.reactivex.schedulers.Schedulers;
3033
import timber.log.Timber;
3134

35+
import static android.view.View.GONE;
36+
import static android.view.View.VISIBLE;
37+
3238
public class CategoryImagesListFragment extends DaggerFragment {
3339

40+
private static int TIMEOUT_SECONDS = 15;
41+
3442
private GridViewAdapter gridAdapter;
3543

44+
@BindView(R.id.statusMessage)
45+
TextView statusTextView;
3646
@BindView(R.id.loadingImagesProgressBar) ProgressBar progressBar;
3747
@BindView(R.id.categoryImagesList) GridView gridView;
3848

49+
private boolean hasMoreImages = true;
3950
private boolean isLoading;
4051
private String categoryName = null;
4152

@@ -74,29 +85,47 @@ private void resetQueryContinueValues(String keyword) {
7485

7586
@SuppressLint("CheckResult")
7687
private void initList() {
88+
if(!NetworkUtils.isInternetConnectionEstablished(getContext())) {
89+
handleNoInternet();
90+
return;
91+
}
92+
7793
isLoading = true;
78-
progressBar.setVisibility(View.VISIBLE);
94+
progressBar.setVisibility(VISIBLE);
7995
Observable.fromCallable(() -> controller.getCategoryImages(categoryName))
8096
.subscribeOn(Schedulers.io())
8197
.observeOn(AndroidSchedulers.mainThread())
82-
.subscribe(featuredImageList -> {
83-
isLoading = false;
84-
setAdapter(featuredImageList);
85-
progressBar.setVisibility(View.GONE);
86-
}, throwable -> {
87-
isLoading = false;
88-
Timber.e(throwable, "Error occurred while loading featured images");
89-
ViewUtil.showSnackbar(gridView, R.string.error_featured_images);
90-
progressBar.setVisibility(View.GONE);
91-
});
98+
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
99+
.subscribe(this::handleSuccess, this::handleError);
92100
}
93101

94-
private void setAdapter(List<Media> mediaList) {
95-
if (mediaList == null || mediaList.isEmpty()) {
96-
ViewUtil.showSnackbar(gridView, R.string.no_featured_images);
97-
return;
102+
private void handleNoInternet() {
103+
progressBar.setVisibility(GONE);
104+
if (gridAdapter == null || gridAdapter.isEmpty()) {
105+
statusTextView.setVisibility(VISIBLE);
106+
statusTextView.setText(getString(R.string.no_internet));
107+
} else {
108+
ViewUtil.showSnackbar(gridView, R.string.no_internet);
109+
}
110+
}
111+
112+
private void handleError(Throwable throwable) {
113+
Timber.e(throwable, "Error occurred while loading featured images");
114+
initErrorView();
115+
}
116+
117+
private void initErrorView() {
118+
ViewUtil.showSnackbar(gridView, R.string.error_loading_images);
119+
progressBar.setVisibility(GONE);
120+
if (gridAdapter == null || gridAdapter.isEmpty()) {
121+
statusTextView.setVisibility(VISIBLE);
122+
statusTextView.setText(getString(R.string.no_images_found));
123+
} else {
124+
statusTextView.setVisibility(GONE);
98125
}
126+
}
99127

128+
private void setAdapter(List<Media> mediaList) {
100129
gridAdapter = new GridViewAdapter(this.getContext(), R.layout.layout_category_images, mediaList);
101130
gridView.setAdapter(gridAdapter);
102131
}
@@ -109,7 +138,7 @@ public void onScrollStateChanged(AbsListView view, int scrollState) {
109138

110139
@Override
111140
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
112-
if (!isLoading && (firstVisibleItem + visibleItemCount + 1 >= totalItemCount)) {
141+
if (hasMoreImages && !isLoading && (firstVisibleItem + visibleItemCount + 1 >= totalItemCount)) {
113142
isLoading = true;
114143
fetchMoreImages();
115144
}
@@ -119,20 +148,35 @@ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun
119148

120149
@SuppressLint("CheckResult")
121150
private void fetchMoreImages() {
122-
progressBar.setVisibility(View.VISIBLE);
151+
if(!NetworkUtils.isInternetConnectionEstablished(getContext())) {
152+
handleNoInternet();
153+
return;
154+
}
155+
156+
progressBar.setVisibility(VISIBLE);
123157
Observable.fromCallable(() -> controller.getCategoryImages(categoryName))
124158
.subscribeOn(Schedulers.io())
125159
.observeOn(AndroidSchedulers.mainThread())
126-
.subscribe(collection -> {
127-
gridAdapter.addItems(collection);
128-
isLoading = false;
129-
},
130-
throwable -> {
131-
isLoading = false;
132-
Timber.e(throwable, "Error occurred while loading featured images");
133-
ViewUtil.showSnackbar(gridView, R.string.error_featured_images);
134-
progressBar.setVisibility(View.GONE);
135-
});
160+
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
161+
.subscribe(this::handleSuccess, this::handleError);
162+
}
163+
164+
private void handleSuccess(List<Media> collection) {
165+
if(collection == null || collection.isEmpty()) {
166+
initErrorView();
167+
hasMoreImages = false;
168+
return;
169+
}
170+
171+
if(gridAdapter == null) {
172+
setAdapter(collection);
173+
} else {
174+
gridAdapter.addItems(collection);
175+
}
176+
177+
progressBar.setVisibility(GONE);
178+
isLoading = false;
179+
statusTextView.setVisibility(GONE);
136180
}
137181

138182
public ListAdapter getAdapter() {

app/src/main/java/fr/free/nrw/commons/category/GridViewAdapter.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import android.widget.ArrayAdapter;
99
import android.widget.TextView;
1010

11+
import java.util.ArrayList;
1112
import java.util.List;
1213

1314
import fr.free.nrw.commons.Media;
@@ -29,10 +30,18 @@ public GridViewAdapter(Context context, int layoutResourceId, List<Media> data)
2930
}
3031

3132
public void addItems(List<Media> images) {
33+
if (data == null) {
34+
data = new ArrayList<>();
35+
}
3236
data.addAll(images);
3337
notifyDataSetChanged();
3438
}
3539

40+
@Override
41+
public boolean isEmpty() {
42+
return data == null || data.isEmpty();
43+
}
44+
3645
@Override
3746
public View getView(int position, View convertView, ViewGroup parent) {
3847

@@ -53,7 +62,8 @@ public View getView(int position, View convertView, ViewGroup parent) {
5362

5463
private void setAuthorView(Media item, TextView author) {
5564
if (item.getCreator() != null && !item.getCreator().equals("")) {
56-
author.setText(String.format("Uploaded by: %s", item.getCreator()));
65+
String uploadedByTemplate = context.getString(R.string.image_uploaded_by);
66+
author.setText(String.format(uploadedByTemplate, item.getCreator()));
5767
} else {
5868
author.setVisibility(View.GONE);
5969
}

app/src/main/res/layout/fragment_category_images.xml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<RelativeLayout
3-
xmlns:android="http://schemas.android.com/apk/res/android"
2+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
44
android:orientation="vertical"
55
android:layout_width="match_parent"
66
android:layout_height="match_parent"
7-
android:background="?attr/mainBackground"
8-
>
7+
android:background="?attr/mainBackground">
98

109
<TextView
1110
android:layout_width="wrap_content"
1211
android:layout_height="wrap_content"
1312
android:text="@string/waiting_first_sync"
14-
android:id="@+id/waitingMessage"
13+
android:id="@+id/statusMessage"
1514
android:layout_gravity="center"
1615
android:visibility="gone"
16+
tools:visibility="visible"
1717
android:layout_centerHorizontal="true"
18+
android:layout_centerVertical="true"
1819
/>
1920

2021
<ProgressBar

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@
271271
<string name="about_translate_cancel">Cancel</string>
272272
<string name="retry">Retry</string>
273273

274-
<string name="no_featured_images">No featured images found</string>
275-
<string name="error_featured_images">Error fetching featured images</string>
274+
<string name="no_images_found">No images found!</string>
275+
<string name="error_loading_images">Error occurred while loading images.</string>
276+
<string name="image_uploaded_by">Uploaded by: %1$s</string>
276277
</resources>

0 commit comments

Comments
 (0)