mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 12:53:55 +01:00
* Fixes #3303 * Refactor Nearby to alig lifecycle methods * Pass updated place list to listfragment * Added default zoom rate to mapbox * Removed NearbyListFragmet and added the ui login to handle the same in NearbyParentFragment * More code refactor * Make BottomSheetList hideable * onFragmentHide, hide the bottom sheets * BigFix, Fragmet visibility, register/un-register camera move based on fragments lifecycke * More code refactor * Let the ExecutorUtil have non-ui thread * Add Location Marker on non-ui thread (the non-ui stuffs) * BugFixes * Removed configchanges "orientation" from MainActivity in Manifest (That was messing with the fragment lifecycle) * Some null checks * Initialise lastknown location in onMapReady * UI Fixes * Adjusted UI to support dark and no-dark themes both (in nearby) * Do not update map on Location Slightly changed * Fix failing test case, let TestCommonsApplication extend Application instead of CommonsApplication * start map view when nearby is visible * start the map when NearbyFragmet is visible * More bugfixes * Added DUMMY view for NearbyPresenter's onDetach State * Added a wrapper frame layout parent for MapView to preven it from drawing above other views * More bugfixes (Fixes #3287) * Gray out the un-selected markers from the nearby filter list * BugFix, search this area should search the nearby places for the current camera position * More BugFixes * Handle null primitives with proxy * Current location marker flow via permission flow * onCameraMove should have null-check on NearbyController.latestSearchLocation instead of currentLocation * Search for places around last focus location * Handle location updates * If the user is browsing the map, donot update the map with current location
This commit is contained in:
parent
a6d2523588
commit
05e98307be
25 changed files with 915 additions and 1254 deletions
|
|
@ -78,7 +78,7 @@
|
|||
android:name=".contributions.MainActivity"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:configChanges="orientation|screenSize|keyboard" />
|
||||
android:configChanges="screenSize|keyboard" />
|
||||
<activity
|
||||
android:name=".settings.SettingsActivity"
|
||||
android:label="@string/title_activity_settings" />
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import com.facebook.imagepipeline.producers.Consumer;
|
|||
import com.facebook.imagepipeline.producers.FetchState;
|
||||
import com.facebook.imagepipeline.producers.NetworkFetcher;
|
||||
import com.facebook.imagepipeline.producers.ProducerContext;
|
||||
import com.mapbox.mapboxsdk.Mapbox;
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
import com.squareup.leakcanary.RefWatcher;
|
||||
|
||||
|
|
@ -134,6 +135,7 @@ public class CommonsApplication extends Application {
|
|||
|
||||
INSTANCE = this;
|
||||
ACRA.init(this);
|
||||
Mapbox.getInstance(this, getString(R.string.mapbox_commons_app_token));
|
||||
|
||||
ApplicationlessInjection
|
||||
.getInstance(this)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ import fr.free.nrw.commons.auth.SessionManager;
|
|||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.nearby.NearbyNotificationCardView;
|
||||
import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment;
|
||||
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
|
||||
import fr.free.nrw.commons.notification.Notification;
|
||||
import fr.free.nrw.commons.notification.NotificationActivity;
|
||||
import fr.free.nrw.commons.notification.NotificationController;
|
||||
|
|
@ -78,6 +77,7 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
|
|||
|
||||
private MenuItem notificationsMenuItem;
|
||||
private TextView notificationCount;
|
||||
private NearbyParentFragment nearbyParentFragment;
|
||||
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
@ -188,8 +188,6 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
|
|||
tabLayout.getTabAt(NEARBY_TAB_POSITION).select();
|
||||
isContributionsFragmentVisible = false;
|
||||
updateMenuItem();
|
||||
// Do all permission and GPS related tasks on tab selected, not on create
|
||||
NearbyParentFragmentPresenter.getInstance().onTabSelected();
|
||||
break;
|
||||
default:
|
||||
tabLayout.getTabAt(CONTRIBUTIONS_TAB_POSITION).select();
|
||||
|
|
@ -265,7 +263,9 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
|
|||
}
|
||||
} else if (getSupportFragmentManager().findFragmentByTag(nearbyFragmentTag) != null && !isContributionsFragmentVisible) {
|
||||
// Means that nearby fragment is visible (not contributions fragment)
|
||||
NearbyParentFragmentPresenter.getInstance().backButtonClicked();
|
||||
if (null != nearbyParentFragment) {
|
||||
nearbyParentFragment.backButtonClicked();
|
||||
}
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
|
|
@ -380,12 +380,13 @@ public class MainActivity extends NavigationBaseActivity implements FragmentMana
|
|||
}
|
||||
|
||||
case 1:
|
||||
NearbyParentFragment retainedNearbyFragment = getNearbyFragment(1);
|
||||
if (retainedNearbyFragment != null) {
|
||||
return retainedNearbyFragment;
|
||||
nearbyParentFragment = getNearbyFragment(1);
|
||||
if (nearbyParentFragment != null) {
|
||||
return nearbyParentFragment;
|
||||
} else {
|
||||
// If we reach here, retainedNearbyFragment is null
|
||||
return new NearbyParentFragment();
|
||||
nearbyParentFragment=new NearbyParentFragment();
|
||||
return nearbyParentFragment;
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -13,8 +13,6 @@ import fr.free.nrw.commons.explore.images.SearchImageFragment;
|
|||
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesFragment;
|
||||
import fr.free.nrw.commons.media.MediaDetailFragment;
|
||||
import fr.free.nrw.commons.media.MediaDetailPagerFragment;
|
||||
import fr.free.nrw.commons.nearby.fragments.NearbyListFragment;
|
||||
import fr.free.nrw.commons.nearby.fragments.NearbyMapFragment;
|
||||
import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment;
|
||||
import fr.free.nrw.commons.review.ReviewImageFragment;
|
||||
import fr.free.nrw.commons.settings.SettingsFragment;
|
||||
|
|
@ -40,9 +38,6 @@ public abstract class FragmentBuilderModule {
|
|||
@ContributesAndroidInjector
|
||||
abstract MediaDetailPagerFragment bindMediaDetailPagerFragment();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract NearbyListFragment bindNearbyListFragment();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract SettingsFragment bindSettingsFragment();
|
||||
|
||||
|
|
@ -64,9 +59,6 @@ public abstract class FragmentBuilderModule {
|
|||
@ContributesAndroidInjector
|
||||
abstract ContributionsFragment bindContributionsFragment();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract NearbyMapFragment bindNearbyMapFragment();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract NearbyParentFragment bindNearbyParentFragment();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ import android.widget.CompoundButton;
|
|||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.widget.AppCompatCheckBox;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
|
||||
|
||||
|
|
@ -25,6 +27,16 @@ public class CheckBoxTriStates extends AppCompatCheckBox {
|
|||
|
||||
private int state;
|
||||
|
||||
private Callback callback;
|
||||
|
||||
public interface Callback{
|
||||
void filterByMarkerType(@Nullable List<Label> selectedLabels, int state, boolean b, boolean b1);
|
||||
}
|
||||
|
||||
public void setCallback(Callback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the listener set to the super class which is going to be evoke each
|
||||
* time the check state has changed.
|
||||
|
|
@ -87,7 +99,7 @@ public class CheckBoxTriStates extends AppCompatCheckBox {
|
|||
}
|
||||
|
||||
if (NearbyController.currentLocation != null) {
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(null, state, false, true);
|
||||
callback.filterByMarkerType(null, state, false, true);
|
||||
}
|
||||
updateBtn();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,10 +17,6 @@ public class NearbyAdapterFactory {
|
|||
private Fragment fragment;
|
||||
private ContributionController controller;
|
||||
|
||||
NearbyAdapterFactory(){
|
||||
|
||||
}
|
||||
|
||||
public NearbyAdapterFactory(Fragment fragment, ContributionController controller) {
|
||||
this.fragment = fragment;
|
||||
this.controller = controller;
|
||||
|
|
|
|||
|
|
@ -27,20 +27,24 @@ public class NearbyFilterSearchRecyclerViewAdapter
|
|||
|
||||
private final LayoutInflater inflater;
|
||||
private Context context;
|
||||
private RecyclerView recyclerView;
|
||||
private ArrayList<Label> labels;
|
||||
private ArrayList<Label> displayedLabels;
|
||||
public ArrayList<Label> selectedLabels = new ArrayList<>();
|
||||
|
||||
private int state;
|
||||
|
||||
private Callback callback;
|
||||
|
||||
RecyclerView.SmoothScroller smoothScroller;
|
||||
|
||||
public void setCallback(Callback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public NearbyFilterSearchRecyclerViewAdapter(Context context, ArrayList<Label> labels, RecyclerView recyclerView) {
|
||||
this.context = context;
|
||||
this.labels = labels;
|
||||
this.displayedLabels = labels;
|
||||
this.recyclerView = recyclerView;
|
||||
smoothScroller = new
|
||||
LinearSmoothScroller(context) {
|
||||
@Override protected int getVerticalSnapPreference() {
|
||||
|
|
@ -66,7 +70,7 @@ public class NearbyFilterSearchRecyclerViewAdapter
|
|||
@NonNull
|
||||
@Override
|
||||
public RecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = inflater.inflate(R.layout.nearby_search_list_item, parent, false);
|
||||
View itemView = inflater.inflate(callback.isDarkTheme()?R.layout.nearby_search_list_item_dark:R.layout.nearby_search_list_item, parent, false);
|
||||
return new RecyclerViewHolder(itemView);
|
||||
}
|
||||
|
||||
|
|
@ -76,9 +80,9 @@ public class NearbyFilterSearchRecyclerViewAdapter
|
|||
holder.placeTypeIcon.setImageResource(label.getIcon());
|
||||
holder.placeTypeLabel.setText(label.toString());
|
||||
|
||||
holder.placeTypeLayout.setBackgroundColor(label.isSelected() ? ContextCompat.getColor(context, R.color.divider_grey) : Color.WHITE);
|
||||
holder.placeTypeLayout.setBackgroundColor(label.isSelected() ? ContextCompat.getColor(context, R.color.divider_grey) : callback.isDarkTheme()?Color.BLACK:Color.WHITE);
|
||||
holder.placeTypeLayout.setOnClickListener(view -> {
|
||||
NearbyParentFragmentPresenter.getInstance().setCheckboxUnknown();
|
||||
callback.setCheckboxUnknown();
|
||||
if (label.isSelected()) {
|
||||
selectedLabels.remove(label);
|
||||
} else {
|
||||
|
|
@ -86,7 +90,7 @@ public class NearbyFilterSearchRecyclerViewAdapter
|
|||
}
|
||||
label.setSelected(!label.isSelected());
|
||||
holder.placeTypeLayout.setBackgroundColor(label.isSelected() ? ContextCompat.getColor(context, R.color.divider_grey) : Color.WHITE);
|
||||
NearbyParentFragmentPresenter.getInstance().filterByMarkerType(selectedLabels, 0, false, false);
|
||||
callback.filterByMarkerType(selectedLabels, 0, false, false);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -161,8 +165,13 @@ public class NearbyFilterSearchRecyclerViewAdapter
|
|||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setRecyclerViewAdapterNeutral() {
|
||||
state = CheckBoxTriStates.UNKNOWN;
|
||||
public interface Callback{
|
||||
|
||||
void setCheckboxUnknown();
|
||||
|
||||
void filterByMarkerType(ArrayList<Label> selectedLabels, int i, boolean b, boolean b1);
|
||||
|
||||
boolean isDarkTheme();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,11 +34,9 @@ import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
|||
import fr.free.nrw.commons.contributions.ContributionController;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.nearby.fragments.NearbyMapFragment;
|
||||
import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static fr.free.nrw.commons.nearby.fragments.NearbyParentFragment.TAG_RETAINED_MAP_FRAGMENT;
|
||||
import static fr.free.nrw.commons.theme.NavigationBaseActivity.startActivityWithFlags;
|
||||
import static fr.free.nrw.commons.wikidata.WikidataConstants.PLACE_OBJECT;
|
||||
|
||||
|
|
@ -121,7 +119,7 @@ public class PlaceRenderer extends Renderer<Place> {
|
|||
}
|
||||
}
|
||||
if (onBookmarkClick == null) {
|
||||
((NearbyParentFragment) fragment.getParentFragment()).centerMapToPlace(place);
|
||||
((NearbyParentFragment) fragment).centerMapToPlace(place);
|
||||
}
|
||||
};
|
||||
view.setOnClickListener(listener);
|
||||
|
|
@ -194,8 +192,7 @@ public class PlaceRenderer extends Renderer<Place> {
|
|||
onBookmarkClick.onClick();
|
||||
}
|
||||
else {
|
||||
((NearbyMapFragment)(fragment.getParentFragment()).getChildFragmentManager().
|
||||
findFragmentByTag(TAG_RETAINED_MAP_FRAGMENT)).
|
||||
((NearbyParentFragment) (fragment.getParentFragment())).
|
||||
updateMarker(isBookmarked, place, null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
package fr.free.nrw.commons.nearby.contract;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
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;
|
||||
|
||||
/**
|
||||
* This interface defines specific View and UserActions for map
|
||||
* part of the nearby.
|
||||
*/
|
||||
public interface NearbyMapContract {
|
||||
|
||||
interface View{
|
||||
void updateMapMarkers(LatLng latLng, List<Place> placeList, Marker selectedMarker, NearbyParentFragmentPresenter nearbyParentFragmentPresenter);
|
||||
void updateMapToTrackPosition(LatLng curLatLng);
|
||||
void addCurrentLocationMarker(LatLng curLatLng);
|
||||
void addNearbyMarkersToMapBoxMap(List<NearbyBaseMarker> baseMarkerOptions, Marker marker, NearbyParentFragmentPresenter nearbyParentFragmentPresenter);
|
||||
LatLng getCameraTarget();
|
||||
MapboxMap getMapboxMap();
|
||||
void viewsAreAssignedToPresenter(NearbyParentFragmentContract.ViewsAreReadyCallback viewsAreReadyCallback);
|
||||
void addOnCameraMoveListener(MapboxMap.OnCameraMoveListener onCameraMoveListener);
|
||||
void centerMapToPlace(Place place, boolean isPortraitMode);
|
||||
void removeCurrentLocationMarker();
|
||||
List<NearbyBaseMarker> getBaseMarkerOptions();
|
||||
void filterMarkersByLabels(List<Label> labelList, boolean displayExists, boolean displayNeeds, boolean filterForPlaceState, boolean filterForAllNoneType);
|
||||
void filterOutAllMarkers();
|
||||
void displayAllMarkers();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package fr.free.nrw.commons.nearby.contract;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
|
||||
|
|
@ -9,16 +11,16 @@ import fr.free.nrw.commons.kvstore.JsonKvStore;
|
|||
import fr.free.nrw.commons.location.LatLng;
|
||||
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 {
|
||||
|
||||
interface View {
|
||||
void registerLocationUpdates(LocationServiceManager locationServiceManager);
|
||||
boolean isNetworkConnectionEstablished();
|
||||
void addNetworkBroadcastReceiver();
|
||||
void listOptionMenuItemClicked();
|
||||
void populatePlaces(LatLng curlatLng, LatLng searchLatLng);
|
||||
void populatePlaces(LatLng curlatLng);
|
||||
boolean isListBottomSheetExpanded();
|
||||
void checkPermissionsAndPerformAction(Runnable runnable);
|
||||
void displayLoginSkippedWarning();
|
||||
|
|
@ -29,7 +31,7 @@ public interface NearbyParentFragmentContract {
|
|||
void hideBottomSheet();
|
||||
void hideBottomDetailsSheet();
|
||||
void displayBottomSheetWithInfo(Marker marker);
|
||||
void addOnCameraMoveListener(MapboxMap.OnCameraMoveListener onCameraMoveListener);
|
||||
void addOnCameraMoveListener();
|
||||
void addSearchThisAreaButtonAction();
|
||||
void setSearchThisAreaButtonVisibility(boolean isVisible);
|
||||
void setProgressBarVisibility(boolean isVisible);
|
||||
|
|
@ -44,6 +46,29 @@ public interface NearbyParentFragmentContract {
|
|||
void setFilterState();
|
||||
void disableFABRecenter();
|
||||
void enableFABRecenter();
|
||||
void addCurrentLocationMarker(LatLng curLatLng);
|
||||
|
||||
void updateMapToTrackPosition(LatLng curLatLng);
|
||||
|
||||
Context getContext();
|
||||
|
||||
void updateMapMarkers(List<NearbyBaseMarker> nearbyBaseMarkers, Marker selectedMarker);
|
||||
|
||||
void filterOutAllMarkers();
|
||||
|
||||
void displayAllMarkers();
|
||||
|
||||
void filterMarkersByLabels(List<Label> selectedLabels, boolean existsSelected, boolean needPhotoSelected, boolean filterForPlaceState, boolean filterForAllNoneType);
|
||||
|
||||
LatLng getCameraTarget();
|
||||
|
||||
void centerMapToPlace(Place placeToCenter);
|
||||
|
||||
void updateListFragment(List<Place> placeList);
|
||||
|
||||
LatLng getLastLocation();
|
||||
|
||||
com.mapbox.mapboxsdk.geometry.LatLng getLastFocusLocation();
|
||||
}
|
||||
|
||||
interface NearbyListView {
|
||||
|
|
@ -51,19 +76,21 @@ public interface NearbyParentFragmentContract {
|
|||
}
|
||||
|
||||
interface UserActions {
|
||||
void onTabSelected();
|
||||
void checkForPermission();
|
||||
void updateMapAndList(LocationServiceManager.LocationChangeType locationChangeType, LatLng cameraTarget);
|
||||
void updateMapAndList(LocationServiceManager.LocationChangeType locationChangeType);
|
||||
void lockUnlockNearby(boolean isNearbyLocked);
|
||||
|
||||
void attachView(View view);
|
||||
|
||||
void detachView();
|
||||
|
||||
void setActionListeners(JsonKvStore applicationKvStore);
|
||||
void backButtonClicked();
|
||||
MapboxMap.OnCameraMoveListener onCameraMove(MapboxMap mapboxMap);
|
||||
void onCameraMove(com.mapbox.mapboxsdk.geometry.LatLng latLng);
|
||||
void filterByMarkerType(List<Label> selectedLabels, int state, boolean filterForPlaceState, boolean filterForAllNoneType);
|
||||
|
||||
void updateMapMarkersToController(List<NearbyBaseMarker> nearbyBaseMarkers);
|
||||
|
||||
void searchViewGainedFocus();
|
||||
void setCheckboxUnknown();
|
||||
}
|
||||
|
||||
interface ViewsAreReadyCallback {
|
||||
void nearbyFragmentsAreReady();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,104 +0,0 @@
|
|||
package fr.free.nrw.commons.nearby.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.ContributionController;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.nearby.NearbyAdapterFactory;
|
||||
import fr.free.nrw.commons.nearby.NearbyController;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class NearbyListFragment extends CommonsDaggerSupportFragment implements NearbyParentFragmentContract.NearbyListView {
|
||||
|
||||
private static final Type LIST_TYPE = new TypeToken<List<Place>>() {
|
||||
}.getType();
|
||||
private static final Type CUR_LAT_LNG_TYPE = new TypeToken<LatLng>() {
|
||||
}.getType();
|
||||
|
||||
private NearbyAdapterFactory adapterFactory;
|
||||
private RecyclerView recyclerView;
|
||||
|
||||
@Inject ContributionController controller;
|
||||
@Inject Gson gson;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setRetainInstance(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater,
|
||||
ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
Timber.d("NearbyListFragment created");
|
||||
View view = inflater.inflate(R.layout.fragment_nearby_list, container, false);
|
||||
recyclerView = view.findViewById(R.id.listView);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
adapterFactory = new NearbyAdapterFactory(this, controller);
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
// Check that this is the first time view is created,
|
||||
// to avoid double list when screen orientation changed
|
||||
Bundle bundle = this.getArguments();
|
||||
recyclerView.setAdapter(adapterFactory.create(getPlaceListFromBundle(bundle)));
|
||||
}
|
||||
|
||||
/**
|
||||
* When user moved too much, we need to update nearby list too. This operation is made by passing
|
||||
* a bundle from NearbyFragment to NearbyListFragment and NearbyMapFragment. This method extracts
|
||||
* place list from bundle to a list variable.
|
||||
* @param bundle Bundle passed from NearbyFragment on users significant moving
|
||||
* @return List of new nearby places
|
||||
*/
|
||||
private List<Place> getPlaceListFromBundle(Bundle bundle) {
|
||||
List<Place> placeList = Collections.emptyList();
|
||||
|
||||
if (bundle != null) {
|
||||
String gsonPlaceList = bundle.getString("PlaceList", "[]");
|
||||
placeList = gson.fromJson(gsonPlaceList, LIST_TYPE);
|
||||
|
||||
String gsonLatLng = bundle.getString("CurLatLng");
|
||||
LatLng curLatLng = gson.fromJson(gsonLatLng, CUR_LAT_LNG_TYPE);
|
||||
|
||||
placeList = NearbyController.loadAttractionsFromLocationToPlaces(curLatLng, placeList);
|
||||
}
|
||||
|
||||
return placeList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateListFragment(List<Place> placeList) {
|
||||
Timber.d("Update list fragment");
|
||||
adapterFactory.updateAdapterData(placeList, (RVRendererAdapter<Place>) recyclerView.getAdapter());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,596 +0,0 @@
|
|||
package fr.free.nrw.commons.nearby.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.IconFactory;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.Polygon;
|
||||
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.maps.MapFragment;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.utils.MapFragmentUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
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.NearbyMarker;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyMapContract;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract;
|
||||
import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter;
|
||||
import fr.free.nrw.commons.utils.LocationUtils;
|
||||
import fr.free.nrw.commons.utils.UiUtils;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween;
|
||||
|
||||
/**
|
||||
* Support Fragment wrapper around a map view.
|
||||
* <p>
|
||||
* A Map component in an app. This fragment is the simplest way to place a map in an application.
|
||||
* It's a wrapper around a view of a map to automatically handle the necessary life cycle needs.
|
||||
* Being a fragment, this component can be added to an activity's layout or can dynamically be added
|
||||
* using a FragmentManager.
|
||||
* </p>
|
||||
* <p>
|
||||
* To get a reference to the MapView, use {@link #getMapAsync(OnMapReadyCallback)}}
|
||||
* </p>
|
||||
*
|
||||
* @see #getMapAsync(OnMapReadyCallback)
|
||||
*/
|
||||
public class NearbyMapFragment extends CommonsDaggerSupportFragment
|
||||
implements OnMapReadyCallback, NearbyMapContract.View{
|
||||
|
||||
@Inject
|
||||
BookmarkLocationsDao bookmarkLocationDao;
|
||||
|
||||
private final List<OnMapReadyCallback> mapReadyCallbackList = new ArrayList<>();
|
||||
private MapFragment.OnMapViewReadyCallback mapViewReadyCallback;
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView map;
|
||||
private Marker currentLocationMarker;
|
||||
private Polygon currentLocationPolygon;
|
||||
private List<NearbyBaseMarker> customBaseMarkerOptions;
|
||||
|
||||
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.005;
|
||||
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.004;
|
||||
private static final double ZOOM_LEVEL = 14f;
|
||||
|
||||
/**
|
||||
* Creates a MapFragment instance
|
||||
*
|
||||
* @param mapboxMapOptions The configuration options to be used.
|
||||
* @return MapFragment created.
|
||||
*/
|
||||
@NonNull
|
||||
public static NearbyMapFragment newInstance(@Nullable MapboxMapOptions mapboxMapOptions) {
|
||||
NearbyMapFragment mapFragment = new NearbyMapFragment();
|
||||
mapFragment.setArguments(MapFragmentUtils.createFragmentArgs(mapboxMapOptions));
|
||||
return mapFragment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the context attaches to this fragment.
|
||||
*
|
||||
* @param context the context attaching
|
||||
*/
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
if (context instanceof MapFragment.OnMapViewReadyCallback) {
|
||||
mapViewReadyCallback = (MapFragment.OnMapViewReadyCallback) context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when this fragment is inflated, parses XML tag attributes.
|
||||
*
|
||||
* @param context The context inflating this fragment.
|
||||
* @param attrs The XML tag attributes.
|
||||
* @param savedInstanceState The saved instance state for the map fragment.
|
||||
*/
|
||||
@Override
|
||||
public void onInflate(@NonNull Context context, AttributeSet attrs, Bundle savedInstanceState) {
|
||||
super.onInflate(context, attrs, savedInstanceState);
|
||||
setArguments(MapFragmentUtils.createFragmentArgs(MapboxMapOptions.createFromAttributes(context, attrs)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the fragment view hierarchy.
|
||||
*
|
||||
* @param inflater Inflater used to inflate content.
|
||||
* @param container The parent layout for the map fragment.
|
||||
* @param savedInstanceState The saved instance state for the map fragment.
|
||||
* @return The view created
|
||||
*/
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
super.onCreateView(inflater, container, savedInstanceState);
|
||||
Context context = inflater.getContext();
|
||||
map = new MapView(context, MapFragmentUtils.resolveArgs(context, getArguments()));
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment view hierarchy is created.
|
||||
*
|
||||
* @param view The content view of the fragment
|
||||
* @param savedInstanceState THe saved instance state of the framgnt
|
||||
*/
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
map.onCreate(savedInstanceState);
|
||||
map.getMapAsync(this);
|
||||
|
||||
// notify listeners about MapView creation
|
||||
if (mapViewReadyCallback != null) {
|
||||
mapViewReadyCallback.onMapViewReady(map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
for (OnMapReadyCallback onMapReadyCallback : mapReadyCallbackList) {
|
||||
onMapReadyCallback.onMapReady(mapboxMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is visible for the users.
|
||||
*/
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
map.onStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is ready to be interacted with.
|
||||
*/
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
map.onResume();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is pausing.
|
||||
*/
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
map.onPause();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment state needs to be saved.
|
||||
*
|
||||
* @param outState The saved state
|
||||
*/
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (map != null) {
|
||||
map.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is no longer visible for the user.
|
||||
*/
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
map.onStop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment receives onLowMemory call from the hosting Activity.
|
||||
*/
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
if (map != null) {
|
||||
map.onLowMemory();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is view hierarchy is being destroyed.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
map.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the fragment is destroyed.
|
||||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapReadyCallbackList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a callback object which will be triggered when the MapboxMap instance is ready to be used.
|
||||
*
|
||||
* @param onMapReadyCallback The callback to be invoked.
|
||||
*/
|
||||
public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
|
||||
if (mapboxMap == null) {
|
||||
mapReadyCallbackList.add(onMapReadyCallback);
|
||||
} else {
|
||||
onMapReadyCallback.onMapReady(mapboxMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears map, adds nearby markers to map
|
||||
* @param latLng current location
|
||||
* @param placeList all places will be displayed on the map
|
||||
* @param selectedMarker clicked marker by user
|
||||
* @param nearbyParentFragmentPresenter presenter
|
||||
*/
|
||||
@Override
|
||||
public void updateMapMarkers(LatLng latLng, List<Place> placeList
|
||||
, Marker selectedMarker
|
||||
, NearbyParentFragmentPresenter nearbyParentFragmentPresenter) {
|
||||
Timber.d("Updates map markers");
|
||||
customBaseMarkerOptions = NearbyController
|
||||
.loadAttractionsFromLocationToBaseMarkerOptions(latLng, // Curlatlang will be used to calculate distances
|
||||
placeList,
|
||||
getActivity(),
|
||||
bookmarkLocationDao.getAllBookmarksLocations());
|
||||
mapboxMap.clear();
|
||||
addNearbyMarkersToMapBoxMap(customBaseMarkerOptions, selectedMarker, nearbyParentFragmentPresenter);
|
||||
// Re-enable mapbox gestures on custom location markers load
|
||||
mapboxMap.getUiSettings().setAllGesturesEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes map camera follow users location with animation
|
||||
* @param curLatLng current location of user
|
||||
*/
|
||||
@Override
|
||||
public void updateMapToTrackPosition(LatLng curLatLng) {
|
||||
Timber.d("Updates map camera to track user position");
|
||||
CameraPosition cameraPosition = new CameraPosition.Builder().target
|
||||
(LocationUtils.commonsLatLngToMapBoxLatLng(curLatLng)).build();
|
||||
mapboxMap.setCameraPosition(cameraPosition);
|
||||
mapboxMap.animateCamera(CameraUpdateFactory
|
||||
.newCameraPosition(cameraPosition), 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a marker for the user's current position. Adds a
|
||||
* circle which uses the accuracy * 2, to draw a circle
|
||||
* which represents the user's position with an accuracy
|
||||
* of 95%.
|
||||
*
|
||||
* Should be called only on creation of mapboxMap, there
|
||||
* is other method to update markers location with users
|
||||
* move.
|
||||
* @param curLatLng current location
|
||||
*/
|
||||
@Override
|
||||
public void addCurrentLocationMarker(LatLng curLatLng) {
|
||||
if (null != curLatLng) {
|
||||
removeCurrentLocationMarker();
|
||||
Timber.d("Adds current location marker");
|
||||
|
||||
Icon icon = IconFactory.getInstance(getContext())
|
||||
.fromResource(R.drawable.current_location_marker);
|
||||
|
||||
MarkerOptions currentLocationMarkerOptions = new MarkerOptions()
|
||||
.position(new com.mapbox.mapboxsdk.geometry.LatLng(curLatLng.getLatitude(),
|
||||
curLatLng.getLongitude()));
|
||||
currentLocationMarkerOptions.setIcon(icon); // Set custom icon
|
||||
currentLocationMarker = mapboxMap.addMarker(currentLocationMarkerOptions);
|
||||
|
||||
List<com.mapbox.mapboxsdk.geometry.LatLng> circle = UiUtils
|
||||
.createCircleArray(curLatLng.getLatitude(), curLatLng.getLongitude(),
|
||||
curLatLng.getAccuracy() * 2, 100);
|
||||
|
||||
PolygonOptions currentLocationPolygonOptions = new PolygonOptions()
|
||||
.addAll(circle)
|
||||
.strokeColor(getResources().getColor(R.color.current_marker_stroke))
|
||||
.fillColor(getResources().getColor(R.color.current_marker_fill));
|
||||
currentLocationPolygon = mapboxMap.addPolygon(currentLocationPolygonOptions);
|
||||
} else {
|
||||
Timber.d("not adding current location marker..current location is null");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeCurrentLocationMarker() {
|
||||
if (currentLocationMarker != null) {
|
||||
mapboxMap.removeMarker(currentLocationMarker);
|
||||
mapboxMap.removePolygon(currentLocationPolygon);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters markers based on selectedLabels and chips
|
||||
* @param selectedLabels label list that user clicked
|
||||
* @param displayExists chip for displaying only existing places
|
||||
* @param displayNeedsPhoto chip for displaying only places need photos
|
||||
* @param filterForPlaceState true if we filter places for place state
|
||||
* @param filterForAllNoneType true if we filter places with all none button
|
||||
*/
|
||||
@Override
|
||||
public void filterMarkersByLabels(List<Label> selectedLabels,
|
||||
boolean displayExists,
|
||||
boolean displayNeedsPhoto,
|
||||
boolean filterForPlaceState,
|
||||
boolean filterForAllNoneType) {
|
||||
|
||||
if (selectedLabels.size() == 0 && filterForPlaceState) { // If nothing is selected, display all
|
||||
greyOutAllMarkers();
|
||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||
if (displayExists && displayNeedsPhoto) {
|
||||
// Exists and needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty() && markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (displayExists && !displayNeedsPhoto) {
|
||||
// Exists and all included needs and doesn't needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && displayNeedsPhoto) {
|
||||
// All and only needs photo
|
||||
if (markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && !displayNeedsPhoto) {
|
||||
// all
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
|
||||
//updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else {
|
||||
// First greyed out all markers
|
||||
greyOutAllMarkers();
|
||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||
for (Label label : selectedLabels) {
|
||||
if (markerPlaceGroup.getPlace().getLabel().toString().equals(label.toString())) {
|
||||
|
||||
if (displayExists && displayNeedsPhoto) {
|
||||
// Exists and needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty() && markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (displayExists && !displayNeedsPhoto) {
|
||||
// Exists and all included needs and doesn't needs photo
|
||||
if (markerPlaceGroup.getPlace().destroyed.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && displayNeedsPhoto) {
|
||||
// All and only needs photo
|
||||
if (markerPlaceGroup.getPlace().pic.trim().isEmpty()) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
} else if (!displayExists && !displayNeedsPhoto) {
|
||||
// all
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Greys out all markers
|
||||
*/
|
||||
@Override
|
||||
public void filterOutAllMarkers() {
|
||||
greyOutAllMarkers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays all markers
|
||||
*/
|
||||
@Override
|
||||
public void displayAllMarkers() {
|
||||
for (MarkerPlaceGroup markerPlaceGroup : NearbyController.markerLabelList) {
|
||||
updateMarker(markerPlaceGroup.getIsBookmarked(), markerPlaceGroup.getPlace(), NearbyController.currentLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NearbyBaseMarker> getBaseMarkerOptions() {
|
||||
return customBaseMarkerOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds markers to map
|
||||
* @param baseMarkerList is markers will be added
|
||||
* @param selectedMarker is selected marker by user
|
||||
* @param nearbyParentFragmentPresenter presenter
|
||||
*/
|
||||
@Override
|
||||
public void addNearbyMarkersToMapBoxMap(@Nullable List<NearbyBaseMarker> baseMarkerList
|
||||
, Marker selectedMarker
|
||||
, NearbyParentFragmentPresenter nearbyParentFragmentPresenter) {
|
||||
List<Marker> markers = mapboxMap.addMarkers(baseMarkerList);
|
||||
NearbyController.markerExistsMap = new HashMap<Boolean, Marker>();
|
||||
NearbyController.markerNeedPicMap = new HashMap<Boolean, Marker>();
|
||||
|
||||
NearbyController.markerLabelList.clear();
|
||||
|
||||
for (int i = 0; i < baseMarkerList.size(); i++) {
|
||||
|
||||
NearbyBaseMarker nearbyBaseMarker = baseMarkerList.get(i);
|
||||
NearbyController.markerLabelList.add(
|
||||
new MarkerPlaceGroup(markers.get(i), bookmarkLocationDao.findBookmarkLocation(baseMarkerList.get(i).getPlace()), nearbyBaseMarker.getPlace()));
|
||||
//TODO: fix bookmark location
|
||||
NearbyController.markerExistsMap.put((baseMarkerList.get(i).getPlace().hasWikidataLink()), markers.get(i));
|
||||
NearbyController.markerNeedPicMap.put(((baseMarkerList.get(i).getPlace().pic == null) ? true : false), markers.get(i));
|
||||
}
|
||||
|
||||
map.getMapAsync(mapboxMap -> {
|
||||
mapboxMap.addMarkers(baseMarkerList);
|
||||
setMapMarkerActions(selectedMarker, nearbyParentFragmentPresenter);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LatLng getCameraTarget() {
|
||||
return LocationUtils
|
||||
.mapBoxLatLngToCommonsLatLng(mapboxMap.getCameraPosition().target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MapboxMap getMapboxMap() {
|
||||
return mapboxMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void viewsAreAssignedToPresenter(NearbyParentFragmentContract.ViewsAreReadyCallback viewsAreReadyCallback) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOnCameraMoveListener(MapboxMap.OnCameraMoveListener onCameraMoveListener) {
|
||||
|
||||
}
|
||||
|
||||
void setMapMarkerActions(Marker selected, NearbyParentFragmentPresenter nearbyParentFragmentPresenter) {
|
||||
getMapboxMap().setOnInfoWindowCloseListener(marker -> {
|
||||
if (marker == selected) {
|
||||
nearbyParentFragmentPresenter.markerUnselected();
|
||||
}
|
||||
});
|
||||
|
||||
getMapboxMap().setOnMarkerClickListener(marker -> {
|
||||
|
||||
if (marker instanceof NearbyMarker) {
|
||||
nearbyParentFragmentPresenter.markerSelected(marker);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets marker icon according to marker status. Sets title and distance.
|
||||
* @param isBookmarked true if place is bookmarked
|
||||
* @param place
|
||||
* @param curLatLng current location
|
||||
*/
|
||||
public void updateMarker(boolean isBookmarked, Place place, @Nullable LatLng curLatLng) {
|
||||
|
||||
VectorDrawableCompat vectorDrawable;
|
||||
if (isBookmarked) {
|
||||
vectorDrawable = VectorDrawableCompat.create(
|
||||
getContext().getResources(), R.drawable.ic_custom_bookmark_marker, getContext().getTheme()
|
||||
);
|
||||
} else if (!place.pic.trim().isEmpty()) {
|
||||
vectorDrawable = VectorDrawableCompat.create( // Means place has picture
|
||||
getContext().getResources(), R.drawable.ic_custom_map_marker_green, getContext().getTheme()
|
||||
);
|
||||
} else if (!place.destroyed.trim().isEmpty()) { // Means place is destroyed
|
||||
vectorDrawable = VectorDrawableCompat.create( // Means place has picture
|
||||
getContext().getResources(), R.drawable.ic_custom_map_marker_grey, getContext().getTheme()
|
||||
);
|
||||
} else {
|
||||
vectorDrawable = VectorDrawableCompat.create(
|
||||
getContext().getResources(), R.drawable.ic_custom_map_marker, getContext().getTheme()
|
||||
);
|
||||
}
|
||||
for (Marker marker : mapboxMap.getMarkers()) {
|
||||
if (marker.getTitle() != null && marker.getTitle().equals(place.getName())) {
|
||||
|
||||
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
|
||||
if (curLatLng != null) {
|
||||
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()));
|
||||
nearbyBaseMarker.place(place);
|
||||
nearbyBaseMarker.icon(IconFactory.getInstance(getContext())
|
||||
.fromBitmap(icon));
|
||||
marker.setIcon(IconFactory.getInstance(getContext()).fromBitmap(icon));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Greys out all markers except current location marker
|
||||
*/
|
||||
public void greyOutAllMarkers() {
|
||||
VectorDrawableCompat vectorDrawable;
|
||||
vectorDrawable = VectorDrawableCompat.create(
|
||||
getContext().getResources(), R.drawable.ic_custom_greyed_out_marker, getContext().getTheme());
|
||||
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
|
||||
for (Marker marker : mapboxMap.getMarkers()) {
|
||||
if (currentLocationMarker.getTitle() != marker.getTitle()) {
|
||||
marker.setIcon(IconFactory.getInstance(getContext()).fromBitmap(icon));
|
||||
}
|
||||
}
|
||||
addCurrentLocationMarker(NearbyController.currentLocation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Centers the map in nearby fragment to a given place
|
||||
* @param place is new center of the map
|
||||
*/
|
||||
@Override
|
||||
public void centerMapToPlace(Place place, boolean isPortraitMode) {
|
||||
Timber.d("Map is centered to place");
|
||||
double cameraShift;
|
||||
if (isPortraitMode) {
|
||||
cameraShift = CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT;
|
||||
} else {
|
||||
cameraShift = CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE;
|
||||
}
|
||||
CameraPosition position = new CameraPosition.Builder()
|
||||
.target(LocationUtils.commonsLatLngToMapBoxLatLng(
|
||||
new LatLng(place.location.getLatitude()-cameraShift,
|
||||
place.getLocation().getLongitude(),
|
||||
0))) // Sets the new camera position
|
||||
.zoom(ZOOM_LEVEL) // Same zoom level
|
||||
.build();
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -3,21 +3,27 @@ package fr.free.nrw.commons.nearby.presenter;
|
|||
import android.view.View;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
|
||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.location.LocationUpdateListener;
|
||||
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.NearbyFilterState;
|
||||
import fr.free.nrw.commons.nearby.Place;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyMapContract;
|
||||
import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract;
|
||||
import fr.free.nrw.commons.upload.UploadContract;
|
||||
import fr.free.nrw.commons.utils.LocationUtils;
|
||||
import fr.free.nrw.commons.wikidata.WikidataEditListener;
|
||||
import timber.log.Timber;
|
||||
|
|
@ -32,118 +38,58 @@ import static fr.free.nrw.commons.nearby.CheckBoxTriStates.UNKNOWN;
|
|||
|
||||
public class NearbyParentFragmentPresenter
|
||||
implements NearbyParentFragmentContract.UserActions,
|
||||
WikidataEditListener.WikidataP18EditListener,
|
||||
LocationUpdateListener,
|
||||
NearbyParentFragmentContract.ViewsAreReadyCallback{
|
||||
WikidataEditListener.WikidataP18EditListener,
|
||||
LocationUpdateListener {
|
||||
|
||||
|
||||
private NearbyParentFragmentContract.View nearbyParentFragmentView;
|
||||
private NearbyMapContract.View nearbyMapFragmentView;
|
||||
private NearbyParentFragmentContract.NearbyListView nearbyListFragmentView;
|
||||
private boolean isNearbyLocked;
|
||||
private LatLng curLatLng;
|
||||
|
||||
private boolean nearbyViewsAreReady;
|
||||
private boolean onTabSelected;
|
||||
private boolean mapInitialized;
|
||||
|
||||
private Place placeToCenter;
|
||||
private boolean isPortraitMode;
|
||||
private boolean placesLoadedOnce;
|
||||
|
||||
private LocationServiceManager locationServiceManager;
|
||||
BookmarkLocationsDao bookmarkLocationDao;
|
||||
|
||||
public static NearbyParentFragmentPresenter presenterInstance;
|
||||
private static final NearbyParentFragmentContract.View DUMMY = (NearbyParentFragmentContract.View) Proxy.newProxyInstance(
|
||||
NearbyParentFragmentContract.View.class.getClassLoader(),
|
||||
new Class[]{NearbyParentFragmentContract.View.class}, (proxy, method, args) -> {
|
||||
if (method.getName().equals("onMyEvent")) {
|
||||
return null;
|
||||
} else if (String.class == method.getReturnType()) {
|
||||
return "";
|
||||
} else if (Integer.class == method.getReturnType()) {
|
||||
return Integer.valueOf(0);
|
||||
} else if (int.class == method.getReturnType()) {
|
||||
return 0;
|
||||
} else if (Boolean.class == method.getReturnType()) {
|
||||
return Boolean.FALSE;
|
||||
} else if (boolean.class == method.getReturnType()) {
|
||||
return false;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
private NearbyParentFragmentContract.View nearbyParentFragmentView = DUMMY;
|
||||
|
||||
private NearbyParentFragmentPresenter(NearbyParentFragmentContract.NearbyListView nearbyListFragmentView,
|
||||
NearbyParentFragmentContract.View nearbyParentFragmentView,
|
||||
NearbyMapContract.View nearbyMapFragmentView,
|
||||
LocationServiceManager locationServiceManager) {
|
||||
this.nearbyListFragmentView = nearbyListFragmentView;
|
||||
this.nearbyParentFragmentView = nearbyParentFragmentView;
|
||||
this.nearbyMapFragmentView = nearbyMapFragmentView;
|
||||
this.nearbyMapFragmentView.viewsAreAssignedToPresenter(this);
|
||||
this.locationServiceManager = locationServiceManager;
|
||||
|
||||
public NearbyParentFragmentPresenter(BookmarkLocationsDao bookmarkLocationDao){
|
||||
this.bookmarkLocationDao=bookmarkLocationDao;
|
||||
}
|
||||
|
||||
// static method to create instance of Singleton class
|
||||
public static NearbyParentFragmentPresenter getInstance(NearbyParentFragmentContract.NearbyListView nearbyListFragmentView,
|
||||
NearbyParentFragmentContract.View nearbyParentFragmentView,
|
||||
NearbyMapContract.View nearbyMapFragmentView,
|
||||
LocationServiceManager locationServiceManager) {
|
||||
if (presenterInstance == null) {
|
||||
presenterInstance = new NearbyParentFragmentPresenter(nearbyListFragmentView,
|
||||
nearbyParentFragmentView,
|
||||
nearbyMapFragmentView,
|
||||
locationServiceManager);
|
||||
}
|
||||
return presenterInstance;
|
||||
}
|
||||
|
||||
// We call this method when we are sure presenterInstance is not null
|
||||
public static NearbyParentFragmentPresenter getInstance() {
|
||||
return presenterInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: To initialize nearby operations both views should be ready and tab is selected.
|
||||
* Initializes nearby operations if nearby views are ready
|
||||
*/
|
||||
@Override
|
||||
public void onTabSelected() {
|
||||
Timber.d("Nearby tab selected");
|
||||
onTabSelected = true;
|
||||
// The condition for initialize operations is both having views ready and tab is selected
|
||||
if (nearbyViewsAreReady && !mapInitialized) {
|
||||
checkForPermission();
|
||||
}
|
||||
public void attachView(NearbyParentFragmentContract.View view){
|
||||
this.nearbyParentFragmentView=view;
|
||||
}
|
||||
|
||||
/**
|
||||
* -To initialize nearby operations both views should be ready and tab is selected.
|
||||
* Initializes nearby operations if tab selected, otherwise just sets nearby views are ready
|
||||
*/
|
||||
@Override
|
||||
public void nearbyFragmentsAreReady() {
|
||||
Timber.d("Nearby fragments are ready to be used by presenter");
|
||||
nearbyViewsAreReady = true;
|
||||
// The condition for initialize operations is both having views ready and tab is selected
|
||||
if (onTabSelected) {
|
||||
checkForPermission();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes nearby operations by following these steps:
|
||||
* -Checks for permission and perform if given
|
||||
*/
|
||||
@Override
|
||||
public void checkForPermission() {
|
||||
Timber.d("checking for permission");
|
||||
nearbyParentFragmentView.checkPermissionsAndPerformAction(this::performNearbyOperationsIfPermissionGiven);
|
||||
}
|
||||
|
||||
/**
|
||||
* - Adds search this area button action
|
||||
* - Adds camera move action listener
|
||||
* - Initializes nearby operations, registers listeners, broadcast receivers etc.
|
||||
*/
|
||||
public void performNearbyOperationsIfPermissionGiven() {
|
||||
Timber.d("Permission is given, performing actions");
|
||||
this.nearbyParentFragmentView.addSearchThisAreaButtonAction();
|
||||
this.nearbyParentFragmentView.addOnCameraMoveListener(onCameraMove(getMapboxMap()));
|
||||
initializeMapOperations();
|
||||
public void detachView(){
|
||||
this.nearbyParentFragmentView=DUMMY;
|
||||
}
|
||||
|
||||
public void initializeMapOperations() {
|
||||
lockUnlockNearby(false);
|
||||
registerUnregisterLocationListener(false);
|
||||
nearbyParentFragmentView.addNetworkBroadcastReceiver();
|
||||
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED, null);
|
||||
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED);
|
||||
this.nearbyParentFragmentView.addSearchThisAreaButtonAction();
|
||||
this.nearbyMapFragmentView.addOnCameraMoveListener(onCameraMove(getMapboxMap()));
|
||||
nearbyParentFragmentView.setCheckBoxAction();
|
||||
mapInitialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -204,34 +150,13 @@ public class NearbyParentFragmentPresenter
|
|||
}
|
||||
}
|
||||
|
||||
public void registerUnregisterLocationListener(boolean removeLocationListener) {
|
||||
if (removeLocationListener) {
|
||||
locationServiceManager.unregisterLocationManager();
|
||||
locationServiceManager.removeLocationListener(this);
|
||||
Timber.d("Location service manager unregistered and removed");
|
||||
} else {
|
||||
locationServiceManager.addLocationListener(this);
|
||||
nearbyParentFragmentView.registerLocationUpdates(locationServiceManager);
|
||||
Timber.d("Location service manager added and registered");
|
||||
}
|
||||
}
|
||||
|
||||
public LatLng getCameraTarget() {
|
||||
return nearbyMapFragmentView.getCameraTarget();
|
||||
}
|
||||
public MapboxMap getMapboxMap() {
|
||||
return nearbyMapFragmentView.getMapboxMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be the single point to update Map and List. Triggered by location
|
||||
* changes
|
||||
* @param locationChangeType defines if location changed significantly or slightly
|
||||
* @param cameraTarget will be used for search this area mode, when searching around
|
||||
* user's camera target
|
||||
*/
|
||||
@Override
|
||||
public void updateMapAndList(LocationServiceManager.LocationChangeType locationChangeType, LatLng cameraTarget) {
|
||||
public void updateMapAndList(LocationServiceManager.LocationChangeType locationChangeType) {
|
||||
Timber.d("Presenter updates map and list");
|
||||
if (isNearbyLocked) {
|
||||
Timber.d("Nearby is locked, so updateMapAndList returns");
|
||||
|
|
@ -243,7 +168,7 @@ public class NearbyParentFragmentPresenter
|
|||
return;
|
||||
}
|
||||
|
||||
LatLng lastLocation = locationServiceManager.getLastLocation();
|
||||
LatLng lastLocation = nearbyParentFragmentView.getLastLocation();
|
||||
curLatLng = lastLocation;
|
||||
|
||||
if (curLatLng == null) {
|
||||
|
|
@ -260,14 +185,13 @@ public class NearbyParentFragmentPresenter
|
|||
Timber.d("LOCATION_SIGNIFICANTLY_CHANGED");
|
||||
lockUnlockNearby(true);
|
||||
nearbyParentFragmentView.setProgressBarVisibility(true);
|
||||
nearbyParentFragmentView.populatePlaces(lastLocation, lastLocation);
|
||||
nearbyParentFragmentView.populatePlaces(lastLocation);
|
||||
|
||||
} else if (locationChangeType.equals(SEARCH_CUSTOM_AREA)) {
|
||||
Timber.d("SEARCH_CUSTOM_AREA");
|
||||
lockUnlockNearby(true);
|
||||
nearbyParentFragmentView.setProgressBarVisibility(true);
|
||||
nearbyParentFragmentView.populatePlaces(lastLocation, cameraTarget);
|
||||
|
||||
nearbyParentFragmentView.populatePlaces(nearbyParentFragmentView.getCameraTarget());
|
||||
} else { // Means location changed slightly, ie user is walking or driving.
|
||||
Timber.d("Means location changed slightly");
|
||||
if (!nearbyParentFragmentView.isSearchThisAreaButtonVisible()) { // Do not track users position if the user is checking around
|
||||
|
|
@ -281,28 +205,23 @@ public class NearbyParentFragmentPresenter
|
|||
* location where you are not at.
|
||||
* @param nearbyPlacesInfo This variable has placeToCenter list information and distances.
|
||||
*/
|
||||
public void updateMapMarkers(NearbyController.NearbyPlacesInfo nearbyPlacesInfo, Marker selectedMarker) {
|
||||
nearbyMapFragmentView.updateMapMarkers(nearbyPlacesInfo.curLatLng, nearbyPlacesInfo.placeList, selectedMarker, this);
|
||||
nearbyMapFragmentView.addCurrentLocationMarker(nearbyPlacesInfo.curLatLng);
|
||||
nearbyMapFragmentView.updateMapToTrackPosition(nearbyPlacesInfo.curLatLng);
|
||||
lockUnlockNearby(false); // So that new location updates wont come
|
||||
nearbyParentFragmentView.setProgressBarVisibility(false);
|
||||
nearbyListFragmentView.updateListFragment(nearbyPlacesInfo.placeList);
|
||||
handleCenteringTaskIfAny();
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates places for custom location, should be used for finding nearby places around a
|
||||
* location where you are not at.
|
||||
* @param nearbyPlacesInfo This variable has placeToCenter list information and distances.
|
||||
*/
|
||||
public void updateMapMarkersForCustomLocation(NearbyController.NearbyPlacesInfo nearbyPlacesInfo, Marker selectedMarker) {
|
||||
nearbyMapFragmentView.updateMapMarkers(nearbyPlacesInfo.curLatLng, nearbyPlacesInfo.placeList, selectedMarker, this);
|
||||
nearbyMapFragmentView.addCurrentLocationMarker(nearbyPlacesInfo.curLatLng);
|
||||
lockUnlockNearby(false); // So that new location updates wont come
|
||||
nearbyParentFragmentView.setProgressBarVisibility(false);
|
||||
nearbyListFragmentView.updateListFragment(nearbyPlacesInfo.placeList);
|
||||
handleCenteringTaskIfAny();
|
||||
public void updateMapMarkers(NearbyController.NearbyPlacesInfo nearbyPlacesInfo, Marker selectedMarker, boolean shouldTrackPosition) {
|
||||
if(null!=nearbyParentFragmentView) {
|
||||
List<NearbyBaseMarker> nearbyBaseMarkers = NearbyController
|
||||
.loadAttractionsFromLocationToBaseMarkerOptions(nearbyPlacesInfo.curLatLng, // Curlatlang will be used to calculate distances
|
||||
nearbyPlacesInfo.placeList,
|
||||
nearbyParentFragmentView.getContext(),
|
||||
bookmarkLocationDao.getAllBookmarksLocations());
|
||||
nearbyParentFragmentView.updateMapMarkers(nearbyBaseMarkers, selectedMarker);
|
||||
nearbyParentFragmentView.addCurrentLocationMarker(nearbyPlacesInfo.curLatLng);
|
||||
if(shouldTrackPosition){
|
||||
nearbyParentFragmentView.updateMapToTrackPosition(nearbyPlacesInfo.curLatLng);
|
||||
}
|
||||
lockUnlockNearby(false); // So that new location updates wont come
|
||||
nearbyParentFragmentView.setProgressBarVisibility(false);
|
||||
nearbyParentFragmentView.updateListFragment(nearbyPlacesInfo.placeList);
|
||||
handleCenteringTaskIfAny();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -312,25 +231,25 @@ public class NearbyParentFragmentPresenter
|
|||
private void handleCenteringTaskIfAny() {
|
||||
if (!placesLoadedOnce) {
|
||||
placesLoadedOnce = true;
|
||||
nearbyMapFragmentView.centerMapToPlace(placeToCenter, isPortraitMode);
|
||||
nearbyParentFragmentView.centerMapToPlace(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWikidataEditSuccessful() {
|
||||
updateMapAndList(MAP_UPDATED, null);
|
||||
updateMapAndList(MAP_UPDATED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChangedSignificantly(LatLng latLng) {
|
||||
Timber.d("Location significantly changed");
|
||||
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED, null);
|
||||
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChangedSlightly(LatLng latLng) {
|
||||
Timber.d("Location significantly changed");
|
||||
updateMapAndList(LOCATION_SLIGHTLY_CHANGED, null);
|
||||
updateMapAndList(LOCATION_SLIGHTLY_CHANGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -339,11 +258,10 @@ public class NearbyParentFragmentPresenter
|
|||
}
|
||||
|
||||
@Override
|
||||
public MapboxMap.OnCameraMoveListener onCameraMove(MapboxMap mapboxMap) {
|
||||
return () -> {
|
||||
public void onCameraMove(com.mapbox.mapboxsdk.geometry.LatLng latLng) {
|
||||
// If our nearby markers are calculated at least once
|
||||
if (NearbyController.currentLocation != null) {
|
||||
double distance = mapboxMap.getCameraPosition().target.distanceTo
|
||||
if (NearbyController.latestSearchLocation != null) {
|
||||
double distance =latLng.distanceTo
|
||||
(LocationUtils.commonsLatLngToMapBoxLatLng(NearbyController.latestSearchLocation));
|
||||
if (nearbyParentFragmentView.isNetworkConnectionEstablished()) {
|
||||
if (distance > NearbyController.latestSearchRadius) {
|
||||
|
|
@ -355,7 +273,6 @@ public class NearbyParentFragmentPresenter
|
|||
} else {
|
||||
nearbyParentFragmentView.setSearchThisAreaButtonVisibility(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -366,19 +283,34 @@ public class NearbyParentFragmentPresenter
|
|||
// Do nothing
|
||||
break;
|
||||
case UNCHECKED:
|
||||
nearbyMapFragmentView.filterOutAllMarkers();
|
||||
nearbyParentFragmentView.filterOutAllMarkers();
|
||||
nearbyParentFragmentView.setRecyclerViewAdapterItemsGreyedOut();
|
||||
break;
|
||||
case CHECKED:
|
||||
nearbyMapFragmentView.displayAllMarkers();
|
||||
nearbyParentFragmentView.displayAllMarkers();
|
||||
nearbyParentFragmentView.setRecyclerViewAdapterAllSelected();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
nearbyMapFragmentView.filterMarkersByLabels(selectedLabels,
|
||||
nearbyParentFragmentView.filterMarkersByLabels(selectedLabels,
|
||||
NearbyFilterState.getInstance().isExistsSelected(),
|
||||
NearbyFilterState.getInstance().isNeedPhotoSelected(),
|
||||
filterForPlaceState, filterForAllNoneType);
|
||||
filterForPlaceState, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMapMarkersToController(List<NearbyBaseMarker> nearbyBaseMarkers) {
|
||||
NearbyController.markerExistsMap = new HashMap<>();
|
||||
NearbyController.markerNeedPicMap = new HashMap<>();
|
||||
NearbyController.markerLabelList.clear();
|
||||
for (int i = 0; i < nearbyBaseMarkers.size(); i++) {
|
||||
NearbyBaseMarker nearbyBaseMarker = nearbyBaseMarkers.get(i);
|
||||
NearbyController.markerLabelList.add(
|
||||
new MarkerPlaceGroup(nearbyBaseMarkers.get(i).getMarker(), bookmarkLocationDao.findBookmarkLocation(nearbyBaseMarkers.get(i).getPlace()), nearbyBaseMarker.getPlace()));
|
||||
//TODO: fix bookmark location
|
||||
NearbyController.markerExistsMap.put((nearbyBaseMarkers.get(i).getPlace().hasWikidataLink()), nearbyBaseMarkers.get(i).getMarker());
|
||||
NearbyController.markerNeedPicMap.put(((nearbyBaseMarkers.get(i).getPlace().pic == null) ? true : false), nearbyBaseMarkers.get(i).getMarker());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -403,11 +335,9 @@ public class NearbyParentFragmentPresenter
|
|||
nearbyParentFragmentView.setSearchThisAreaButtonVisibility(false);
|
||||
|
||||
if (searchCloseToCurrentLocation()){
|
||||
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED,
|
||||
null);
|
||||
updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED);
|
||||
} else {
|
||||
updateMapAndList(SEARCH_CUSTOM_AREA,
|
||||
getCameraTarget());
|
||||
updateMapAndList(SEARCH_CUSTOM_AREA);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -418,9 +348,11 @@ public class NearbyParentFragmentPresenter
|
|||
* @return Returns true if search this area button is used around our current location
|
||||
*/
|
||||
public boolean searchCloseToCurrentLocation() {
|
||||
double distance = LocationUtils.commonsLatLngToMapBoxLatLng(getCameraTarget())
|
||||
.distanceTo(new com.mapbox.mapboxsdk.geometry.LatLng(NearbyController.currentLocation.getLatitude()
|
||||
, NearbyController.currentLocation.getLongitude()));
|
||||
if (null == nearbyParentFragmentView.getLastFocusLocation()) {
|
||||
return true;
|
||||
}
|
||||
double distance = LocationUtils.commonsLatLngToMapBoxLatLng(nearbyParentFragmentView.getCameraTarget())
|
||||
.distanceTo(nearbyParentFragmentView.getLastFocusLocation());
|
||||
if (distance > NearbyController.currentLocationSearchRadius * 3 / 4) {
|
||||
return false;
|
||||
} else {
|
||||
|
|
@ -428,16 +360,20 @@ public class NearbyParentFragmentPresenter
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Centers the map in nearby fragment to a given placeToCenter
|
||||
* @param place is new center of the map
|
||||
*/
|
||||
public void centerMapToPlace(Place place, boolean isPortraitMode) {
|
||||
if (placesLoadedOnce) {
|
||||
nearbyMapFragmentView.centerMapToPlace(place, isPortraitMode);
|
||||
public void onMapReady() {
|
||||
if(null!=nearbyParentFragmentView) {
|
||||
nearbyParentFragmentView.addSearchThisAreaButtonAction();
|
||||
initializeMapOperations();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean areLocationsClose(LatLng cameraTarget, LatLng lastKnownLocation) {
|
||||
double distance = LocationUtils.commonsLatLngToMapBoxLatLng(cameraTarget)
|
||||
.distanceTo(LocationUtils.commonsLatLngToMapBoxLatLng(lastKnownLocation));
|
||||
if (distance > NearbyController.currentLocationSearchRadius * 3 / 4) {
|
||||
return false;
|
||||
} else {
|
||||
this.isPortraitMode = isPortraitMode;
|
||||
this.placeToCenter = place;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import android.os.Handler;
|
|||
import android.os.Looper;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class ExecutorUtils {
|
||||
|
||||
|
|
@ -19,4 +21,11 @@ public class ExecutorUtils {
|
|||
return uiExecutor;
|
||||
}
|
||||
|
||||
|
||||
private static final ExecutorService executor = Executors.newFixedThreadPool(3);
|
||||
|
||||
public static ExecutorService get() {
|
||||
return executor;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
10
app/src/main/res/layout-v21/drawer_view.xml
Normal file
10
app/src/main/res/layout-v21/drawer_view.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.navigation.NavigationView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/navigation_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:elevation="2dp"
|
||||
app:headerLayout="@layout/drawer_header"
|
||||
app:menu="@menu/drawer" />
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
app:layout_behavior="@string/bottom_sheet_behavior"
|
||||
app:behavior_peekHeight="72dp"
|
||||
app:behavior_hideable="true"
|
||||
android:visibility="gone"
|
||||
android:visibility="visible"
|
||||
|
||||
>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,51 +1,16 @@
|
|||
<?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="480dp"
|
||||
android:id="@+id/bottom_sheet"
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/bottom_sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:background="?attr/mainBackground"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior"
|
||||
app:behavior_peekHeight="0dp"
|
||||
app:behavior_hideable="true"
|
||||
>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/loading_nearby_list"
|
||||
android:visibility="visible"
|
||||
app:layout_behavior="@string/bottom_sheet_behavior"
|
||||
android:background="@android:color/white">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_nearby_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="visible">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
/>
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:layout_marginTop="10dp"
|
||||
android:textSize="20sp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/progress_bar"
|
||||
android:text="Loading..."
|
||||
/>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/container_sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:focusableInTouchMode="true"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
</LinearLayout>
|
||||
android:layout_height="match_parent" />
|
||||
</RelativeLayout>
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:elevation="2dp"
|
||||
app:headerLayout="@layout/drawer_header"
|
||||
app:menu="@menu/drawer" />
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone"
|
||||
>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
|
|
|
|||
|
|
@ -10,11 +10,6 @@
|
|||
android:layout_height="match_parent"
|
||||
android:background="@color/status_bar_blue"
|
||||
android:id="@+id/map_layout">
|
||||
|
||||
<View
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:focusableInTouchMode="true"/>
|
||||
|
||||
<include
|
||||
layout="@layout/nearby_filter_all_items"
|
||||
|
|
@ -27,11 +22,25 @@
|
|||
android:layout_width="160dp"
|
||||
android:layout_alignParentEnd="true"/>
|
||||
|
||||
|
||||
<!-- I have done this intentionally, the mapview because of some elevation or something,
|
||||
sometimes hangs over the drawer layout and sometimes draws its onPaused state over the contributions, this seems to be the probable fix -->
|
||||
<FrameLayout
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/nearby_filter"/>
|
||||
android:layout_below="@id/nearby_filter">
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
android:id="@+id/map_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/transparent" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
<Button
|
||||
|
|
@ -54,7 +63,6 @@
|
|||
android:id="@+id/transparentView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:background="#aa969696"
|
||||
android:visibility="gone"
|
||||
|
|
|
|||
|
|
@ -1,21 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/search_list_item"
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="25dp"
|
||||
>
|
||||
android:orientation="horizontal"
|
||||
android:padding="4dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/place_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
</ImageView>
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/place_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
</TextView>
|
||||
android:layout_height="wrap_content"></TextView>
|
||||
</LinearLayout>
|
||||
19
app/src/main/res/layout/nearby_search_list_item_dark.xml
Normal file
19
app/src/main/res/layout/nearby_search_list_item_dark.xml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/search_list_item"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/place_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/place_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/white"></TextView>
|
||||
</LinearLayout>
|
||||
|
|
@ -277,7 +277,7 @@
|
|||
<string name="wikicode_copied">The wikitext was copied to the clipboard</string>
|
||||
|
||||
<string name="nearby_location_has_not_changed">Location has not changed.</string>
|
||||
<string name="nearby_location_not_available">Location not available.</string>
|
||||
<string name="nearby_location_not_available">Nearby might not work properly, Location not available.</string>
|
||||
<string name="location_permission_rationale_nearby">Permission required to display a list of nearby places</string>
|
||||
<string name="get_directions">Get directions</string>
|
||||
<string name="read_article">Read article</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue