Replace temporary fixes completely

This commit is contained in:
savsch 2024-12-19 21:13:52 +05:30
parent 73c16aea41
commit c25f79c49a
3 changed files with 29 additions and 238 deletions

View file

@ -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<Place> getPlacesFromController(List<Place> places) {
List<Place> results = new ArrayList<Place>();
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<BaseMarker> 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<Overlay> overlays = binding.map.getOverlays();
ScaleDiskOverlay diskOverlay =
new ScaleDiskOverlay(this.getContext(),
geoPoint, 2000, UnitOfMeasure.foot);

View file

@ -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<List<Marker>>(Channel.CONFLATED)
private val markerBaseDataChannel = Channel<ArrayList<MarkerPlaceGroup>>(Channel.CONFLATED)
private val clickedPlaces = CopyOnWriteArrayList<Place>()
fun handlePlaceClicked(place: Place) {
clickedPlaces.add(place)
}
fun loadNewMarkers(es: ArrayList<MarkerPlaceGroup>) = scope.launch {
markerBaseDataChannel.send(es)
}
suspend fun updateMarkersState(markers: List<Marker>) {
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<MarkerPlaceGroup>,
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<Marker>(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<Int>()
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..<currentIndex) {
updatedMarkers[i] = frag.convertToMarker(
markerBaseDataList[i].place, markerBaseDataList[i].isBookmarked
)
}
if (clickedPlacesIndex < clickedPlaces.size) {
val clickedPlacesBacklog = hashMapOf<LatLng, Place>()
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<Overlay> = listOf(
// // distance scale
// ScaleBarOverlay(view).apply {
// setScaleBarOffset(15, 25)
// setBackgroundPaint(Paint().apply { setARGB(200, 255, 250, 250) })
// enableScaleBar()
// },
// // map events overlay:
// mapEventsOverlay
// )
}

View file

@ -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<Place>()
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<Int>()
@ -305,6 +314,25 @@ class NearbyParentFragmentPresenter
placesRepository.save(finalPlaceGroup.place)
}
}
// handle any places clicked
if (clickedPlacesIndex < clickedPlaces.size) {
val clickedPlacesBacklog = hashMapOf<LatLng, Place>()
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