From cd1aaa82e014f6d1e7cf781c887fb64378a07f16 Mon Sep 17 00:00:00 2001 From: Paul Hawke Date: Thu, 31 Jul 2025 08:49:07 -0500 Subject: [PATCH] Convert the map presenter to kotlin --- .../commons/explore/map/ExploreMapContract.kt | 2 +- .../explore/map/ExploreMapPresenter.java | 236 ------------------ .../explore/map/ExploreMapPresenter.kt | 223 +++++++++++++++++ 3 files changed, 224 insertions(+), 237 deletions(-) delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.java create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.kt diff --git a/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapContract.kt b/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapContract.kt index 76500b1bc..306446a43 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapContract.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapContract.kt @@ -33,7 +33,7 @@ class ExploreMapContract { } interface UserActions { - fun updateMap(locationChangeType: LocationChangeType?) + fun updateMap(locationChangeType: LocationChangeType) fun lockUnlockNearby(isNearbyLocked: Boolean) fun attachView(view: View?) fun detachView() diff --git a/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.java b/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.java deleted file mode 100644 index cb6b8ce47..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.java +++ /dev/null @@ -1,236 +0,0 @@ -package fr.free.nrw.commons.explore.map; - -import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED; -import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.SEARCH_CUSTOM_AREA; - - -import android.location.Location; -import android.view.View; -import fr.free.nrw.commons.BaseMarker; -import fr.free.nrw.commons.MapController; -import fr.free.nrw.commons.MapController.ExplorePlacesInfo; -import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao; -import fr.free.nrw.commons.explore.map.ExploreMapController.NearbyBaseMarkerThumbCallback; -import fr.free.nrw.commons.kvstore.JsonKvStore; -import fr.free.nrw.commons.location.LatLng; -import fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType; -import fr.free.nrw.commons.nearby.Place; -import io.reactivex.Observable; -import java.lang.reflect.Proxy; -import java.util.List; -import timber.log.Timber; - -public class ExploreMapPresenter - implements ExploreMapContract.UserActions, - NearbyBaseMarkerThumbCallback { - - BookmarkLocationsDao bookmarkLocationDao; - private boolean isNearbyLocked; - private LatLng currentLatLng; - private ExploreMapController exploreMapController; - - private static final ExploreMapContract.View DUMMY = (ExploreMapContract.View) Proxy - .newProxyInstance( - ExploreMapContract.View.class.getClassLoader(), - new Class[]{ExploreMapContract.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 ExploreMapContract.View exploreMapFragmentView = DUMMY; - - public ExploreMapPresenter(BookmarkLocationsDao bookmarkLocationDao) { - this.bookmarkLocationDao = bookmarkLocationDao; - } - - @Override - public void updateMap(LocationChangeType locationChangeType) { - Timber.d("Presenter updates map and list" + locationChangeType.toString()); - if (isNearbyLocked) { - Timber.d("Nearby is locked, so updateMapAndList returns"); - return; - } - - if (!exploreMapFragmentView.isNetworkConnectionEstablished()) { - Timber.d("Network connection is not established"); - return; - } - - /** - * Significant changed - Markers and current location will be updated together - * Slightly changed - Only current position marker will be updated - */ - if (locationChangeType.equals(LOCATION_SIGNIFICANTLY_CHANGED)) { - Timber.d("LOCATION_SIGNIFICANTLY_CHANGED"); - LatLng populateLatLng = exploreMapFragmentView.getMapCenter(); - - //If "Show in Explore" was selected in Nearby, use the previous LatLng - if (exploreMapFragmentView instanceof ExploreMapFragment) { - ExploreMapFragment exploreMapFragment = (ExploreMapFragment)exploreMapFragmentView; - if (exploreMapFragment.recentlyCameFromNearbyMap()) { - //Ensure this LatLng will not be used again if user searches their GPS location - exploreMapFragment.setRecentlyCameFromNearbyMap(false); - - populateLatLng = exploreMapFragment.getPreviousLatLng(); - } - } - - lockUnlockNearby(true); - exploreMapFragmentView.setProgressBarVisibility(true); - exploreMapFragmentView.populatePlaces(populateLatLng); - } else if (locationChangeType.equals(SEARCH_CUSTOM_AREA)) { - Timber.d("SEARCH_CUSTOM_AREA"); - lockUnlockNearby(true); - exploreMapFragmentView.setProgressBarVisibility(true); - exploreMapFragmentView.populatePlaces(exploreMapFragmentView.getMapFocus()); - } else { // Means location changed slightly, ie user is walking or driving. - Timber.d("Means location changed slightly"); - } - } - - /** - * Nearby updates takes time, since they are network operations. During update time, we don't - * want to get any other calls from user. So locking nearby. - * - * @param isNearbyLocked true means lock, false means unlock - */ - @Override - public void lockUnlockNearby(boolean isNearbyLocked) { - this.isNearbyLocked = isNearbyLocked; - if (isNearbyLocked) { - exploreMapFragmentView.disableFABRecenter(); - } else { - exploreMapFragmentView.enableFABRecenter(); - } - } - - @Override - public void attachView(ExploreMapContract.View view) { - exploreMapFragmentView = view; - } - - @Override - public void detachView() { - exploreMapFragmentView = DUMMY; - } - - /** - * Sets click listener of FAB - */ - @Override - public void setActionListeners(JsonKvStore applicationKvStore) { - exploreMapFragmentView.setFABRecenterAction(v -> { - exploreMapFragmentView.recenterMap(currentLatLng); - }); - - } - - @Override - public boolean backButtonClicked() { - return exploreMapFragmentView.backButtonClicked(); - } - - public void onMapReady(ExploreMapController exploreMapController) { - this.exploreMapController = exploreMapController; - if (null != exploreMapFragmentView) { - exploreMapFragmentView.addSearchThisAreaButtonAction(); - initializeMapOperations(); - } - } - - public void initializeMapOperations() { - lockUnlockNearby(false); - updateMap(LOCATION_SIGNIFICANTLY_CHANGED); - } - - public Observable loadAttractionsFromLocation(LatLng currentLatLng, - LatLng searchLatLng, boolean checkingAroundCurrent) { - return Observable - .fromCallable(() -> exploreMapController - .loadAttractionsFromLocation(currentLatLng, searchLatLng, checkingAroundCurrent)); - } - - /** - * Populates places for custom location, should be used for finding nearby places around a - * location where you are not at. - * - * @param explorePlacesInfo This variable has placeToCenter list information and distances. - */ - public void updateMapMarkers( - MapController.ExplorePlacesInfo explorePlacesInfo) { - if (explorePlacesInfo.mediaList != null) { - prepareNearbyBaseMarkers(explorePlacesInfo); - } else { - lockUnlockNearby(false); // So that new location updates wont come - exploreMapFragmentView.setProgressBarVisibility(false); - } - } - - void prepareNearbyBaseMarkers(MapController.ExplorePlacesInfo explorePlacesInfo) { - ExploreMapController.Companion.loadAttractionsFromLocationToBaseMarkerOptions(explorePlacesInfo.currentLatLng, - // Curlatlang will be used to calculate distances - (List) explorePlacesInfo.explorePlaceList, - exploreMapFragmentView.getContext(), - this, - explorePlacesInfo); - } - - @Override - public void onNearbyBaseMarkerThumbsReady(List baseMarkers, - ExplorePlacesInfo explorePlacesInfo) { - if (null != exploreMapFragmentView) { - exploreMapFragmentView.addMarkersToMap(baseMarkers); - lockUnlockNearby(false); // So that new location updates wont come - exploreMapFragmentView.setProgressBarVisibility(false); - } - } - - public View.OnClickListener onSearchThisAreaClicked() { - return v -> { - // Lock map operations during search this area operation - exploreMapFragmentView.setSearchThisAreaButtonVisibility(false); - - if (searchCloseToCurrentLocation()) { - updateMap(LOCATION_SIGNIFICANTLY_CHANGED); - } else { - updateMap(SEARCH_CUSTOM_AREA); - } - }; - } - - /** - * Returns true if search this area button is used around our current location, so that we can - * continue following our current location again - * - * @return Returns true if search this area button is used around our current location - */ - public boolean searchCloseToCurrentLocation() { - if (null == exploreMapFragmentView.getLastMapFocus()) { - return true; - } - - Location mylocation = new Location(""); - Location dest_location = new Location(""); - dest_location.setLatitude(exploreMapFragmentView.getMapFocus().getLatitude()); - dest_location.setLongitude(exploreMapFragmentView.getMapFocus().getLongitude()); - mylocation.setLatitude(exploreMapFragmentView.getLastMapFocus().getLatitude()); - mylocation.setLongitude(exploreMapFragmentView.getLastMapFocus().getLongitude()); - Float distance = mylocation.distanceTo(dest_location); - - return !(distance > 2000.0 * 3 / 4); - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.kt b/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.kt new file mode 100644 index 000000000..002ff6044 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/map/ExploreMapPresenter.kt @@ -0,0 +1,223 @@ +package fr.free.nrw.commons.explore.map + +import android.location.Location +import android.view.View +import fr.free.nrw.commons.BaseMarker +import fr.free.nrw.commons.MapController.ExplorePlacesInfo +import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao +import fr.free.nrw.commons.explore.map.ExploreMapController.Companion.loadAttractionsFromLocationToBaseMarkerOptions +import fr.free.nrw.commons.explore.map.ExploreMapController.NearbyBaseMarkerThumbCallback +import fr.free.nrw.commons.kvstore.JsonKvStore +import fr.free.nrw.commons.location.LatLng +import fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType +import fr.free.nrw.commons.nearby.Place +import io.reactivex.Observable +import timber.log.Timber +import java.lang.reflect.Method +import java.lang.reflect.Proxy +import java.util.concurrent.Callable + +class ExploreMapPresenter( + var bookmarkLocationDao: BookmarkLocationsDao +) : ExploreMapContract.UserActions, NearbyBaseMarkerThumbCallback { + + private var isNearbyLocked = false + private val currentLatLng: LatLng? = null + private var exploreMapController: ExploreMapController? = null + private var exploreMapFragmentView: ExploreMapContract.View? = DUMMY + + override fun updateMap(locationChangeType: LocationChangeType) { + Timber.d("Presenter updates map and list$locationChangeType") + if (isNearbyLocked) { + Timber.d("Nearby is locked, so updateMapAndList returns") + return + } + + if (!exploreMapFragmentView!!.isNetworkConnectionEstablished()) { + Timber.d("Network connection is not established") + return + } + + /** + * Significant changed - Markers and current location will be updated together + * Slightly changed - Only current position marker will be updated + */ + if (locationChangeType == LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED) { + Timber.d("LOCATION_SIGNIFICANTLY_CHANGED") + var populateLatLng = exploreMapFragmentView!!.getMapCenter() + + //If "Show in Explore" was selected in Nearby, use the previous LatLng + if (exploreMapFragmentView is ExploreMapFragment) { + val exploreMapFragment = exploreMapFragmentView as ExploreMapFragment + if (exploreMapFragment.recentlyCameFromNearbyMap()) { + //Ensure this LatLng will not be used again if user searches their GPS location + exploreMapFragment.setRecentlyCameFromNearbyMap(false) + + populateLatLng = exploreMapFragment.previousLatLng + } + } + + lockUnlockNearby(true) + exploreMapFragmentView!!.setProgressBarVisibility(true) + exploreMapFragmentView!!.populatePlaces(populateLatLng) + } else if (locationChangeType == LocationChangeType.SEARCH_CUSTOM_AREA) { + Timber.d("SEARCH_CUSTOM_AREA") + lockUnlockNearby(true) + exploreMapFragmentView!!.setProgressBarVisibility(true) + exploreMapFragmentView!!.populatePlaces(exploreMapFragmentView!!.getMapFocus()) + } else { // Means location changed slightly, ie user is walking or driving. + Timber.d("Means location changed slightly") + } + } + + /** + * Nearby updates takes time, since they are network operations. During update time, we don't + * want to get any other calls from user. So locking nearby. + * + * @param isNearbyLocked true means lock, false means unlock + */ + override fun lockUnlockNearby(isNearbyLocked: Boolean) { + this.isNearbyLocked = isNearbyLocked + if (isNearbyLocked) { + exploreMapFragmentView!!.disableFABRecenter() + } else { + exploreMapFragmentView!!.enableFABRecenter() + } + } + + override fun attachView(view: ExploreMapContract.View?) { + exploreMapFragmentView = view + } + + override fun detachView() { + exploreMapFragmentView = DUMMY + } + + /** + * Sets click listener of FAB + */ + override fun setActionListeners(applicationKvStore: JsonKvStore?) { + exploreMapFragmentView!!.setFABRecenterAction { + exploreMapFragmentView!!.recenterMap(currentLatLng) + } + } + + override fun backButtonClicked(): Boolean = + exploreMapFragmentView!!.backButtonClicked() + + fun onMapReady(exploreMapController: ExploreMapController?) { + this.exploreMapController = exploreMapController + if (null != exploreMapFragmentView) { + exploreMapFragmentView!!.addSearchThisAreaButtonAction() + initializeMapOperations() + } + } + + fun initializeMapOperations() { + lockUnlockNearby(false) + updateMap(LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED) + } + + fun loadAttractionsFromLocation( + currentLatLng: LatLng?, + searchLatLng: LatLng?, checkingAroundCurrent: Boolean + ): Observable = Observable.fromCallable(Callable { + exploreMapController!!.loadAttractionsFromLocation( + currentLatLng, + searchLatLng, + checkingAroundCurrent + ) + }) + + /** + * Populates places for custom location, should be used for finding nearby places around a + * location where you are not at. + * + * @param explorePlacesInfo This variable has placeToCenter list information and distances. + */ + fun updateMapMarkers( + explorePlacesInfo: ExplorePlacesInfo + ) { + if (explorePlacesInfo.mediaList != null) { + prepareNearbyBaseMarkers(explorePlacesInfo) + } else { + lockUnlockNearby(false) // So that new location updates wont come + exploreMapFragmentView!!.setProgressBarVisibility(false) + } + } + + private fun prepareNearbyBaseMarkers(explorePlacesInfo: ExplorePlacesInfo) { + loadAttractionsFromLocationToBaseMarkerOptions( + explorePlacesInfo.currentLatLng, // Curlatlang will be used to calculate distances + explorePlacesInfo.explorePlaceList, + exploreMapFragmentView!!.getContext()!!, + this, + explorePlacesInfo + ) + } + + override fun onNearbyBaseMarkerThumbsReady( + baseMarkers: List?, + explorePlacesInfo: ExplorePlacesInfo? + ) { + if (null != exploreMapFragmentView) { + exploreMapFragmentView!!.addMarkersToMap(baseMarkers) + lockUnlockNearby(false) // So that new location updates wont come + exploreMapFragmentView!!.setProgressBarVisibility(false) + } + } + + fun onSearchThisAreaClicked(): View.OnClickListener { + return View.OnClickListener { + // Lock map operations during search this area operation + exploreMapFragmentView!!.setSearchThisAreaButtonVisibility(false) + updateMap(if (searchCloseToCurrentLocation()) { + LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED + } else { + LocationChangeType.SEARCH_CUSTOM_AREA + }) + } + } + + /** + * Returns true if search this area button is used around our current location, so that we can + * continue following our current location again + * + * @return Returns true if search this area button is used around our current location + */ + private fun searchCloseToCurrentLocation(): Boolean { + if (null == exploreMapFragmentView!!.getLastMapFocus()) { + return true + } + + val mylocation = Location("").apply { + latitude = exploreMapFragmentView!!.getLastMapFocus()!!.latitude + longitude = exploreMapFragmentView!!.getLastMapFocus()!!.longitude + } + val dest_location = Location("").apply { + latitude = exploreMapFragmentView!!.getMapFocus()!!.latitude + longitude = exploreMapFragmentView!!.getMapFocus()!!.longitude + } + + val distance = mylocation.distanceTo(dest_location) + + return !(distance > 2000.0 * 3 / 4) + } + + companion object { + private val DUMMY = Proxy.newProxyInstance( + ExploreMapContract.View::class.java.classLoader, + arrayOf>(ExploreMapContract.View::class.java) + ) { _: Any?, method: Method, _: Array? -> + when { + method.name == "onMyEvent" -> null + String::class.java == method.returnType -> "" + Int::class.java == method.returnType -> 0 + Int::class.javaPrimitiveType == method.returnType -> 0 + Boolean::class.java == method.returnType -> java.lang.Boolean.FALSE + Boolean::class.javaPrimitiveType == method.returnType -> false + else -> null + } + } as ExploreMapContract.View + } +}