diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java index a55ae5e0d..850b953e9 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java @@ -46,11 +46,11 @@ public class BookmarkLocationsDao { ContentProviderClient db = clientProvider.get(); try { cursor = db.query( - BookmarkLocationsContentProvider.BASE_URI, - Table.ALL_FIELDS, - null, - new String[]{}, - null); + BookmarkLocationsContentProvider.BASE_URI, + Table.ALL_FIELDS, + null, + new String[]{}, + null); while (cursor != null && cursor.moveToNext()) { items.add(fromCursor(cursor)); } @@ -126,11 +126,11 @@ public class BookmarkLocationsDao { ContentProviderClient db = clientProvider.get(); try { cursor = db.query( - BookmarkLocationsContentProvider.BASE_URI, - Table.ALL_FIELDS, - Table.COLUMN_NAME + "=?", - new String[]{bookmarkLocation.name}, - null); + BookmarkLocationsContentProvider.BASE_URI, + Table.ALL_FIELDS, + Table.COLUMN_NAME + "=?", + new String[]{bookmarkLocation.name}, + null); if (cursor != null && cursor.moveToFirst()) { return true; } @@ -149,7 +149,7 @@ public class BookmarkLocationsDao { @NonNull Place fromCursor(final Cursor cursor) { final LatLng location = new LatLng(cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LAT)), - cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LONG)), 1F); + cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LONG)), 1F); final Sitelinks.Builder builder = new Sitelinks.Builder(); builder.setWikipediaLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_WIKIPEDIA_LINK))); @@ -207,40 +207,40 @@ public class BookmarkLocationsDao { // NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES. public static final String[] ALL_FIELDS = { - COLUMN_NAME, - COLUMN_LANGUAGE, - COLUMN_DESCRIPTION, - COLUMN_CATEGORY, - COLUMN_LABEL_TEXT, - COLUMN_LABEL_ICON, - COLUMN_LAT, - COLUMN_LONG, - COLUMN_IMAGE_URL, - COLUMN_WIKIPEDIA_LINK, - COLUMN_WIKIDATA_LINK, - COLUMN_COMMONS_LINK, - COLUMN_PIC, - COLUMN_EXISTS, + COLUMN_NAME, + COLUMN_LANGUAGE, + COLUMN_DESCRIPTION, + COLUMN_CATEGORY, + COLUMN_LABEL_TEXT, + COLUMN_LABEL_ICON, + COLUMN_LAT, + COLUMN_LONG, + COLUMN_IMAGE_URL, + COLUMN_WIKIPEDIA_LINK, + COLUMN_WIKIDATA_LINK, + COLUMN_COMMONS_LINK, + COLUMN_PIC, + COLUMN_EXISTS, }; static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME; static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " (" - + COLUMN_NAME + " STRING PRIMARY KEY," - + COLUMN_LANGUAGE + " STRING," - + COLUMN_DESCRIPTION + " STRING," - + COLUMN_CATEGORY + " STRING," - + COLUMN_LABEL_TEXT + " STRING," - + COLUMN_LABEL_ICON + " INTEGER," - + COLUMN_LAT + " DOUBLE," - + COLUMN_LONG + " DOUBLE," - + COLUMN_IMAGE_URL + " STRING," - + COLUMN_WIKIPEDIA_LINK + " STRING," - + COLUMN_WIKIDATA_LINK + " STRING," - + COLUMN_COMMONS_LINK + " STRING," - + COLUMN_PIC + " STRING," - + COLUMN_EXISTS + " STRING" - + ");"; + + COLUMN_NAME + " STRING PRIMARY KEY," + + COLUMN_LANGUAGE + " STRING," + + COLUMN_DESCRIPTION + " STRING," + + COLUMN_CATEGORY + " STRING," + + COLUMN_LABEL_TEXT + " STRING," + + COLUMN_LABEL_ICON + " INTEGER," + + COLUMN_LAT + " DOUBLE," + + COLUMN_LONG + " DOUBLE," + + COLUMN_IMAGE_URL + " STRING," + + COLUMN_WIKIPEDIA_LINK + " STRING," + + COLUMN_WIKIDATA_LINK + " STRING," + + COLUMN_COMMONS_LINK + " STRING," + + COLUMN_PIC + " STRING," + + COLUMN_EXISTS + " STRING" + + ");"; public static void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_TABLE_STATEMENT); @@ -308,4 +308,4 @@ public class BookmarkLocationsDao { } } } -} +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/db/AppDatabase.kt b/app/src/main/java/fr/free/nrw/commons/db/AppDatabase.kt index 6d63e58a1..594f087c8 100644 --- a/app/src/main/java/fr/free/nrw/commons/db/AppDatabase.kt +++ b/app/src/main/java/fr/free/nrw/commons/db/AppDatabase.kt @@ -6,6 +6,8 @@ import androidx.room.TypeConverters import fr.free.nrw.commons.contributions.Contribution import fr.free.nrw.commons.contributions.ContributionDao import fr.free.nrw.commons.customselector.database.* +import fr.free.nrw.commons.nearby.Place +import fr.free.nrw.commons.nearby.PlaceDao import fr.free.nrw.commons.review.ReviewDao import fr.free.nrw.commons.review.ReviewEntity import fr.free.nrw.commons.upload.depicts.Depicts @@ -15,10 +17,11 @@ import fr.free.nrw.commons.upload.depicts.DepictsDao * The database for accessing the respective DAOs * */ -@Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class, NotForUploadStatus::class, ReviewEntity::class], version = 16, exportSchema = false) +@Database(entities = [Contribution::class, Depicts::class, UploadedStatus::class, NotForUploadStatus::class, ReviewEntity::class, Place::class], version = 18, exportSchema = false) @TypeConverters(Converters::class) abstract class AppDatabase : RoomDatabase() { abstract fun contributionDao(): ContributionDao + abstract fun PlaceDao(): PlaceDao abstract fun DepictsDao(): DepictsDao; abstract fun UploadedStatusDao(): UploadedStatusDao; abstract fun NotForUploadStatusDao(): NotForUploadStatusDao diff --git a/app/src/main/java/fr/free/nrw/commons/db/Converters.java b/app/src/main/java/fr/free/nrw/commons/db/Converters.java index 6f0c8c1fc..a70cdc815 100644 --- a/app/src/main/java/fr/free/nrw/commons/db/Converters.java +++ b/app/src/main/java/fr/free/nrw/commons/db/Converters.java @@ -8,8 +8,10 @@ import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.contributions.ChunkInfo; import fr.free.nrw.commons.di.ApplicationlessInjection; import fr.free.nrw.commons.location.LatLng; +import fr.free.nrw.commons.nearby.Sitelinks; import fr.free.nrw.commons.upload.WikidataPlace; import fr.free.nrw.commons.upload.structure.depictions.DepictedItem; +import java.lang.reflect.Type; import java.util.Date; import java.util.List; import java.util.Map; @@ -134,6 +136,18 @@ public class Converters { return readObjectWithTypeToken(depictedItems, new TypeToken>() {}); } + @TypeConverter + public static Sitelinks sitelinksFromString(String value) { + Type type = new TypeToken() {}.getType(); + return new Gson().fromJson(value, type); + } + + @TypeConverter + public static String fromSitelinks(Sitelinks sitelinks) { + Gson gson = new Gson(); + return gson.toJson(sitelinks); + } + private static String writeObjectToString(Object object) { return object == null ? null : getGson().toJson(object); } diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java index abf7c6fb1..cd7324c63 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationModule.java @@ -24,6 +24,7 @@ import fr.free.nrw.commons.data.DBOpenHelper; import fr.free.nrw.commons.db.AppDatabase; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.location.LocationServiceManager; +import fr.free.nrw.commons.nearby.PlaceDao; import fr.free.nrw.commons.review.ReviewDao; import fr.free.nrw.commons.settings.Prefs; import fr.free.nrw.commons.upload.UploadController; @@ -275,6 +276,11 @@ public class CommonsApplicationModule { return appDatabase.contributionDao(); } + @Provides + public PlaceDao providesPlaceDao(AppDatabase appDatabase) { + return appDatabase.PlaceDao(); + } + /** * Get the reference of DepictsDao class. */ diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java b/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java index 317d1ebc0..8d6b74231 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java @@ -397,6 +397,54 @@ public class OkHttpJsonApiClient { throw new Exception(response.message()); } + /** + * Retrieves a list of places based on the provided list of places and language. + * + * @param placeList A list of Place objects for which to fetch information. + * @param language The language code to use for the query. + * @return A list of Place objects with additional information retrieved from Wikidata, or null + * if an error occurs. + * @throws IOException If there is an issue with reading the resource file or executing the HTTP + * request. + */ + @Nullable + public List getPlaces( + final List placeList, final String language) throws IOException { + final String wikidataQuery = FileUtils.readFromResource("/queries/query_for_item.rq"); + String qids = ""; + for (final Place place : placeList) { + qids += "\n" + ("wd:" + place.getWikiDataEntityId()); + } + final String query = wikidataQuery + .replace("${ENTITY}", qids) + .replace("${LANG}", language); + final HttpUrl.Builder urlBuilder = HttpUrl + .parse(sparqlQueryUrl) + .newBuilder() + .addQueryParameter("query", query) + .addQueryParameter("format", "json"); + + final Request request = new Request.Builder() + .url(urlBuilder.build()) + .build(); + + try (Response response = okHttpClient.newCall(request).execute()) { + if (response.isSuccessful()) { + final String json = response.body().string(); + final NearbyResponse nearbyResponse = gson.fromJson(json, NearbyResponse.class); + final List bindings = nearbyResponse.getResults().getBindings(); + final List places = new ArrayList<>(); + for (final NearbyResultItem item : bindings) { + final Place placeFromNearbyItem = Place.from(item); + places.add(placeFromNearbyItem); + } + return places; + } else { + throw new IOException("Unexpected response code: " + response.code()); + } + } + } + /** * Make API Call to get Places * diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java index d650f2869..7bb311961 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java @@ -131,6 +131,17 @@ public class NearbyController extends MapController { ); } + /** + * Retrieves a list of places based on the provided list of places and language. + * + * @param placeList A list of Place objects for which to fetch information. + * @return A list of Place objects obtained from the Wikidata query. + * @throws Exception If an error occurs during the retrieval process. + */ + public List getPlaces(List placeList) throws Exception { + return nearbyPlaces.getPlaces(placeList, Locale.getDefault().getLanguage()); + } + public static LatLng calculateNorthEast(double latitude, double longitude, double distance) { double lat1 = Math.toRadians(latitude); double deltaLat = distance * 0.008; diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java index 787cc35e2..46f0a2a9e 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java @@ -120,6 +120,22 @@ public class NearbyPlaces { customQuery); } + /** + * Retrieves a list of places based on the provided list of places and language. + * + * This method fetches place information from a Wikidata query using the specified language. + * + * @param placeList A list of Place objects for which to fetch information. + * @param lang The language code to use for the query. + * @return A list of Place objects obtained from the Wikidata query. + * @throws Exception If an error occurs during the retrieval process. + */ + public List getPlaces(final List placeList, + final String lang) throws Exception { + return okHttpJsonApiClient + .getPlaces(placeList, lang); + } + /** * Runs the Wikidata query to retrieve the KML String * diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/Place.java b/app/src/main/java/fr/free/nrw/commons/nearby/Place.java index fdd836390..7732669bc 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/Place.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/Place.java @@ -3,34 +3,38 @@ package fr.free.nrw.commons.nearby; import android.net.Uri; import android.os.Parcel; import android.os.Parcelable; - +import androidx.annotation.NonNull; import androidx.annotation.Nullable; - -import org.apache.commons.lang3.StringUtils; - +import androidx.room.Entity; +import androidx.room.PrimaryKey; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.nearby.model.NearbyResultItem; +import fr.free.nrw.commons.utils.LocationUtils; import fr.free.nrw.commons.utils.PlaceUtils; +import org.apache.commons.lang3.StringUtils; import timber.log.Timber; /** * A single geolocated Wikidata item */ +@Entity(tableName = "place") public class Place implements Parcelable { - public final String language; - public final String name; - private final Label label; - private final String longDescription; - public final LatLng location; - private final String category; - public final String pic; + public String language; + public String name; + private Label label; + private String longDescription; + public LatLng location; + @PrimaryKey @NonNull + public String entityID; + private String category; + public String pic; // exists boolean will tell whether the place exists or not, // For a place to be existing both destroyed and endTime property should be null but it is also not necessary for a non-existing place to have both properties either one property is enough (in such case that not given property will be considered as null). - public final Boolean exists; + public Boolean exists; public String distance; - public final Sitelinks siteLinks; + public Sitelinks siteLinks; private boolean isMonument; private String thumb; @@ -44,9 +48,11 @@ public class Place implements Parcelable { pic = null; exists = null; siteLinks = null; + entityID = null; } - public Place(String language,String name, Label label, String longDescription, LatLng location, String category, Sitelinks siteLinks, String pic, Boolean exists) { + public Place(String language, String name, Label label, String longDescription, LatLng location, + String category, Sitelinks siteLinks, String pic, Boolean exists, String entityID) { this.language = language; this.name = name; this.label = label; @@ -54,21 +60,37 @@ public class Place implements Parcelable { this.location = location; this.category = category; this.siteLinks = siteLinks; - this.pic = (pic == null) ? "":pic; + this.pic = (pic == null) ? "" : pic; + this.exists = exists; + this.entityID = entityID; + } + + public Place(String language, String name, Label label, String longDescription, LatLng location, + String category, Sitelinks siteLinks, String pic, Boolean exists) { + this.language = language; + this.name = name; + this.label = label; + this.longDescription = longDescription; + this.location = location; + this.category = category; + this.siteLinks = siteLinks; + this.pic = (pic == null) ? "" : pic; this.exists = exists; } - public Place(String name, String longDescription, LatLng location, String category, Sitelinks siteLinks, String pic, String thumb) { + public Place(String name, String longDescription, LatLng location, String category, + Sitelinks siteLinks, String pic, String thumb, String entityID) { this.name = name; this.longDescription = longDescription; this.location = location; this.category = category; this.siteLinks = siteLinks; - this.pic = (pic == null) ? "":pic; + this.pic = (pic == null) ? "" : pic; this.thumb = thumb; this.language = null; this.label = null; this.exists = true; + this.entityID = entityID; } public Place(Parcel in) { @@ -80,19 +102,27 @@ public class Place implements Parcelable { this.category = in.readString(); this.siteLinks = in.readParcelable(Sitelinks.class.getClassLoader()); String picString = in.readString(); - this.pic = (picString == null) ? "":picString; + this.pic = (picString == null) ? "" : picString; String existString = in.readString(); this.exists = Boolean.parseBoolean(existString); this.isMonument = in.readInt() == 1; + this.entityID = in.readString(); } + public static Place from(NearbyResultItem item) { String itemClass = item.getClassName().getValue(); String classEntityId = ""; - if(!StringUtils.isBlank(itemClass)) { + if (!StringUtils.isBlank(itemClass)) { classEntityId = itemClass.replace("http://www.wikidata.org/entity/", ""); } + String entityId = ""; + if (!StringUtils.isBlank(item.getItem().getValue())){ + entityId = item.getItem().getValue().replace("http://www.wikidata.org/entity/", ""); + } // Set description when not null and not empty - String description = (item.getDescription().getValue() != null && !item.getDescription().getValue().isEmpty()) ? item.getDescription().getValue() : ""; + String description = + (item.getDescription().getValue() != null && !item.getDescription().getValue() + .isEmpty()) ? item.getDescription().getValue() : ""; // When description is "?" but we have a valid label, just use the label. So replace "?" by "" in description description = (description.equals("?") && (item.getLabel().getValue() != null @@ -104,8 +134,8 @@ public class Place implements Parcelable { */ description = ((item.getLabel().getValue() != null && !item.getLabel().getValue().isEmpty()) ? item.getLabel().getValue() - + ((description != null && !description.isEmpty()) - ? " (" + description + ")" : "") + + ((description != null && !description.isEmpty()) + ? " (" + description + ")" : "") : description); return new Place( item.getLabel().getLanguage(), @@ -121,11 +151,12 @@ public class Place implements Parcelable { .build(), item.getPic().getValue(), // Checking if the place exists or not - (item.getDestroyed().getValue() == "") && (item.getEndTime().getValue() == "")); + (item.getDestroyed().getValue() == "") && (item.getEndTime().getValue() == ""), entityId); } /** * Gets the language of the caption ie name. + * * @return language */ public String getLanguage() { @@ -134,12 +165,27 @@ public class Place implements Parcelable { /** * Gets the name of the place + * * @return name */ - public String getName() { return name; } + public String getName() { + return name; + } - /** Gets the label of the place - * e.g. "building", "city", etc + /** + * Gets the distance between place and curLatLng + * + * @param curLatLng + * @return name + */ + public Double getDistanceInDouble(LatLng curLatLng) { + return LocationUtils.calculateDistance(curLatLng.getLatitude(), curLatLng.getLongitude(), + getLocation().getLatitude(), getLocation().getLongitude()); + } + + /** + * Gets the label of the place e.g. "building", "city", etc + * * @return label */ public Label getLabel() { @@ -152,6 +198,7 @@ public class Place implements Parcelable { /** * Gets the long description of the place + * * @return long description */ public String getLongDescription() { @@ -160,12 +207,16 @@ public class Place implements Parcelable { /** * Gets the Commons category of the place + * * @return Commons category */ - public String getCategory() {return category; } + public String getCategory() { + return category; + } /** * Sets the distance of the place from the user's location + * * @param distance distance of place from user's location */ public void setDistance(String distance) { @@ -174,6 +225,7 @@ public class Place implements Parcelable { /** * Extracts the entity id from the wikidata link + * * @return returns the entity id if wikidata link destroyed */ @Nullable @@ -189,6 +241,7 @@ public class Place implements Parcelable { /** * Checks if the Wikidata item has a Wikipedia page associated with it + * * @return true if there is a Wikipedia link */ public boolean hasWikipediaLink() { @@ -197,6 +250,7 @@ public class Place implements Parcelable { /** * Checks if the Wikidata item has a Wikidata page associated with it + * * @return true if there is a Wikidata link */ public boolean hasWikidataLink() { @@ -205,6 +259,7 @@ public class Place implements Parcelable { /** * Checks if the Wikidata item has a Commons page associated with it + * * @return true if there is a Commons link */ public boolean hasCommonsLink() { @@ -213,6 +268,7 @@ public class Place implements Parcelable { /** * Sets that this place in nearby is a WikiData monument + * * @param monument */ public void setMonument(final boolean monument) { @@ -221,6 +277,7 @@ public class Place implements Parcelable { /** * Returns if this place is a WikiData monument + * * @return */ public boolean isMonument() { @@ -229,6 +286,7 @@ public class Place implements Parcelable { /** * Check if we already have the exact same Place + * * @param o Place being tested * @return true if name and location of Place is exactly the same */ @@ -250,17 +308,18 @@ public class Place implements Parcelable { @Override public String toString() { return "Place{" + - "name='" + name + '\'' + - ", lang='" + language + '\'' + - ", label='" + label + '\'' + - ", longDescription='" + longDescription + '\'' + - ", location='" + location + '\'' + - ", category='" + category + '\'' + - ", distance='" + distance + '\'' + - ", siteLinks='" + siteLinks.toString() + '\'' + - ", pic='" + pic + '\'' + - ", exists='" + exists.toString() + '\'' + - '}'; + "name='" + name + '\'' + + ", lang='" + language + '\'' + + ", label='" + label + '\'' + + ", longDescription='" + longDescription + '\'' + + ", location='" + location + '\'' + + ", category='" + category + '\'' + + ", distance='" + distance + '\'' + + ", siteLinks='" + siteLinks.toString() + '\'' + + ", pic='" + pic + '\'' + + ", exists='" + exists.toString() + '\'' + + ", entityID='" + entityID + '\'' + + '}'; } @Override @@ -278,6 +337,7 @@ public class Place implements Parcelable { dest.writeString(category); dest.writeParcelable(siteLinks, 0); dest.writeString(pic); + dest.writeString(entityID); dest.writeString(exists.toString()); dest.writeInt(isMonument ? 1 : 0); } @@ -298,7 +358,40 @@ public class Place implements Parcelable { return thumb; } + /** + * Sets the thumbnail URL for the place. + * + * @param thumb the thumbnail URL to set + */ public void setThumb(String thumb) { this.thumb = thumb; } + + /** + * Sets the label for the place. + * + * @param label the label to set + */ + public void setLabel(Label label) { + this.label = label; + } + + /** + * Sets the long description for the place. + * + * @param longDescription the long description to set + */ + public void setLongDescription(String longDescription) { + this.longDescription = longDescription; + } + + /** + * Sets the Commons category for the place. + * + * @param category the category to set + */ + public void setCategory(String category) { + this.category = category; + } + } diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/PlaceDao.java b/app/src/main/java/fr/free/nrw/commons/nearby/PlaceDao.java new file mode 100644 index 000000000..f18b80004 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/nearby/PlaceDao.java @@ -0,0 +1,45 @@ +package fr.free.nrw.commons.nearby; + +import androidx.room.Dao; +import androidx.room.Insert; +import androidx.room.OnConflictStrategy; +import androidx.room.Query; +import fr.free.nrw.commons.location.LatLng; +import io.reactivex.Completable; + +/** + * Data Access Object (DAO) for accessing the Place entity in the database. + * This class provides methods for storing and retrieving Place objects, + * utilized for the caching of places in the Nearby Map feature. + */ +@Dao +public abstract class PlaceDao { + + /** + * Inserts a Place object into the database. + * If a conflict occurs, the existing entry will be replaced. + * + * @param place The Place object to be inserted. + */ + @Insert(onConflict = OnConflictStrategy.REPLACE) + public abstract void saveSynchronous(Place place); + + /** + * Retrieves a Place object from the database based on the provided entity ID. + * + * @param entity The entity ID of the Place to be retrieved. + * @return The Place object with the specified entity ID. + */ + @Query("SELECT * from place WHERE entityID=:entity") + public abstract Place getPlace(String entity); + + /** + * Saves a Place object asynchronously into the database. + */ + public Completable save(final Place place) { + return Completable + .fromAction(() -> { + saveSynchronous(place); + }); + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/PlacesLocalDataSource.java b/app/src/main/java/fr/free/nrw/commons/nearby/PlacesLocalDataSource.java new file mode 100644 index 000000000..8de437c82 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/nearby/PlacesLocalDataSource.java @@ -0,0 +1,39 @@ +package fr.free.nrw.commons.nearby; + +import fr.free.nrw.commons.location.LatLng; +import io.reactivex.Completable; +import javax.inject.Inject; + +/** + * The LocalDataSource class for Places + */ +public class PlacesLocalDataSource { + + private final PlaceDao placeDao; + + @Inject + public PlacesLocalDataSource( + final PlaceDao placeDao) { + this.placeDao = placeDao; + } + + /** + * Fetches a Place object from the database based on the provided entity ID. + * + * @param entityID The entity ID of the Place to be retrieved. + * @return The Place object with the specified entity ID. + */ + public Place fetchPlace(String entityID){ + return placeDao.getPlace(entityID); + } + + /** + * Saves a Place object asynchronously into the database. + * + * @param place The Place object to be saved. + * @return A Completable that completes once the save operation is done. + */ + public Completable savePlace(Place place) { + return placeDao.save(place); + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/PlacesRepository.java b/app/src/main/java/fr/free/nrw/commons/nearby/PlacesRepository.java new file mode 100644 index 000000000..85e964ddb --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/nearby/PlacesRepository.java @@ -0,0 +1,41 @@ +package fr.free.nrw.commons.nearby; + +import fr.free.nrw.commons.contributions.Contribution; +import fr.free.nrw.commons.location.LatLng; +import io.reactivex.Completable; +import javax.inject.Inject; + +/** + * The PlacesRepository class acts as a repository for Place entities. + * It interacts with the PlacesLocalDataSource to perform database operations. + */ +public class PlacesRepository { + + private PlacesLocalDataSource localDataSource; + + @Inject + public PlacesRepository(PlacesLocalDataSource localDataSource) { + this.localDataSource = localDataSource; + } + + /** + * Saves a Place object asynchronously into the database. + * + * @param place The Place object to be saved. + * @return A Completable that completes once the save operation is done. + */ + public Completable save(Place place){ + return localDataSource.savePlace(place); + } + + /** + * Fetches a Place object from the database based on the provided entity ID. + * + * @param entityID The entity ID of the Place to be retrieved. + * @return The Place object with the specified entity ID. + */ + public Place fetchPlace(String entityID){ + return localDataSource.fetchPlace(entityID); + } + +} diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/contract/NearbyParentFragmentContract.java b/app/src/main/java/fr/free/nrw/commons/nearby/contract/NearbyParentFragmentContract.java index df999dbf0..bcf8d8421 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/contract/NearbyParentFragmentContract.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/contract/NearbyParentFragmentContract.java @@ -42,10 +42,6 @@ public interface NearbyParentFragmentContract { void hideBottomDetailsSheet(); - void addSearchThisAreaButtonAction(); - - void setSearchThisAreaButtonVisibility(boolean isVisible); - void setProgressBarVisibility(boolean isVisible); boolean isDetailsBottomSheetVisible(); @@ -76,8 +72,7 @@ public interface NearbyParentFragmentContract { void filterOutAllMarkers(); - void filterMarkersByLabels(List