Skip to content

Commit 3e020ed

Browse files
Fixes commons-app#5806 Implemented "Refresh" button to clear the cache and reload the Nearby map (commons-app#5891)
* Changed files required to get the app to run correctly. Removed suspend from affected DAO files and funcs, and changed to (Kotlin v1.9.22) and (Kotlin compiler v1.5.8) * Created refresh button icon, and added it to the nearby_fragment_menu.xml (header of the nearby page). Created function refresh() in NearbyParentFragment.java to handle refresh functionality. * Replaced refresh() func with emptyCache() and reloadMap() * Attempt at reloadMap(), no testing done yet. * added changes for a possibly working emptyCache implementation (needs testing). * Tested changes as working, edited emptyCache to correctly clear cache and then reload map --------- Co-authored-by: MarcusBarta <marcusbarta@icloud.com>
1 parent becc07d commit 3e020ed

File tree

15 files changed

+140
-35
lines changed

15 files changed

+140
-35
lines changed

.idea/inspectionProfiles/Project_Default.xml

-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ android {
381381
compose true
382382
}
383383
composeOptions {
384-
kotlinCompilerExtensionVersion '1.3.2'
384+
kotlinCompilerExtensionVersion '1.5.8'
385385
}
386386
namespace 'fr.free.nrw.commons'
387387
lint {

app/src/main/java/fr/free/nrw/commons/customselector/database/NotForUploadStatusDao.kt

+5-5
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ abstract class NotForUploadStatusDao {
1515
* Insert into Not For Upload status.
1616
*/
1717
@Insert(onConflict = OnConflictStrategy.REPLACE)
18-
abstract suspend fun insert(notForUploadStatus: NotForUploadStatus)
18+
abstract fun insert(notForUploadStatus: NotForUploadStatus)
1919

2020
/**
2121
* Delete Not For Upload status entry.
2222
*/
2323
@Delete
24-
abstract suspend fun delete(notForUploadStatus: NotForUploadStatus)
24+
abstract fun delete(notForUploadStatus: NotForUploadStatus)
2525

2626
/**
2727
* Query Not For Upload status with image sha1.
2828
*/
2929
@Query("SELECT * FROM images_not_for_upload_table WHERE imageSHA1 = (:imageSHA1) ")
30-
abstract suspend fun getFromImageSHA1(imageSHA1: String): NotForUploadStatus?
30+
abstract fun getFromImageSHA1(imageSHA1: String): NotForUploadStatus?
3131

3232
/**
3333
* Asynchronous image sha1 query.
@@ -38,7 +38,7 @@ abstract class NotForUploadStatusDao {
3838
* Deletion Not For Upload status with image sha1.
3939
*/
4040
@Query("DELETE FROM images_not_for_upload_table WHERE imageSHA1 = (:imageSHA1) ")
41-
abstract suspend fun deleteWithImageSHA1(imageSHA1: String)
41+
abstract fun deleteWithImageSHA1(imageSHA1: String)
4242

4343
/**
4444
* Asynchronous image sha1 deletion.
@@ -49,5 +49,5 @@ abstract class NotForUploadStatusDao {
4949
* Check whether the imageSHA1 is present in database
5050
*/
5151
@Query("SELECT COUNT() FROM images_not_for_upload_table WHERE imageSHA1 = (:imageSHA1) ")
52-
abstract suspend fun find(imageSHA1: String): Int
52+
abstract fun find(imageSHA1: String): Int
5353
}

app/src/main/java/fr/free/nrw/commons/customselector/database/UploadedStatusDao.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -17,31 +17,31 @@ abstract class UploadedStatusDao {
1717
* Insert into uploaded status.
1818
*/
1919
@Insert(onConflict = OnConflictStrategy.REPLACE)
20-
abstract suspend fun insert(uploadedStatus: UploadedStatus)
20+
abstract fun insert(uploadedStatus: UploadedStatus)
2121

2222
/**
2323
* Update uploaded status entry.
2424
*/
2525
@Update
26-
abstract suspend fun update(uploadedStatus: UploadedStatus)
26+
abstract fun update(uploadedStatus: UploadedStatus)
2727

2828
/**
2929
* Delete uploaded status entry.
3030
*/
3131
@Delete
32-
abstract suspend fun delete(uploadedStatus: UploadedStatus)
32+
abstract fun delete(uploadedStatus: UploadedStatus)
3333

3434
/**
3535
* Query uploaded status with image sha1.
3636
*/
3737
@Query("SELECT * FROM uploaded_table WHERE imageSHA1 = (:imageSHA1) ")
38-
abstract suspend fun getFromImageSHA1(imageSHA1: String): UploadedStatus?
38+
abstract fun getFromImageSHA1(imageSHA1: String): UploadedStatus?
3939

4040
/**
4141
* Query uploaded status with modified image sha1.
4242
*/
4343
@Query("SELECT * FROM uploaded_table WHERE modifiedImageSHA1 = (:modifiedImageSHA1) ")
44-
abstract suspend fun getFromModifiedImageSHA1(modifiedImageSHA1: String): UploadedStatus?
44+
abstract fun getFromModifiedImageSHA1(modifiedImageSHA1: String): UploadedStatus?
4545

4646
/**
4747
* Asynchronous insert into uploaded status table.
@@ -55,7 +55,7 @@ abstract class UploadedStatusDao {
5555
* Check whether the imageSHA1 is present in database
5656
*/
5757
@Query("SELECT COUNT() FROM uploaded_table WHERE imageSHA1 = (:imageSHA1) AND imageResult = (:imageResult) ")
58-
abstract suspend fun findByImageSHA1(
58+
abstract fun findByImageSHA1(
5959
imageSHA1: String,
6060
imageResult: Boolean,
6161
): Int
@@ -66,7 +66,7 @@ abstract class UploadedStatusDao {
6666
@Query(
6767
"SELECT COUNT() FROM uploaded_table WHERE modifiedImageSHA1 = (:modifiedImageSHA1) AND modifiedImageResult = (:modifiedImageResult) ",
6868
)
69-
abstract suspend fun findByModifiedImageSHA1(
69+
abstract fun findByModifiedImageSHA1(
7070
modifiedImageSHA1: String,
7171
modifiedImageResult: Boolean,
7272
): Int

app/src/main/java/fr/free/nrw/commons/nearby/PlaceDao.java

+19
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,23 @@ public Completable save(final Place place) {
4141
saveSynchronous(place);
4242
});
4343
}
44+
45+
/**
46+
* Deletes all Place objects from the database.
47+
*
48+
* @return A Completable that completes once the deletion operation is done.
49+
*/
50+
@Query("DELETE FROM place")
51+
public abstract void deleteAllSynchronous();
52+
53+
/**
54+
* Deletes all Place objects from the database.
55+
*
56+
*/
57+
public Completable deleteAll() {
58+
return Completable
59+
.fromAction(() -> {
60+
deleteAllSynchronous();
61+
});
62+
}
4463
}

app/src/main/java/fr/free/nrw/commons/nearby/PlacesLocalDataSource.java

+4
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@ public Place fetchPlace(String entityID){
3535
public Completable savePlace(Place place) {
3636
return placeDao.save(place);
3737
}
38+
39+
public Completable clearCache() {
40+
return placeDao.deleteAll();
41+
}
3842
}

app/src/main/java/fr/free/nrw/commons/nearby/PlacesRepository.java

+10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import fr.free.nrw.commons.contributions.Contribution;
44
import fr.free.nrw.commons.location.LatLng;
55
import io.reactivex.Completable;
6+
import io.reactivex.schedulers.Schedulers;
67
import javax.inject.Inject;
78

89
/**
@@ -38,4 +39,13 @@ public Place fetchPlace(String entityID){
3839
return localDataSource.fetchPlace(entityID);
3940
}
4041

42+
/**
43+
* Clears the Nearby cache on an IO thread.
44+
*
45+
* @return A Completable that completes once the cache has been successfully cleared.
46+
*/
47+
public Completable clearCache() {
48+
return localDataSource.clearCache()
49+
.subscribeOn(Schedulers.io()); // Ensure it runs on IO thread
50+
}
4151
}

app/src/main/java/fr/free/nrw/commons/nearby/fragments/NearbyParentFragment.java

+55
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
import fr.free.nrw.commons.utils.SystemThemeUtils;
109109
import fr.free.nrw.commons.utils.ViewUtil;
110110
import fr.free.nrw.commons.wikidata.WikidataEditListener;
111+
import io.reactivex.Completable;
111112
import io.reactivex.Observable;
112113
import io.reactivex.android.schedulers.AndroidSchedulers;
113114
import io.reactivex.disposables.Disposable;
@@ -342,9 +343,21 @@ public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup
342343
public void onCreateOptionsMenu(@NonNull final Menu menu,
343344
@NonNull final MenuInflater inflater) {
344345
inflater.inflate(R.menu.nearby_fragment_menu, menu);
346+
MenuItem refreshButton = menu.findItem(R.id.item_refresh);
345347
MenuItem listMenu = menu.findItem(R.id.list_sheet);
346348
MenuItem saveAsGPXButton = menu.findItem(R.id.list_item_gpx);
347349
MenuItem saveAsKMLButton = menu.findItem(R.id.list_item_kml);
350+
refreshButton.setOnMenuItemClickListener(new OnMenuItemClickListener() {
351+
@Override
352+
public boolean onMenuItemClick(MenuItem item) {
353+
try {
354+
emptyCache();
355+
} catch (Exception e) {
356+
throw new RuntimeException(e);
357+
}
358+
return false;
359+
}
360+
});
348361
listMenu.setOnMenuItemClickListener(new OnMenuItemClickListener() {
349362
@Override
350363
public boolean onMenuItemClick(MenuItem item) {
@@ -1158,6 +1171,48 @@ public void populatePlaces(final LatLng currentLatLng,
11581171
}
11591172
}
11601173

1174+
/**
1175+
* Reloads the Nearby map
1176+
* Clears all location markers, refreshes them, reinserts them into the map.
1177+
*
1178+
*/
1179+
private void reloadMap() {
1180+
clearAllMarkers(); // Clear the list of markers
1181+
binding.map.getController().setZoom(ZOOM_LEVEL); // Reset the zoom level
1182+
binding.map.getController().setCenter(lastMapFocus); // Recenter the focus
1183+
if (locationPermissionsHelper.checkLocationPermission(getActivity())) {
1184+
locationPermissionGranted(); // Reload map with user's location
1185+
} else {
1186+
startMapWithoutPermission(); // Reload map without user's location
1187+
}
1188+
binding.map.invalidate(); // Invalidate the map
1189+
presenter.updateMapAndList(LOCATION_SIGNIFICANTLY_CHANGED); // Restart the map
1190+
Timber.d("Reloaded Map Successfully");
1191+
}
1192+
1193+
1194+
/**
1195+
* Clears the Nearby local cache and then calls for the map to be reloaded
1196+
*
1197+
*/
1198+
private void emptyCache() {
1199+
// reload the map once the cache is cleared
1200+
compositeDisposable.add(
1201+
placesRepository.clearCache()
1202+
.subscribeOn(Schedulers.io())
1203+
.observeOn(AndroidSchedulers.mainThread())
1204+
.andThen(Completable.fromAction(this::reloadMap))
1205+
.subscribe(
1206+
() -> {
1207+
Timber.d("Nearby Cache cleared successfully.");
1208+
},
1209+
throwable -> {
1210+
Timber.e(throwable, "Failed to clear the Nearby Cache");
1211+
}
1212+
)
1213+
);
1214+
}
1215+
11611216
private void savePlacesAsKML() {
11621217
final Observable<String> savePlacesObservable = Observable
11631218
.fromCallable(() -> nearbyController

app/src/main/java/fr/free/nrw/commons/upload/categories/BaseDelegateAdapter.kt

+6-8
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@ abstract class BaseDelegateAdapter<T>(
1010
areContentsTheSame: (T, T) -> Boolean = { old, new -> old == new },
1111
) : AsyncListDifferDelegationAdapter<T>(
1212
object : DiffUtil.ItemCallback<T>() {
13-
override fun areItemsTheSame(
14-
oldItem: T,
15-
newItem: T,
16-
) = areItemsTheSame(oldItem, newItem)
13+
override fun areItemsTheSame(oldItem: T & Any, newItem: T & Any): Boolean {
14+
return areItemsTheSame(oldItem, newItem)
15+
}
1716

18-
override fun areContentsTheSame(
19-
oldItem: T,
20-
newItem: T,
21-
) = areContentsTheSame(oldItem, newItem)
17+
override fun areContentsTheSame(oldItem: T & Any, newItem: T & Any): Boolean {
18+
return areContentsTheSame(oldItem, newItem)
19+
}
2220
},
2321
*delegates,
2422
) {

app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsDao.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ abstract class DepictsDao {
2222
private val maxItemsAllowed = 10
2323

2424
@Insert(onConflict = OnConflictStrategy.REPLACE)
25-
abstract suspend fun insert(depictedItem: Depicts)
25+
abstract fun insert(depictedItem: Depicts)
2626

2727
@Query("Select * From depicts_table order by lastUsed DESC")
28-
abstract suspend fun getAllDepicts(): List<Depicts>
28+
abstract fun getAllDepicts(): List<Depicts>
2929

3030
@Query("Select * From depicts_table order by lastUsed DESC LIMIT :n OFFSET 10")
31-
abstract suspend fun getDepictsForDeletion(n: Int): List<Depicts>
31+
abstract fun getDepictsForDeletion(n: Int): List<Depicts>
3232

3333
@Delete
34-
abstract suspend fun delete(depicts: Depicts)
34+
abstract fun delete(depicts: Depicts)
3535

3636
/**
3737
* Gets all Depicts objects from the database, ordered by lastUsed in descending order.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="@dimen/half_standard_height"
3+
android:height="@dimen/half_standard_height"
4+
android:viewportHeight="24.0"
5+
android:viewportWidth="24.0">
6+
7+
<group
8+
android:scaleX="1.0"
9+
android:scaleY="1.0"
10+
android:translateX="-0.0"
11+
android:translateY="-0.0">
12+
13+
<path
14+
android:fillColor="?attr/menu_item_tint"
15+
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
16+
17+
</group>
18+
</vector>
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
<menu xmlns:android="http://schemas.android.com/apk/res/android"
22
xmlns:app="http://schemas.android.com/apk/res-auto">
33

4+
<item android:id="@+id/item_refresh"
5+
android:title="Refresh"
6+
app:showAsAction="ifRoom"
7+
android:icon="@drawable/ic_refresh_24dp_nearby" />
8+
49
<item android:id="@+id/list_sheet"
510
android:title="@string/list_sheet"
611
app:showAsAction="ifRoom|withText"
712
android:icon="@drawable/ic_list_white_24dp"
813
/>
14+
915
<item android:id="@+id/list_item_gpx"
1016
android:layout_width="wrap_content"
1117
android:layout_height="wrap_content"
1218
android:title="Save as GPX file" />
19+
1320
<item android:id="@+id/list_item_kml"
1421
android:layout_width="wrap_content"
1522
android:layout_height="wrap_content"
1623
android:title="Save as KML file" />
24+
1725
</menu>

build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ buildscript {
66
maven { url "https://plugins.gradle.org/m2/" }
77
}
88
dependencies {
9-
classpath 'com.android.tools.build:gradle:8.5.0'
9+
classpath 'com.android.tools.build:gradle:8.7.0'
1010
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.8.2'
1111
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION"
1212
classpath 'org.codehaus.groovy:groovy-all:2.4.15'

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ org.gradle.jvmargs=-Xmx1536M
1717
org.gradle.caching=true
1818
android.enableR8.fullMode=false
1919

20-
KOTLIN_VERSION=1.7.20
20+
KOTLIN_VERSION=1.9.22
2121
LEAK_CANARY_VERSION=2.10
2222
DAGGER_VERSION=2.23
2323
ROOM_VERSION=2.5.0
+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#Sun Apr 23 18:22:54 IST 2023
22
distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
4-
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
4+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
55
zipStoreBase=GRADLE_USER_HOME
66
zipStorePath=wrapper/dists

0 commit comments

Comments
 (0)