diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java index 1cebeda95..8ca73bedb 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java @@ -23,8 +23,6 @@ import android.graphics.drawable.Drawable; import android.location.Location; import android.location.LocationManager; import android.net.Uri; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; import android.os.Handler; @@ -56,7 +54,6 @@ import androidx.appcompat.app.AlertDialog.Builder; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.core.content.ContextCompat; import androidx.core.content.FileProvider; -import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwnerKt; import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.GridLayoutManager; @@ -97,7 +94,6 @@ import fr.free.nrw.commons.nearby.PlacesRepository; import fr.free.nrw.commons.nearby.WikidataFeedback; import fr.free.nrw.commons.nearby.contract.NearbyParentFragmentContract; import fr.free.nrw.commons.nearby.fragments.AdvanceQueryFragment.Callback; -import fr.free.nrw.commons.nearby.helper.JustExperimenting; import fr.free.nrw.commons.nearby.model.BottomSheetItem; import fr.free.nrw.commons.nearby.presenter.NearbyParentFragmentPresenter; import fr.free.nrw.commons.upload.FileUtils; @@ -113,16 +109,12 @@ import fr.free.nrw.commons.wikidata.WikidataEditListener; import io.reactivex.Completable; import io.reactivex.Observable; import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Locale; @@ -158,8 +150,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment FragmentNearbyParentBinding binding; -// private JustExperimenting justExperimenting; - public final MapEventsOverlay mapEventsOverlay = new MapEventsOverlay(new MapEventsReceiver() { @Override public boolean singleTapConfirmedHelper(GeoPoint p) { @@ -353,8 +343,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment binding = FragmentNearbyParentBinding.inflate(inflater, container, false); view = binding.getRoot(); -// justExperimenting = new JustExperimenting(this); - initNetworkBroadCastReceiver(); presenter = new NearbyParentFragmentPresenter(bookmarkLocationDao, placesRepository, nearbyController); progressDialog = new ProgressDialog(getActivity()); @@ -1363,7 +1351,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment ? getTextBetweenParentheses( updatedPlace.getLongDescription()) : updatedPlace.getLongDescription()); marker.showInfoWindow(); -// justExperimenting.handlePlaceClicked(updatedPlace); + presenter.handlePinClicked(updatedPlace); savePlaceToDatabase(place); Drawable icon = ContextCompat.getDrawable(getContext(), getIconFor(updatedPlace, isBookMarked)); @@ -1464,20 +1452,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment })); } - public Place getPlaceFromRepository(String entityID) { - return placesRepository.fetchPlace(entityID); - } - - public List getPlacesFromController(List places) { - List results = new ArrayList(); - try { - results = nearbyController.getPlaces(places); - } catch (Exception e) { - Timber.tag("Nearby Pin Details").e(e); - } - return results; - } - public void savePlaceToDatabase(Place place) { compositeDisposable.add(placesRepository .save(place) @@ -1953,18 +1927,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment binding.map.getOverlays().addAll(newMarkers); } - /** - * Adds multiple markers representing places to the map and handles item gestures. - * - * @param nearbyBaseMarkers The list of Place objects containing information about the - * locations. - */ - private void addMarkersToMap(List nearbyBaseMarkers) { - Timber.tag("temptagtwo").e("another n+1 C 2: " + nearbyBaseMarkers.size()); - for(int i = 0; i< nearbyBaseMarkers.size(); i++){ - addMarkerToMap(nearbyBaseMarkers.get(i).getPlace(), false); - } - } /** * Extracts text between the first occurrence of '(' and its corresponding ')' in the input @@ -2257,7 +2219,6 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment binding.map.invalidate(); GeoPoint geoPoint = mapCenter; if (geoPoint != null) { - List overlays = binding.map.getOverlays(); ScaleDiskOverlay diskOverlay = new ScaleDiskOverlay(this.getContext(), geoPoint, 2000, UnitOfMeasure.foot); diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/helper/JustExperimenting.kt b/app/src/main/java/fr/free/nrw/commons/nearby/helper/JustExperimenting.kt deleted file mode 100644 index 2199cf7dc..000000000 --- a/app/src/main/java/fr/free/nrw/commons/nearby/helper/JustExperimenting.kt +++ /dev/null @@ -1,198 +0,0 @@ -package fr.free.nrw.commons.nearby.helper - -import androidx.lifecycle.DefaultLifecycleObserver -import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.lifecycleScope -import fr.free.nrw.commons.location.LatLng -import fr.free.nrw.commons.nearby.MarkerPlaceGroup -import fr.free.nrw.commons.nearby.Place -import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.delay -import kotlinx.coroutines.ensureActive -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.osmdroid.views.overlay.Marker -import java.util.ArrayList -import java.util.concurrent.CopyOnWriteArrayList - -class JustExperimenting(frag: NearbyParentFragment) { - private val scope = frag.viewLifecycleOwner.lifecycleScope - - private var skippedCount = 0 - private val skipLimit = 2 - private val skipDelayMs = 1000L - - private var markersStateChannel = Channel>(Channel.CONFLATED) - private val markerBaseDataChannel = Channel>(Channel.CONFLATED) - - private val clickedPlaces = CopyOnWriteArrayList() - fun handlePlaceClicked(place: Place) { - clickedPlaces.add(place) - } - - fun loadNewMarkers(es: ArrayList) = scope.launch { - markerBaseDataChannel.send(es) - } - - suspend fun updateMarkersState(markers: List) { - markersStateChannel.send(markers) - } - - init { - scope.launch(Dispatchers.Default) { - var pinStateUpdateJob: Job? = null - for (markers in markersStateChannel) { - pinStateUpdateJob?.cancel() - pinStateUpdateJob = launch { - if (markers.isEmpty()) { - return@launch - } - if (skippedCount++ < skipLimit) { - delay(skipDelayMs) - } - skippedCount = 0 -// frag.replaceMarkerOverlays(markers) - } - } - } - scope.launch(Dispatchers.Default) { - var loadPinDetailsJob: Job? = null - for (markerBaseDataList in markerBaseDataChannel) { - loadPinDetailsJob?.cancel() - loadPinDetailsJob = launch { - loadPinsDetails(frag, markerBaseDataList, this) - } - } - } - - frag.viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { - override fun onDestroy(owner: LifecycleOwner) { - performCleanup() - } - }) - } - - private suspend fun loadPinsDetails( - frag: NearbyParentFragment, - markerBaseDataList: ArrayList, - scope: CoroutineScope - ) { - // make sure the grey pins are loaded immediately: - skippedCount = skipLimit - updateMarkersState(markerBaseDataList.map { - frag.convertToMarker(it.place, it.isBookmarked) - }) - - // now load the pin details: - clickedPlaces.clear() - var clickedPlacesIndex = 0 - markerBaseDataList.sortBy { - it.place.getDistanceInDouble(frag.mapFocus) - } - val updatedMarkers = ArrayList(markerBaseDataList.size) - markerBaseDataList.forEach { - updatedMarkers.add(frag.convertToMarker(it.place, it.isBookmarked)) - } - - val batchSize = 3 - var currentIndex = 0 - val endIndex = markerBaseDataList.lastIndex - while (currentIndex <= endIndex) { - scope.ensureActive() - val toUpdateMarkersFrom = currentIndex - - val placesToFetch = mutableListOf() - while (currentIndex <= endIndex && placesToFetch.size < batchSize) { - val existingPlace = markerBaseDataList[currentIndex].place - if (existingPlace.name != "") { - ++currentIndex - continue - } - val repoPlace = withContext(Dispatchers.IO) { - frag.getPlaceFromRepository(existingPlace.entityID) - } - if (repoPlace != null && repoPlace.name != "") { - markerBaseDataList[currentIndex] = - MarkerPlaceGroup(markerBaseDataList[currentIndex].isBookmarked, repoPlace) - ++currentIndex - continue - } - placesToFetch.add(currentIndex) - ++currentIndex - } - if (placesToFetch.isNotEmpty()) { - val fetchedPlaces = withContext(Dispatchers.IO) { - frag.getPlacesFromController(placesToFetch.map { - markerBaseDataList[it].place - }) - } - scope.ensureActive() - for (fetchedPlace in fetchedPlaces) { - for (index in placesToFetch) { // nesting okay here as batch size is small - val existingPlace = markerBaseDataList[index].place - if (existingPlace.siteLinks.wikidataLink == - fetchedPlace.siteLinks.wikidataLink - ) { - fetchedPlace.location = existingPlace.location - fetchedPlace.distance = existingPlace.distance - fetchedPlace.isMonument = existingPlace.isMonument - markerBaseDataList[index] = MarkerPlaceGroup( - markerBaseDataList[index].isBookmarked, fetchedPlace - ) - frag.savePlaceToDatabase(fetchedPlace) - } - } - } - } - for (i in toUpdateMarkersFrom..() - while (clickedPlacesIndex < clickedPlaces.size) { - clickedPlacesBacklog.put( - clickedPlaces[clickedPlacesIndex].location, - clickedPlaces[clickedPlacesIndex] - ) - ++clickedPlacesIndex - } - for (i in currentIndex..endIndex) { - if (clickedPlacesBacklog.containsKey(markerBaseDataList[i].place.location)) { - markerBaseDataList[i] = MarkerPlaceGroup( - markerBaseDataList[i].isBookmarked, - clickedPlacesBacklog[markerBaseDataList[i].place.location] - ) - updatedMarkers[i] = frag.convertToMarker( - markerBaseDataList[i].place, markerBaseDataList[i].isBookmarked - ) - } - } - } - updateMarkersState(updatedMarkers) - } - } - - private fun performCleanup() { - markersStateChannel.close() - markerBaseDataChannel.close() - } - -// private val mapEventsOverlay = frag.mapEventsOverlay -// fun getBaseOverlays(view: MapView): List = listOf( -// // distance scale -// ScaleBarOverlay(view).apply { -// setScaleBarOffset(15, 25) -// setBackgroundPaint(Paint().apply { setARGB(200, 255, 250, 250) }) -// enableScaleBar() -// }, -// // map events overlay: -// mapEventsOverlay -// ) - -} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/presenter/NearbyParentFragmentPresenter.kt b/app/src/main/java/fr/free/nrw/commons/nearby/presenter/NearbyParentFragmentPresenter.kt index 4ec53c78a..98dd5510d 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/presenter/NearbyParentFragmentPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/nearby/presenter/NearbyParentFragmentPresenter.kt @@ -32,6 +32,8 @@ import timber.log.Timber import java.lang.reflect.InvocationHandler import java.lang.reflect.Method import java.lang.reflect.Proxy +import java.util.concurrent.CopyOnWriteArrayList +import java.util.concurrent.CopyOnWriteArraySet class NearbyParentFragmentPresenter ( @@ -51,6 +53,11 @@ class NearbyParentFragmentPresenter private var nearbyParentFragmentView: NearbyParentFragmentContract.View = DUMMY + private val clickedPlaces = CopyOnWriteArrayList() + fun handlePinClicked(place: Place) { + clickedPlaces.add(place) + } + private var loadPlacesDataAyncJob: Job? = null private object LoadPlacesAsyncOptions { val batchSize = 3 @@ -235,6 +242,8 @@ class NearbyParentFragmentPresenter updatePlaceGroupsToControllerAndRender(nearbyPlaceGroups) loadPlacesDataAyncJob = scope?.launch(Dispatchers.IO) { + clickedPlaces.clear() // clear past clicks + var clickedPlacesIndex = 0 val updatedGroups = nearbyPlaceGroups.toMutableList() // first load cached places: val indicesToUpdate = mutableListOf() @@ -305,6 +314,25 @@ class NearbyParentFragmentPresenter placesRepository.save(finalPlaceGroup.place) } } + // handle any places clicked + if (clickedPlacesIndex < clickedPlaces.size) { + val clickedPlacesBacklog = hashMapOf() + while (clickedPlacesIndex < clickedPlaces.size) { + clickedPlacesBacklog.put( + clickedPlaces[clickedPlacesIndex].location, + clickedPlaces[clickedPlacesIndex] + ) + ++clickedPlacesIndex + } + for ((index, group) in updatedGroups.withIndex()) { + if (clickedPlacesBacklog.containsKey(group.place.location)) { + updatedGroups[index] = MarkerPlaceGroup( + updatedGroups[index].isBookmarked, + clickedPlacesBacklog[group.place.location] + ) + } + } + } schedulePlacesUpdate(updatedGroups) if (collectCount++ == totalBatches) { break