mirror of
				https://github.com/commons-app/apps-android-commons.git
				synced 2025-10-31 06:43:56 +01:00 
			
		
		
		
	* Integrate WLM - Show monuments in maps along with nearby * BugFix in Monuments 1. Single preference for monuments and campaigns 2. Expand collapse chips container in nearby 3. Typo fix in Monuments card in Nearby 4. If a nearby place is a monument as well - do not show them separately, show it as a monument instead 5. Bug fix, monument radius, use the same one as that of nearby * More bug fixes 1. Possible NPE in nearby 2. Added column location_address in BookmarkLocationDao 3. Bug Fix - Display Date in WLM card 4. WLM card on click takes to nearby * Use lowercase country code in WLM uploads * Bug-Fix, WLM Campaign Icon * 1. Updated monuments query to use any of the following properties for monuments - [P1435, P2186, P1459, P1460, P1216, P709, P718, P5694] 2. Append WikiData QID to descriptions template * Updated WLM Banner String, Handle NPE in contributions callback * Added nearby-monuments query log lines * Handle WLM Query exception : - if an exception is thrown in WLM query, continue showing the nearby items if that succeeds * Fix BookmarkLocationDaoTest * Added Column Address in BookmarkLocationDaoTest * Use fallback description as usual nearby pins even for WLM pins, instead of relying on P6375 * Test fix in BookmarkLocationDao * Updated template for WLM, removed redundant feilds * Fixed WLM template * Removed categories from WLM template * Fixed BookmarkControllerTest * Fixed BookmarkLocationFragmentUnitTest * fix ModelFunctions * Fixed BookmarksDaoLocationTest * Fixed WLM template
This commit is contained in:
		
							parent
							
								
									67f5b6c271
								
							
						
					
					
						commit
						6588a6fd0e
					
				
					 39 changed files with 2906 additions and 185 deletions
				
			
		|  | @ -8,14 +8,17 @@ import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions; | |||
| import com.mapbox.mapboxsdk.annotations.Icon; | ||||
| import com.mapbox.mapboxsdk.annotations.IconFactory; | ||||
| import com.mapbox.mapboxsdk.geometry.LatLng; | ||||
| import java.util.Objects; | ||||
| 
 | ||||
| public class NearbyBaseMarker extends BaseMarkerOptions<NearbyMarker, NearbyBaseMarker> { | ||||
| 
 | ||||
|     public static final Parcelable.Creator<NearbyBaseMarker> CREATOR = new Parcelable.Creator<NearbyBaseMarker>() { | ||||
|         @Override | ||||
|         public NearbyBaseMarker createFromParcel(Parcel in) { | ||||
|             return new NearbyBaseMarker(in); | ||||
|         } | ||||
| 
 | ||||
|         @Override | ||||
|         public NearbyBaseMarker[] newArray(int size) { | ||||
|             return new NearbyBaseMarker[size]; | ||||
|         } | ||||
|  | @ -70,4 +73,21 @@ public class NearbyBaseMarker extends BaseMarkerOptions<NearbyMarker, NearbyBase | |||
|         dest.writeString(title); | ||||
|         dest.writeParcelable(place, 0); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean equals(final Object o) { | ||||
|         if (this == o) { | ||||
|             return true; | ||||
|         } | ||||
|         if (o == null || getClass() != o.getClass()) { | ||||
|             return false; | ||||
|         } | ||||
|         final NearbyBaseMarker that = (NearbyBaseMarker) o; | ||||
|         return Objects.equals(place.location, that.place.location); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int hashCode() { | ||||
|         return Objects.hash(place); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; | |||
| import com.mapbox.mapboxsdk.annotations.IconFactory; | ||||
| import com.mapbox.mapboxsdk.annotations.Marker; | ||||
| 
 | ||||
| import io.reactivex.Observable; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
|  | @ -127,6 +128,11 @@ public class NearbyController { | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public Observable<List<Place>> queryWikiDataForMonuments( | ||||
|         final LatLng latLng, final String language) { | ||||
|         return nearbyPlaces.queryWikiDataForMonuments(latLng, language); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Loads attractions from location for list view, we need to return Place data type. | ||||
|      * | ||||
|  | @ -168,6 +174,7 @@ public class NearbyController { | |||
|         VectorDrawableCompat vectorDrawable = null; | ||||
|         VectorDrawableCompat vectorDrawableGreen = null; | ||||
|         VectorDrawableCompat vectorDrawableGrey = null; | ||||
|         VectorDrawableCompat vectorDrawableMonuments = null; | ||||
|         vectorDrawable = null; | ||||
|         try { | ||||
|             vectorDrawable = VectorDrawableCompat.create( | ||||
|  | @ -176,6 +183,9 @@ public class NearbyController { | |||
|                     context.getResources(), R.drawable.ic_custom_map_marker_green, context.getTheme()); | ||||
|             vectorDrawableGrey = VectorDrawableCompat.create( | ||||
|                     context.getResources(), R.drawable.ic_custom_map_marker_grey, context.getTheme()); | ||||
|             vectorDrawableMonuments = VectorDrawableCompat | ||||
|                 .create(context.getResources(), R.drawable.ic_custom_map_marker_monuments, | ||||
|                     context.getTheme()); | ||||
|         } catch (Resources.NotFoundException e) { | ||||
|             // ignore when running tests. | ||||
|         } | ||||
|  | @ -183,34 +193,39 @@ public class NearbyController { | |||
|             Bitmap icon = UiUtils.getBitmap(vectorDrawable); | ||||
|             Bitmap iconGreen = UiUtils.getBitmap(vectorDrawableGreen); | ||||
|             Bitmap iconGrey = UiUtils.getBitmap(vectorDrawableGrey); | ||||
|             Bitmap iconMonuments = UiUtils.getBitmap(vectorDrawableMonuments); | ||||
| 
 | ||||
|             for (Place place : placeList) { | ||||
|                 NearbyBaseMarker nearbyBaseMarker = new NearbyBaseMarker(); | ||||
|                 String distance = formatDistanceBetween(curLatLng, place.location); | ||||
|                 place.setDistance(distance); | ||||
| 
 | ||||
|                 NearbyBaseMarker nearbyBaseMarker = new NearbyBaseMarker(); | ||||
|                 nearbyBaseMarker.title(place.name); | ||||
|                 nearbyBaseMarker.position( | ||||
|                         new com.mapbox.mapboxsdk.geometry.LatLng( | ||||
|                                 place.location.getLatitude(), | ||||
|                                 place.location.getLongitude())); | ||||
|                     new com.mapbox.mapboxsdk.geometry.LatLng( | ||||
|                         place.location.getLatitude(), | ||||
|                         place.location.getLongitude())); | ||||
|                 nearbyBaseMarker.place(place); | ||||
|                 // Check if string is only spaces or empty, if so place doesn't have any picture | ||||
|                 if (!place.pic.trim().isEmpty()) { | ||||
| 
 | ||||
|                 if (place.isMonument()) { | ||||
|                     nearbyBaseMarker.icon(IconFactory.getInstance(context) | ||||
|                         .fromBitmap(iconMonuments)); | ||||
|                 } | ||||
|                 else if (!place.pic.trim().isEmpty()) { | ||||
|                     if (iconGreen != null) { | ||||
|                         nearbyBaseMarker.icon(IconFactory.getInstance(context) | ||||
|                                 .fromBitmap(iconGreen)); | ||||
|                             .fromBitmap(iconGreen)); | ||||
|                     } | ||||
|                 } else if (!place.exists) { // Means that the topic of the Wikidata item does not exist in the real world anymore, for instance it is a past event, or a place that was destroyed | ||||
|                     if (iconGrey != null) { | ||||
|                         nearbyBaseMarker.icon(IconFactory.getInstance(context) | ||||
|                                 .fromBitmap(iconGrey)); | ||||
|                             .fromBitmap(iconGrey)); | ||||
|                     } | ||||
|                 } else { | ||||
|                     nearbyBaseMarker.icon(IconFactory.getInstance(context) | ||||
|                             .fromBitmap(icon)); | ||||
|                         .fromBitmap(icon)); | ||||
|                 } | ||||
| 
 | ||||
|                 baseMarkerOptions.add(nearbyBaseMarker); | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import java.util.ArrayList; | |||
| public class NearbyFilterState { | ||||
|     private boolean existsSelected; | ||||
|     private boolean needPhotoSelected; | ||||
|     private boolean wlmSelected; | ||||
|     private int checkBoxTriState; | ||||
|     private ArrayList<Label> selectedLabels; | ||||
| 
 | ||||
|  | @ -16,6 +17,7 @@ public class NearbyFilterState { | |||
|     private NearbyFilterState() { | ||||
|         existsSelected = false; | ||||
|         needPhotoSelected = true; | ||||
|         wlmSelected = true; | ||||
|         checkBoxTriState = -1; // Unknown | ||||
|         selectedLabels = new ArrayList<>(); // Initially empty | ||||
|     } | ||||
|  | @ -39,6 +41,14 @@ public class NearbyFilterState { | |||
|         getInstance().needPhotoSelected = needPhotoSelected; | ||||
|     } | ||||
| 
 | ||||
|     public static void setWlmSelected(final boolean wlmSelected) { | ||||
|         getInstance().wlmSelected = wlmSelected; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isWlmSelected() { | ||||
|         return wlmSelected; | ||||
|     } | ||||
| 
 | ||||
|     public boolean isExistsSelected() { | ||||
|         return existsSelected; | ||||
|     } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| package fr.free.nrw.commons.nearby; | ||||
| 
 | ||||
| import io.reactivex.Observable; | ||||
| import java.io.IOException; | ||||
| import java.io.InterruptedIOException; | ||||
| import java.util.Collections; | ||||
|  | @ -65,9 +66,9 @@ public class NearbyPlaces { | |||
|             while (radius <= maxRadius) { | ||||
|                 try { | ||||
|                     places = getFromWikidataQuery(curLatLng, lang, radius); | ||||
|                 } catch (InterruptedIOException e) { | ||||
|                     Timber.e(e, "exception in fetching nearby places"); | ||||
|                     return places; | ||||
|                 } catch (final Exception e) { | ||||
|                     Timber.e(e, "Exception in fetching nearby places"); | ||||
|                     break; | ||||
|                 } | ||||
|                 Timber.d("%d results at radius: %f", places.size(), radius); | ||||
|                 if (places.size() >= minResults) { | ||||
|  | @ -91,7 +92,13 @@ public class NearbyPlaces { | |||
|      * @return list of places obtained | ||||
|      * @throws IOException if query fails | ||||
|      */ | ||||
|     public List<Place> getFromWikidataQuery(LatLng cur, String lang, double radius) throws IOException { | ||||
|     public List<Place> getFromWikidataQuery(LatLng cur, String lang, double radius) throws Exception { | ||||
|         return okHttpJsonApiClient.getNearbyPlaces(cur, lang, radius).blockingSingle(); | ||||
|     } | ||||
| 
 | ||||
|     public Observable<List<Place>> queryWikiDataForMonuments( | ||||
|         LatLng latLng, String language) { | ||||
|         return okHttpJsonApiClient | ||||
|             .getNearbyMonuments(latLng, language, radius); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -4,8 +4,10 @@ import android.net.Uri; | |||
| import android.os.Parcel; | ||||
| import android.os.Parcelable; | ||||
| 
 | ||||
| import android.text.TextUtils; | ||||
| import androidx.annotation.Nullable; | ||||
| 
 | ||||
| import fr.free.nrw.commons.nearby.NearbyController.NearbyPlacesInfo; | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
| 
 | ||||
| import fr.free.nrw.commons.location.LatLng; | ||||
|  | @ -31,6 +33,7 @@ public class Place implements Parcelable { | |||
| 
 | ||||
|     public String distance; | ||||
|     public final Sitelinks siteLinks; | ||||
|     private boolean isMonument; | ||||
| 
 | ||||
| 
 | ||||
|     public Place(String language,String name, Label label, String longDescription, LatLng location, String category, Sitelinks siteLinks, String pic, Boolean exists) { | ||||
|  | @ -56,6 +59,7 @@ public class Place implements Parcelable { | |||
|         this.pic = (picString == null) ? "":picString; | ||||
|         String existString = in.readString(); | ||||
|         this.exists = Boolean.parseBoolean(existString); | ||||
|         this.isMonument = in.readInt() == 1; | ||||
|     } | ||||
|     public static Place from(NearbyResultItem item) { | ||||
|         String itemClass = item.getClassName().getValue(); | ||||
|  | @ -80,20 +84,20 @@ public class Place implements Parcelable { | |||
|                 ? " (" + description + ")" : "") | ||||
|             : description); | ||||
|         return new Place( | ||||
|                 item.getLabel().getLanguage(), | ||||
|                 item.getLabel().getValue(), | ||||
|                 Label.fromText(classEntityId), // list | ||||
|                 description, // description and label of Wikidata item | ||||
|                 PlaceUtils.latLngFromPointString(item.getLocation().getValue()), | ||||
|                 item.getCommonsCategory().getValue(), | ||||
|                 new Sitelinks.Builder() | ||||
|                         .setWikipediaLink(item.getWikipediaArticle().getValue()) | ||||
|                         .setCommonsLink(item.getCommonsArticle().getValue()) | ||||
|                         .setWikidataLink(item.getItem().getValue()) | ||||
|                         .build(), | ||||
|                 item.getPic().getValue(), | ||||
|                 // Checking if the place exists or not | ||||
|                 (item.getDestroyed().getValue() == "") && (item.getEndTime().getValue() == "")); | ||||
|             item.getLabel().getLanguage(), | ||||
|             item.getLabel().getValue(), | ||||
|             Label.fromText(classEntityId), // list | ||||
|             description, // description and label of Wikidata item | ||||
|             PlaceUtils.latLngFromPointString(item.getLocation().getValue()), | ||||
|             item.getCommonsCategory().getValue(), | ||||
|             new Sitelinks.Builder() | ||||
|                 .setWikipediaLink(item.getWikipediaArticle().getValue()) | ||||
|                 .setCommonsLink(item.getCommonsArticle().getValue()) | ||||
|                 .setWikidataLink(item.getItem().getValue()) | ||||
|                 .build(), | ||||
|             item.getPic().getValue(), | ||||
|             // Checking if the place exists or not | ||||
|             (item.getDestroyed().getValue() == "") && (item.getEndTime().getValue() == "")); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -126,7 +130,9 @@ public class Place implements Parcelable { | |||
|      * Gets the long description of the place | ||||
|      * @return long description | ||||
|      */ | ||||
|     public String getLongDescription() { return longDescription; } | ||||
|     public String getLongDescription() { | ||||
|         return longDescription; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the Commons category of the place | ||||
|  | @ -181,6 +187,22 @@ public class Place implements Parcelable { | |||
|         return !(siteLinks == null || Uri.EMPTY.equals(siteLinks.getCommonsLink())); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Sets that this place in nearby is a WikiData monument | ||||
|      * @param monument | ||||
|      */ | ||||
|     public void setMonument(final boolean monument) { | ||||
|         isMonument = monument; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns if this place is a WikiData monument | ||||
|      * @return | ||||
|      */ | ||||
|     public boolean isMonument() { | ||||
|         return isMonument; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if we already have the exact same Place | ||||
|      * @param o Place being tested | ||||
|  | @ -233,6 +255,7 @@ public class Place implements Parcelable { | |||
|         dest.writeParcelable(siteLinks, 0); | ||||
|         dest.writeString(pic); | ||||
|         dest.writeString(exists.toString()); | ||||
|         dest.writeInt(isMonument ? 1 : 0); | ||||
|     } | ||||
| 
 | ||||
|     public static final Creator<Place> CREATOR = new Creator<Place>() { | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ package fr.free.nrw.commons.nearby.contract; | |||
| import android.content.Context; | ||||
| 
 | ||||
| import com.mapbox.mapboxsdk.annotations.Marker; | ||||
| import com.mapbox.mapboxsdk.maps.MapboxMap; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
|  | @ -13,7 +12,6 @@ import fr.free.nrw.commons.location.LocationServiceManager; | |||
| import fr.free.nrw.commons.nearby.Label; | ||||
| import fr.free.nrw.commons.nearby.NearbyBaseMarker; | ||||
| import fr.free.nrw.commons.nearby.Place; | ||||
| import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter; | ||||
| 
 | ||||
| public interface NearbyParentFragmentContract { | ||||
| 
 | ||||
|  | @ -60,7 +58,7 @@ public interface NearbyParentFragmentContract { | |||
| 
 | ||||
|         void displayAllMarkers(); | ||||
| 
 | ||||
|         void filterMarkersByLabels(List<Label> selectedLabels, boolean existsSelected, boolean needPhotoSelected, boolean filterForPlaceState, boolean filterForAllNoneType); | ||||
|         void filterMarkersByLabels(List<Label> selectedLabels, boolean existsSelected, boolean needPhotoSelected, boolean wlmSelected, boolean filterForPlaceState, boolean filterForAllNoneType); | ||||
| 
 | ||||
|         LatLng getCameraTarget(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ package fr.free.nrw.commons.nearby.fragments; | |||
| import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED; | ||||
| import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SLIGHTLY_CHANGED; | ||||
| import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.MAP_UPDATED; | ||||
| import static fr.free.nrw.commons.nearby.Label.TEXT_TO_DESCRIPTION; | ||||
| import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween; | ||||
| import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT; | ||||
| 
 | ||||
|  | @ -16,8 +15,8 @@ import android.content.IntentFilter; | |||
| import android.content.pm.PackageManager; | ||||
| import android.content.res.Configuration; | ||||
| import android.graphics.Bitmap; | ||||
| import android.graphics.drawable.VectorDrawable; | ||||
| import android.location.LocationManager; | ||||
| import android.net.Uri; | ||||
| import android.os.Bundle; | ||||
| import android.provider.Settings; | ||||
| import android.text.Html; | ||||
|  | @ -45,8 +44,8 @@ import androidx.annotation.DrawableRes; | |||
| import androidx.annotation.NonNull; | ||||
| import androidx.annotation.Nullable; | ||||
| import androidx.appcompat.app.AlertDialog; | ||||
| import androidx.appcompat.widget.AppCompatImageView; | ||||
| import androidx.appcompat.widget.SearchView; | ||||
| import androidx.fragment.app.Fragment; | ||||
| import androidx.appcompat.widget.AppCompatTextView; | ||||
| import androidx.recyclerview.widget.DividerItemDecoration; | ||||
| import androidx.recyclerview.widget.LinearLayoutManager; | ||||
|  | @ -54,6 +53,7 @@ import androidx.recyclerview.widget.RecyclerView; | |||
| import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; | ||||
| import butterknife.BindView; | ||||
| import butterknife.ButterKnife; | ||||
| import butterknife.OnClick; | ||||
| import com.google.android.material.bottomsheet.BottomSheetBehavior; | ||||
| import com.google.android.material.chip.Chip; | ||||
| import com.google.android.material.chip.ChipGroup; | ||||
|  | @ -83,26 +83,24 @@ import fr.free.nrw.commons.Utils; | |||
| import fr.free.nrw.commons.auth.LoginActivity; | ||||
| import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao; | ||||
| import fr.free.nrw.commons.contributions.ContributionController; | ||||
| import fr.free.nrw.commons.contributions.ContributionsFragment; | ||||
| import fr.free.nrw.commons.contributions.MainActivity; | ||||
| import fr.free.nrw.commons.contributions.MainActivity.ActiveFragment; | ||||
| import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; | ||||
| import fr.free.nrw.commons.kvstore.JsonKvStore; | ||||
| import fr.free.nrw.commons.location.LocationServiceManager; | ||||
| import fr.free.nrw.commons.location.LocationUpdateListener; | ||||
| import fr.free.nrw.commons.navtab.NavTab; | ||||
| import fr.free.nrw.commons.nearby.CheckBoxTriStates; | ||||
| import fr.free.nrw.commons.nearby.Label; | ||||
| import fr.free.nrw.commons.nearby.MarkerPlaceGroup; | ||||
| import fr.free.nrw.commons.nearby.NearbyBaseMarker; | ||||
| import fr.free.nrw.commons.nearby.NearbyController; | ||||
| import fr.free.nrw.commons.nearby.NearbyController.NearbyPlacesInfo; | ||||
| import fr.free.nrw.commons.nearby.NearbyFilterSearchRecyclerViewAdapter; | ||||
| import fr.free.nrw.commons.nearby.NearbyFilterState; | ||||
| import fr.free.nrw.commons.nearby.NearbyMarker; | ||||
| import fr.free.nrw.commons.nearby.Place; | ||||
| import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract; | ||||
| import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter; | ||||
| import fr.free.nrw.commons.notification.NotificationActivity; | ||||
| import fr.free.nrw.commons.utils.DialogUtil; | ||||
| import fr.free.nrw.commons.utils.ExecutorUtils; | ||||
| import fr.free.nrw.commons.utils.LayoutUtils; | ||||
|  | @ -116,14 +114,18 @@ import fr.free.nrw.commons.utils.ViewUtil; | |||
| import fr.free.nrw.commons.wikidata.WikidataEditListener; | ||||
| import io.reactivex.Observable; | ||||
| import io.reactivex.android.schedulers.AndroidSchedulers; | ||||
| import io.reactivex.disposables.CompositeDisposable; | ||||
| import io.reactivex.functions.Function; | ||||
| import io.reactivex.schedulers.Schedulers; | ||||
| import java.io.IOException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Date; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
| import java.util.concurrent.TimeUnit; | ||||
| import javax.inject.Inject; | ||||
| import javax.inject.Named; | ||||
| import kotlin.Unit; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
| import timber.log.Timber; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -155,6 +157,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     @BindView(R.id.search_this_area_button) Button searchThisAreaButton; | ||||
|     @BindView(R.id.map_progress_bar) ProgressBar progressBar; | ||||
|     @BindView(R.id.choice_chip_exists) Chip chipExists; | ||||
|     @BindView(R.id.choice_chip_wlm) Chip chipWlm; | ||||
|     @BindView(R.id.choice_chip_needs_photo) Chip chipNeedsPhoto; | ||||
|     @BindView(R.id.choice_chip_group) ChipGroup choiceChipGroup; | ||||
|     @BindView(R.id.search_view) SearchView searchView; | ||||
|  | @ -168,6 +171,14 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     @BindView(R.id.no_results_message) TextView noResultsView; | ||||
|     @BindView(R.id.tv_attribution) | ||||
|     AppCompatTextView tvAttribution; | ||||
|     @BindView(R.id.rl_container_wlm_month_message) | ||||
|     RelativeLayout rlContainerWLMMonthMessage; | ||||
|     @BindView(R.id.tv_learn_more) | ||||
|     AppCompatTextView tvLearnMore; | ||||
|     @BindView(R.id.iv_toggle_chips) | ||||
|     AppCompatImageView ivToggleChips; | ||||
|     @BindView(R.id.chip_view) | ||||
|     View llContainerChips; | ||||
| 
 | ||||
|     @Inject LocationServiceManager locationManager; | ||||
|     @Inject NearbyController nearbyController; | ||||
|  | @ -229,7 +240,12 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     /** | ||||
|      * Holds all the markers | ||||
|      */ | ||||
|     private List<NearbyBaseMarker> allMarkers; | ||||
|     private List<NearbyBaseMarker> allMarkers =new ArrayList<>(); | ||||
| 
 | ||||
|     /** | ||||
|      * WLM URL | ||||
|      */ | ||||
|     public static final String WLM_URL = "https://www.wikilovesmonuments.org/"; | ||||
| 
 | ||||
|     @NonNull | ||||
|     public static NearbyParentFragment newInstance() { | ||||
|  | @ -268,6 +284,12 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     public void onViewCreated(@NonNull final View view, @Nullable final Bundle savedInstanceState) { | ||||
|         super.onViewCreated(view, savedInstanceState); | ||||
|         isDarkTheme = systemThemeUtils.isDeviceInNightMode(); | ||||
|         if (Utils.isMonumentsEnabled(new Date(), applicationKvStore)) { | ||||
|             rlContainerWLMMonthMessage.setVisibility(View.VISIBLE); | ||||
|         } else { | ||||
|             rlContainerWLMMonthMessage.setVisibility(View.GONE); | ||||
|         } | ||||
| 
 | ||||
|         cameraMoveListener= () -> presenter.onCameraMove(mapBox.getCameraPosition().target); | ||||
|         addCheckBoxCallback(); | ||||
|         presenter.attachView(this); | ||||
|  | @ -491,6 +513,9 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|         setBottomSheetCallbacks(); | ||||
|         decideButtonVisibilities(); | ||||
|         addActionToTitle(); | ||||
|         if(!Utils.isMonumentsEnabled(new Date(), applicationKvStore)){ | ||||
|             chipWlm.setVisibility(View.GONE); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -598,6 +623,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|         Log.d("deneme5","setfilterState"); | ||||
|         chipNeedsPhoto.setChecked(NearbyFilterState.getInstance().isNeedPhotoSelected()); | ||||
|         chipExists.setChecked(NearbyFilterState.getInstance().isExistsSelected()); | ||||
|         chipWlm.setChecked(NearbyFilterState.getInstance().isWlmSelected()); | ||||
|         if (NearbyController.currentLocation != null) { | ||||
|             presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|         } | ||||
|  | @ -608,13 +634,8 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|         chipNeedsPhoto.setOnCheckedChangeListener((buttonView, isChecked) -> { | ||||
|             if (NearbyController.currentLocation != null) { | ||||
|                 checkBoxTriStates.setState(CheckBoxTriStates.UNKNOWN); | ||||
|                 if (isChecked) { | ||||
|                     NearbyFilterState.setNeedPhotoSelected(true); | ||||
|                     presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|                 } else { | ||||
|                     NearbyFilterState.setNeedPhotoSelected(false); | ||||
|                     presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|                 } | ||||
|                 NearbyFilterState.setNeedPhotoSelected(isChecked); | ||||
|                 presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|             } else { | ||||
|                 chipNeedsPhoto.setChecked(!isChecked); | ||||
|             } | ||||
|  | @ -624,17 +645,23 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|         chipExists.setOnCheckedChangeListener((buttonView, isChecked) -> { | ||||
|             if (NearbyController.currentLocation != null) { | ||||
|                 checkBoxTriStates.setState(CheckBoxTriStates.UNKNOWN); | ||||
|                 if (isChecked) { | ||||
|                     NearbyFilterState.setExistsSelected(true); | ||||
|                     presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|                 } else { | ||||
|                     NearbyFilterState.setExistsSelected(false); | ||||
|                     presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|                 } | ||||
|                 NearbyFilterState.setExistsSelected(isChecked); | ||||
|                 presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|             } else { | ||||
|                 chipExists.setChecked(!isChecked); | ||||
|             } | ||||
|         }); | ||||
| 
 | ||||
| 
 | ||||
|         chipWlm.setOnCheckedChangeListener((buttonView, isChecked) -> { | ||||
|             if(NearbyController.currentLocation!=null){ | ||||
|                 checkBoxTriStates.setState(CheckBoxTriStates.UNKNOWN); | ||||
|                 NearbyFilterState.setWlmSelected(isChecked); | ||||
|                 presenter.filterByMarkerType(nearbyFilterSearchRecyclerViewAdapter.selectedLabels, checkBoxTriStates.getState(), true, false); | ||||
|             }else{ | ||||
|                 chipWlm.setChecked(!isChecked); | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -852,40 +879,105 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     } | ||||
| 
 | ||||
|     private void populatePlacesForCurrentLocation(final fr.free.nrw.commons.location.LatLng curlatLng, | ||||
|                                                   final fr.free.nrw.commons.location.LatLng searchLatLng) { | ||||
|         compositeDisposable.add(Observable.fromCallable(() -> nearbyController | ||||
|                 .loadAttractionsFromLocation(curlatLng, searchLatLng, false, true)) | ||||
|                 .subscribeOn(Schedulers.io()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .subscribe(nearbyPlacesInfo -> { | ||||
|                             updateMapMarkers(nearbyPlacesInfo, true); | ||||
|                             lastFocusLocation=searchLatLng; | ||||
|                         }, | ||||
|                         throwable -> { | ||||
|                             Timber.d(throwable); | ||||
|                             showErrorMessage(getString(R.string.error_fetching_nearby_places)+throwable.getLocalizedMessage()); | ||||
|                             setProgressBarVisibility(false); | ||||
|                             presenter.lockUnlockNearby(false); | ||||
|                             setFilterState(); | ||||
|                         })); | ||||
|                                                   final fr.free.nrw.commons.location.LatLng searchLatLng){ | ||||
| 
 | ||||
|         final Observable<NearbyPlacesInfo> nearbyPlacesInfoObservable = Observable | ||||
|             .fromCallable(() -> nearbyController | ||||
|                 .loadAttractionsFromLocation(curlatLng, searchLatLng, false, true)); | ||||
| 
 | ||||
|         Observable<List<Place>> observableWikidataMonuments = Observable.empty(); | ||||
|         if(Utils.isMonumentsEnabled(new Date(), applicationKvStore)){ | ||||
|                 observableWikidataMonuments = | ||||
|                     nearbyController | ||||
|                         .queryWikiDataForMonuments(searchLatLng, Locale.getDefault().getLanguage()); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         compositeDisposable.add(Observable.zip(nearbyPlacesInfoObservable | ||||
|             , observableWikidataMonuments.onErrorReturn(throwable -> { | ||||
|                 showErrorMessage(getString(R.string.error_fetching_nearby_monuments) + throwable | ||||
|                     .getLocalizedMessage()); | ||||
|                 return new ArrayList<>(); | ||||
|             }), | ||||
|             (nearbyPlacesInfo, monuments) -> { | ||||
|                 final List<Place> places = mergeNearbyPlacesAndMonuments(nearbyPlacesInfo.placeList, | ||||
|                     monuments); | ||||
|                 nearbyPlacesInfo.placeList.clear(); | ||||
|                 nearbyPlacesInfo.placeList.addAll(places); | ||||
|                 return nearbyPlacesInfo; | ||||
|             }).subscribeOn(Schedulers.io()) | ||||
|             .observeOn(AndroidSchedulers.mainThread()) | ||||
|             .subscribe(nearbyPlacesInfo -> { | ||||
|                     updateMapMarkers(nearbyPlacesInfo, true); | ||||
|                     lastFocusLocation=searchLatLng; | ||||
|                 }, | ||||
|                 throwable -> { | ||||
|                     Timber.d(throwable); | ||||
|                     showErrorMessage(getString(R.string.error_fetching_nearby_places)+throwable.getLocalizedMessage()); | ||||
|                     setProgressBarVisibility(false); | ||||
|                     presenter.lockUnlockNearby(false); | ||||
|                     setFilterState(); | ||||
|                 })); | ||||
|     } | ||||
| 
 | ||||
|     private void populatePlacesForAnotherLocation(final fr.free.nrw.commons.location.LatLng curlatLng, | ||||
|                                                   final fr.free.nrw.commons.location.LatLng searchLatLng) { | ||||
|         compositeDisposable.add(Observable.fromCallable(() -> nearbyController | ||||
|                 .loadAttractionsFromLocation(curlatLng, searchLatLng, false, false)) | ||||
|                 .subscribeOn(Schedulers.io()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .subscribe(nearbyPlacesInfo -> { | ||||
|                             updateMapMarkers(nearbyPlacesInfo, false); | ||||
|                             lastFocusLocation=searchLatLng; | ||||
|                         }, | ||||
|                         throwable -> { | ||||
|                             Timber.d(throwable); | ||||
|                             showErrorMessage(getString(R.string.error_fetching_nearby_places)+throwable.getLocalizedMessage()); | ||||
|                             setProgressBarVisibility(false); | ||||
|                             presenter.lockUnlockNearby(false); | ||||
|                         })); | ||||
|                                                   final fr.free.nrw.commons.location.LatLng searchLatLng){ | ||||
| 
 | ||||
|         final Observable<NearbyPlacesInfo> nearbyPlacesInfoObservable = Observable | ||||
|             .fromCallable(() -> nearbyController | ||||
|                 .loadAttractionsFromLocation(curlatLng, searchLatLng, false, false)); | ||||
| 
 | ||||
|         Observable<List<Place>> observableWikidataMonuments = Observable.empty(); | ||||
|         if (Utils.isMonumentsEnabled(new Date(), applicationKvStore)) { | ||||
|             observableWikidataMonuments = nearbyController | ||||
|                 .queryWikiDataForMonuments(searchLatLng, Locale.getDefault().getLanguage()); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         compositeDisposable.add(Observable.zip(nearbyPlacesInfoObservable | ||||
|             , observableWikidataMonuments.onErrorReturn(throwable -> { | ||||
|                 showErrorMessage(getString(R.string.error_fetching_nearby_monuments) + throwable | ||||
|                     .getLocalizedMessage()); | ||||
|                 return new ArrayList<>(); | ||||
|             }), | ||||
|             (nearbyPlacesInfo, monuments) -> { | ||||
|                 final List<Place> places = mergeNearbyPlacesAndMonuments(nearbyPlacesInfo.placeList, | ||||
|                     monuments); | ||||
|                 nearbyPlacesInfo.placeList.clear(); | ||||
|                 nearbyPlacesInfo.placeList.addAll(places); | ||||
|                 return nearbyPlacesInfo; | ||||
|             }).subscribeOn(Schedulers.io()) | ||||
|             .observeOn(AndroidSchedulers.mainThread()) | ||||
|             .subscribe(nearbyPlacesInfo -> { | ||||
|                     updateMapMarkers(nearbyPlacesInfo, false); | ||||
|                     lastFocusLocation=searchLatLng; | ||||
|                 }, | ||||
|                 throwable -> { | ||||
|                     Timber.e(throwable); | ||||
|                     showErrorMessage(getString(R.string.error_fetching_nearby_places)+throwable.getLocalizedMessage()); | ||||
|                     setProgressBarVisibility(false); | ||||
|                     presenter.lockUnlockNearby(false); | ||||
|                     setFilterState(); | ||||
|                 })); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * If a nearby place happens to be a monument as well, don't make the Pin's overlap, instead | ||||
|      * show it as a monument | ||||
|      * | ||||
|      * @param nearbyPlaces | ||||
|      * @param monuments | ||||
|      * @return | ||||
|      */ | ||||
|     private List<Place> mergeNearbyPlacesAndMonuments(List<Place> nearbyPlaces, List<Place> monuments){ | ||||
|         List<Place> allPlaces= new ArrayList<>(); | ||||
|         allPlaces.addAll(monuments); | ||||
|         for (Place place : nearbyPlaces){ | ||||
|             if(!allPlaces.contains(place)){ | ||||
|                 allPlaces.add(place); | ||||
|             } | ||||
|         } | ||||
|         return allPlaces; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | @ -1178,7 +1270,9 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     private void removeCurrentLocationMarker() { | ||||
|         if (currentLocationMarker != null && mapBox!=null) { | ||||
|             mapBox.removeMarker(currentLocationMarker); | ||||
|             mapBox.removePolygon(currentLocationPolygon); | ||||
|             if (currentLocationPolygon != null) { | ||||
|                 mapBox.removePolygon(currentLocationPolygon); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|  | @ -1244,6 +1338,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     public void filterMarkersByLabels(final List<Label> selectedLabels, | ||||
|         final boolean displayExists, | ||||
|         final boolean displayNeedsPhoto, | ||||
|         final boolean displayWlm, | ||||
|         final boolean filterForPlaceState, | ||||
|         final boolean filterForAllNoneType) { | ||||
| 
 | ||||
|  | @ -1263,23 +1358,36 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             if (displayExists && displayNeedsPhoto) { | ||||
|             if (!displayWlm && place.isMonument()) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             boolean shouldUpdateMarker=false; | ||||
| 
 | ||||
|             if (displayWlm && place.isMonument()) { | ||||
|                 shouldUpdateMarker=true; | ||||
|             } | ||||
|             else if (displayExists && displayNeedsPhoto) { | ||||
|                 // Exists and needs photo | ||||
|                 if (place.exists && place.pic.trim().isEmpty()) { | ||||
|                     updateMarker(markerPlaceGroup.getIsBookmarked(), place, NearbyController.currentLocation); | ||||
|                     shouldUpdateMarker=true; | ||||
|                 } | ||||
|             } else if (displayExists && !displayNeedsPhoto) { | ||||
|                 // Exists and all included needs and doesn't needs photo | ||||
|                 if (place.exists) { | ||||
|                     updateMarker(markerPlaceGroup.getIsBookmarked(), place, NearbyController.currentLocation); | ||||
|                     shouldUpdateMarker=true; | ||||
|                 } | ||||
|             } else if (!displayExists && displayNeedsPhoto) { | ||||
|                 // All and only needs photo | ||||
|                 if (place.pic.trim().isEmpty()) { | ||||
|                     updateMarker(markerPlaceGroup.getIsBookmarked(), place, NearbyController.currentLocation); | ||||
|                     shouldUpdateMarker=true; | ||||
|                 } | ||||
|             } else if (!displayExists && !displayNeedsPhoto) { | ||||
|                 // all | ||||
|                 shouldUpdateMarker=true; | ||||
|             } | ||||
| 
 | ||||
|             if(shouldUpdateMarker){ | ||||
|                 updateMarker(markerPlaceGroup.getIsBookmarked(), place, NearbyController.currentLocation); | ||||
|             } | ||||
|         } | ||||
|  | @ -1337,7 +1445,10 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     } | ||||
| 
 | ||||
|     private @DrawableRes int getIconFor(Place place, Boolean isBookmarked) { | ||||
|         if (!place.pic.trim().isEmpty()) { | ||||
|         if(place.isMonument()){ | ||||
|             return R.drawable.ic_custom_map_marker_monuments; | ||||
|         } | ||||
|         else if (!place.pic.trim().isEmpty()) { | ||||
|             return (isBookmarked ? | ||||
|                 R.drawable.ic_custom_map_marker_green_bookmarked : | ||||
|                 R.drawable.ic_custom_map_marker_green); | ||||
|  | @ -1397,7 +1508,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void recenterMap(final fr.free.nrw.commons.location.LatLng curLatLng) { | ||||
|     public void recenterMap(fr.free.nrw.commons.location.LatLng curLatLng) { | ||||
|         if (isPermissionDenied || curLatLng == null) { | ||||
|             recenterToUserLocation = true; | ||||
|             checkPermissionsAndPerformAction(); | ||||
|  | @ -1667,4 +1778,21 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment | |||
|         rlBottomSheetLayoutParams.height = getActivity().getWindowManager().getDefaultDisplay().getHeight() / 16 * 9; | ||||
|         rlBottomSheet.setLayoutParams(rlBottomSheetLayoutParams); | ||||
|         } | ||||
| 
 | ||||
|     @OnClick(R.id.tv_learn_more) | ||||
|     public void onLearnMoreClicked() { | ||||
|         Intent intent = new Intent(Intent.ACTION_VIEW); | ||||
|         intent.setData(Uri.parse(WLM_URL)); | ||||
|         startActivity(intent); | ||||
|     } | ||||
| 
 | ||||
|     @OnClick(R.id.iv_toggle_chips) | ||||
|     public void onToggleChipsClicked() { | ||||
|         if (llContainerChips.getVisibility() == View.VISIBLE) { | ||||
|             llContainerChips.setVisibility(View.GONE); | ||||
|         } else { | ||||
|             llContainerChips.setVisibility(View.VISIBLE); | ||||
|         } | ||||
|         ivToggleChips.setRotation(ivToggleChips.getRotation() + 180); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ class NearbyResultItem(private val item: ResultTuple?, | |||
|                        private val commonsArticle: ResultTuple?, | ||||
|                        private val location: ResultTuple?, | ||||
|                        private val label: ResultTuple?, | ||||
|                        @field:SerializedName("streetAddress") private val address: ResultTuple?, | ||||
|                        private val icon: ResultTuple?, @field:SerializedName("class") private val className: ResultTuple?, | ||||
|                        @field:SerializedName("classLabel") private val classLabel: ResultTuple?, | ||||
|                        @field:SerializedName("commonsCategory") private val commonsCategory: ResultTuple?, | ||||
|  | @ -66,4 +67,8 @@ class NearbyResultItem(private val item: ResultTuple?, | |||
|     fun getEndTime(): ResultTuple { | ||||
|         return endTime ?: ResultTuple() | ||||
|     } | ||||
| 
 | ||||
|     fun getAddress(): String { | ||||
|         return address?.value?:"" | ||||
|     } | ||||
| } | ||||
|  | @ -1,6 +1,5 @@ | |||
| package fr.free.nrw.commons.nearby.presenter; | ||||
| 
 | ||||
| import android.util.Log; | ||||
| import android.view.View; | ||||
| 
 | ||||
| import androidx.annotation.MainThread; | ||||
|  | @ -297,6 +296,7 @@ public class NearbyParentFragmentPresenter | |||
|                     nearbyParentFragmentView.filterMarkersByLabels(selectedLabels, | ||||
|                         NearbyFilterState.getInstance().isExistsSelected(), | ||||
|                         NearbyFilterState.getInstance().isNeedPhotoSelected(), | ||||
|                         NearbyFilterState.getInstance().isWlmSelected(), | ||||
|                         filterForPlaceState, false); | ||||
|                     nearbyParentFragmentView.setRecyclerViewAdapterAllSelected(); | ||||
|                     break; | ||||
|  | @ -305,6 +305,7 @@ public class NearbyParentFragmentPresenter | |||
|             nearbyParentFragmentView.filterMarkersByLabels(selectedLabels, | ||||
|                     NearbyFilterState.getInstance().isExistsSelected(), | ||||
|                     NearbyFilterState.getInstance().isNeedPhotoSelected(), | ||||
|                     NearbyFilterState.getInstance().isWlmSelected(), | ||||
|                     filterForPlaceState, false); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Ashish
						Ashish