Skip to content

Commit 75ca96a

Browse files
Nearby: show cached pins even when internet is unavailable (fixes #6051) (#6081)
* Place: Made location @Embedded * Nearby: Move handling map scroll to presenter * PlacesRepository: Add methods for fetching places in geo bounds * Nearby: add getScreenTopRight/BottomLeft and refactor old code * PlacesRepository: Add methods for fetching places in map bounds * Nearby: Complete offline pins implementation * Nearby offline pins: Add snackbar message * Nearby offline pins: Add javadoc --------- Co-authored-by: Nicolas Raoul <[email protected]>
1 parent 0d71da1 commit 75ca96a

File tree

9 files changed

+239
-67
lines changed

9 files changed

+239
-67
lines changed

app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class DBOpenHelper(
1818

1919
companion object {
2020
private const val DATABASE_NAME = "commons.db"
21-
private const val DATABASE_VERSION = 20
21+
private const val DATABASE_VERSION = 21
2222
const val CONTRIBUTIONS_TABLE = "contributions"
2323
private const val DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS %s"
2424
}

app/src/main/java/fr/free/nrw/commons/nearby/Place.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import android.os.Parcelable;
66
import androidx.annotation.NonNull;
77
import androidx.annotation.Nullable;
8+
import androidx.room.Embedded;
89
import androidx.room.Entity;
910
import androidx.room.PrimaryKey;
1011
import fr.free.nrw.commons.location.LatLng;
@@ -24,6 +25,7 @@ public class Place implements Parcelable {
2425
public String name;
2526
private Label label;
2627
private String longDescription;
28+
@Embedded
2729
public LatLng location;
2830
@PrimaryKey @NonNull
2931
public String entityID;

app/src/main/java/fr/free/nrw/commons/nearby/PlaceDao.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import androidx.room.OnConflictStrategy;
66
import androidx.room.Query;
77
import io.reactivex.Completable;
8+
import java.util.List;
89

910
/**
1011
* Data Access Object (DAO) for accessing the Place entity in the database.
@@ -32,6 +33,20 @@ public abstract class PlaceDao {
3233
@Query("SELECT * from place WHERE entityID=:entity")
3334
public abstract Place getPlace(String entity);
3435

36+
/**
37+
* Retrieves a list of places within the specified rectangular area.
38+
*
39+
* @param latBegin Latitudinal lower bound
40+
* @param lngBegin Longitudinal lower bound
41+
* @param latEnd Latitudinal upper bound, should be greater than `latBegin`
42+
* @param lngEnd Longitudinal upper bound, should be greater than `lngBegin`
43+
* @return The list of places within the specified rectangular geographical area.
44+
*/
45+
@Query("SELECT * from place WHERE name!='' AND latitude>=:latBegin AND longitude>=:lngBegin "
46+
+ "AND latitude<:latEnd AND longitude<:lngEnd")
47+
public abstract List<Place> fetchPlaces(double latBegin, double lngBegin,
48+
double latEnd, double lngEnd);
49+
3550
/**
3651
* Saves a Place object asynchronously into the database.
3752
*/

app/src/main/java/fr/free/nrw/commons/nearby/PlacesLocalDataSource.java

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package fr.free.nrw.commons.nearby;
22

3+
import fr.free.nrw.commons.location.LatLng;
34
import io.reactivex.Completable;
5+
import java.util.ArrayList;
6+
import java.util.List;
47
import javax.inject.Inject;
8+
import timber.log.Timber;
59

610
/**
711
* The LocalDataSource class for Places
@@ -26,6 +30,81 @@ public Place fetchPlace(String entityID){
2630
return placeDao.getPlace(entityID);
2731
}
2832

33+
/**
34+
* Retrieves a list of places from the database within the geographical area
35+
* specified by map's opposite corners.
36+
*
37+
* @param mapBottomLeft Bottom left corner of the map.
38+
* @param mapTopRight Top right corner of the map.
39+
* @return The list of saved places within the map's view.
40+
*/
41+
public List<Place> fetchPlaces(final LatLng mapBottomLeft, final LatLng mapTopRight) {
42+
class Constraint {
43+
44+
final double latBegin;
45+
final double lngBegin;
46+
final double latEnd;
47+
final double lngEnd;
48+
49+
public Constraint(final double latBegin, final double lngBegin, final double latEnd,
50+
final double lngEnd) {
51+
this.latBegin = latBegin;
52+
this.lngBegin = lngBegin;
53+
this.latEnd = latEnd;
54+
this.lngEnd = lngEnd;
55+
}
56+
}
57+
58+
final List<Constraint> constraints = new ArrayList<>();
59+
60+
if (mapTopRight.getLatitude() < mapBottomLeft.getLatitude()) {
61+
if (mapTopRight.getLongitude() < mapBottomLeft.getLongitude()) {
62+
constraints.add(
63+
new Constraint(mapBottomLeft.getLatitude(), mapBottomLeft.getLongitude(), 90.0,
64+
180.0));
65+
constraints.add(new Constraint(mapBottomLeft.getLatitude(), -180.0, 90.0,
66+
mapTopRight.getLongitude()));
67+
constraints.add(
68+
new Constraint(-90.0, mapBottomLeft.getLongitude(), mapTopRight.getLatitude(),
69+
180.0));
70+
constraints.add(new Constraint(-90.0, -180.0, mapTopRight.getLatitude(),
71+
mapTopRight.getLongitude()));
72+
} else {
73+
constraints.add(
74+
new Constraint(mapBottomLeft.getLatitude(), mapBottomLeft.getLongitude(), 90.0,
75+
mapTopRight.getLongitude()));
76+
constraints.add(
77+
new Constraint(-90.0, mapBottomLeft.getLongitude(), mapTopRight.getLatitude(),
78+
mapTopRight.getLongitude()));
79+
}
80+
} else {
81+
if (mapTopRight.getLongitude() < mapBottomLeft.getLongitude()) {
82+
constraints.add(
83+
new Constraint(mapBottomLeft.getLatitude(), mapBottomLeft.getLongitude(),
84+
mapTopRight.getLatitude(), 180.0));
85+
constraints.add(
86+
new Constraint(mapBottomLeft.getLatitude(), -180.0, mapTopRight.getLatitude(),
87+
mapTopRight.getLongitude()));
88+
} else {
89+
constraints.add(
90+
new Constraint(mapBottomLeft.getLatitude(), mapBottomLeft.getLongitude(),
91+
mapTopRight.getLatitude(), mapTopRight.getLongitude()));
92+
}
93+
}
94+
95+
final List<Place> cachedPlaces = new ArrayList<>();
96+
for (final Constraint constraint : constraints) {
97+
cachedPlaces.addAll(placeDao.fetchPlaces(
98+
constraint.latBegin,
99+
constraint.lngBegin,
100+
constraint.latEnd,
101+
constraint.lngEnd
102+
));
103+
}
104+
105+
return cachedPlaces;
106+
}
107+
29108
/**
30109
* Saves a Place object asynchronously into the database.
31110
*

app/src/main/java/fr/free/nrw/commons/nearby/PlacesRepository.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import fr.free.nrw.commons.location.LatLng;
55
import io.reactivex.Completable;
66
import io.reactivex.schedulers.Schedulers;
7+
import java.util.List;
78
import javax.inject.Inject;
89

910
/**
@@ -39,6 +40,17 @@ public Place fetchPlace(String entityID){
3940
return localDataSource.fetchPlace(entityID);
4041
}
4142

43+
/**
44+
* Retrieves a list of places within the geographical area specified by map's opposite corners.
45+
*
46+
* @param mapBottomLeft Bottom left corner of the map.
47+
* @param mapTopRight Top right corner of the map.
48+
* @return The list of saved places within the map's view.
49+
*/
50+
public List<Place> fetchPlaces(final LatLng mapBottomLeft, final LatLng mapTopRight) {
51+
return localDataSource.fetchPlaces(mapBottomLeft, mapTopRight);
52+
}
53+
4254
/**
4355
* Clears the Nearby cache on an IO thread.
4456
*

app/src/main/java/fr/free/nrw/commons/nearby/contract/NearbyParentFragmentContract.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ interface View {
1818

1919
boolean isNetworkConnectionEstablished();
2020

21+
void updateSnackbar(boolean offlinePinsShown);
22+
2123
void listOptionMenuItemClicked();
2224

2325
void populatePlaces(LatLng currentLatLng);
@@ -91,6 +93,10 @@ void filterMarkersByLabels(List<Label> selectedLabels, boolean filterForPlaceSta
9193

9294
LatLng getMapFocus();
9395

96+
LatLng getScreenTopRight();
97+
98+
LatLng getScreenBottomLeft();
99+
94100
boolean isAdvancedQueryFragmentVisible();
95101

96102
void showHideAdvancedQueryFragment(boolean shouldShow);
@@ -122,14 +128,14 @@ interface UserActions {
122128
void filterByMarkerType(List<Label> selectedLabels, int state, boolean filterForPlaceState,
123129
boolean filterForAllNoneType);
124130

125-
void updateMapMarkersToController(List<BaseMarker> baseMarkers);
126-
127131
void searchViewGainedFocus();
128132

129133
void setCheckboxUnknown();
130134

131135
void setAdvancedQuery(String query);
132136

133137
void toggleBookmarkedStatus(Place place);
138+
139+
void handleMapScrolled(LifecycleCoroutineScope scope, boolean isNetworkAvailable);
134140
}
135141
}

0 commit comments

Comments
 (0)