Skip to content

Commit 6d4ba12

Browse files
authored
Improved UX for Nearby Export (commons-app#5654)
* Fixed Grey empty screen at Upload wizard caption step after denying files permission * Empty commit * Fixed loop issue * Created docs for earlier commits * Fixed javadoc * Fixed spaces * Added added basic features to OSM Maps * Added search ___location feature * Added filter to Open Street Maps * Fixed chipGroup in Open Street Maps * Removed mapBox code * Removed mapBox's code * Reformat code * Reformatted code * Removed rotation feature to map * Removed rotation files and Fixed Marker click problem * Ignored failing tests * Added voice input feature * Fixed test cases * Changed caption and description text * Replaced mapbox to osmdroid in upload activity * Fixed Unit Tests * Made selected marker to be fixed on map * Changed color of map marker * Fixes commons-app#5439 by capitalizing first letter of voice input * Removed mapbox code1 * Removed mapbox code2 * Fixed failing tests * Fixed failing due to merging * Added feature to save nearby places as GPX and KML * Fixed error caused by null * Improved UX for Nearby Export * Delete app/src/main/res/values-yue-hant directory * Fixed internationalization issue
1 parent c5c5a52 commit 6d4ba12

File tree

3 files changed

+90
-48
lines changed

3 files changed

+90
-48
lines changed

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

Lines changed: 82 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import android.Manifest;
1010
import android.Manifest.permission;
1111
import android.annotation.SuppressLint;
12+
import android.app.ProgressDialog;
13+
import android.content.ActivityNotFoundException;
1214
import android.content.BroadcastReceiver;
1315
import android.content.Context;
1416
import android.content.Intent;
@@ -45,6 +47,7 @@
4547
import androidx.annotation.Nullable;
4648
import androidx.appcompat.app.AlertDialog;
4749
import androidx.core.content.ContextCompat;
50+
import androidx.core.content.FileProvider;
4851
import androidx.recyclerview.widget.DividerItemDecoration;
4952
import androidx.recyclerview.widget.LinearLayoutManager;
5053
import com.google.android.material.bottomsheet.BottomSheetBehavior;
@@ -168,6 +171,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
168171
private Place selectedPlace;
169172
private Place clickedMarkerPlace;
170173
private boolean isClickedMarkerBookmarked;
174+
private ProgressDialog progressDialog;
171175
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.005;
172176
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.004;
173177
private boolean isPermissionDenied;
@@ -257,6 +261,9 @@ public View onCreateView(@NonNull final LayoutInflater inflater, final ViewGroup
257261

258262
initNetworkBroadCastReceiver();
259263
presenter = new NearbyParentFragmentPresenter(bookmarkLocationDao);
264+
progressDialog = new ProgressDialog(getActivity());
265+
progressDialog.setCancelable(false);
266+
progressDialog.setMessage("Saving in progress...");
260267
setHasOptionsMenu(true);
261268
// Inflate the layout for this fragment
262269
return view;
@@ -288,8 +295,9 @@ public boolean onMenuItemClick(@NonNull MenuItem item) {
288295
screenBottomLeft.getLatitude(), screenBottomLeft.getLongitude(), 0);
289296
fr.free.nrw.commons.___location.LatLng screenBottomLeftLatLng = new fr.free.nrw.commons.___location.LatLng(
290297
screenTopRight.getLatitude(), screenTopRight.getLongitude(), 0);
291-
setProgressBarVisibility(true);
292-
savePlacesAsGPX(screenTopRightLatLng,screenBottomLeftLatLng);
298+
progressDialog.setTitle(getString(R.string.saving_gpx_file));
299+
progressDialog.show();
300+
savePlacesAsGPX(screenTopRightLatLng, screenBottomLeftLatLng);
293301
} catch (Exception e) {
294302
throw new RuntimeException(e);
295303
}
@@ -307,8 +315,9 @@ public boolean onMenuItemClick(@NonNull MenuItem item) {
307315
screenBottomLeft.getLatitude(), screenBottomLeft.getLongitude(), 0);
308316
fr.free.nrw.commons.___location.LatLng screenBottomLeftLatLng = new fr.free.nrw.commons.___location.LatLng(
309317
screenTopRight.getLatitude(), screenTopRight.getLongitude(), 0);
310-
setProgressBarVisibility(true);
311-
savePlacesAsKML(screenTopRightLatLng,screenBottomLeftLatLng);
318+
progressDialog.setTitle(getString(R.string.saving_kml_file));
319+
progressDialog.show();
320+
savePlacesAsKML(screenTopRightLatLng, screenBottomLeftLatLng);
312321
} catch (Exception e) {
313322
throw new RuntimeException(e);
314323
}
@@ -367,10 +376,10 @@ public void onViewCreated(@NonNull final View view, @Nullable final Bundle saved
367376
binding.map.getOverlays().add(new MapEventsOverlay(new MapEventsReceiver() {
368377
@Override
369378
public boolean singleTapConfirmedHelper(GeoPoint p) {
370-
if (clickedMarkerPlace != null){
379+
if (clickedMarkerPlace != null) {
371380
removeMarker(clickedMarkerPlace);
372-
addMarkerToMap(clickedMarkerPlace,isClickedMarkerBookmarked);
373-
}else {
381+
addMarkerToMap(clickedMarkerPlace, isClickedMarkerBookmarked);
382+
} else {
374383
Timber.e("CLICKED MARKER IS NULL");
375384
}
376385
if (isListBottomSheetExpanded()) {
@@ -441,7 +450,8 @@ public boolean onZoom(ZoomEvent event) {
441450
final AdvanceQueryFragment fragment = new AdvanceQueryFragment();
442451
final Bundle bundle = new Bundle();
443452
try {
444-
bundle.putString("query", FileUtils.readFromResource("/queries/radius_query_for_upload_wizard.rq"));
453+
bundle.putString("query",
454+
FileUtils.readFromResource("/queries/radius_query_for_upload_wizard.rq"));
445455
} catch (IOException e) {
446456
Timber.e(e);
447457
}
@@ -507,7 +517,8 @@ private void initRvNearbyList() {
507517
binding.bottomSheetNearby.rvNearbyList.setLayoutManager(new LinearLayoutManager(getContext()));
508518
adapter = new PlaceAdapter(bookmarkLocationDao,
509519
place -> {
510-
moveCameraToPosition(new GeoPoint(place.___location.getLatitude(),place.___location.getLongitude()));
520+
moveCameraToPosition(
521+
new GeoPoint(place.___location.getLatitude(), place.___location.getLongitude()));
511522
return Unit.INSTANCE;
512523
},
513524
(place, isBookmarked) -> {
@@ -1166,13 +1177,12 @@ private void savePlacesAsKML(LatLng latLng, LatLng nextlatLng) {
11661177
String fileName =
11671178
"KML_" + timeStamp + "_" + System.currentTimeMillis() + ".kml";
11681179
boolean saved = saveFile(kmlString, fileName);
1169-
setProgressBarVisibility(false);
1180+
progressDialog.hide();
11701181
if (saved) {
1171-
Toast.makeText(this.getContext(),
1172-
"KML file saved successfully at /Downloads/" + fileName,
1173-
Toast.LENGTH_SHORT).show();
1182+
showOpenFileDialog(getContext(), fileName, false);
11741183
} else {
1175-
Toast.makeText(this.getContext(), "Failed to save KML file.",
1184+
Toast.makeText(this.getContext(),
1185+
getString(R.string.failed_to_save_kml_file),
11761186
Toast.LENGTH_SHORT).show();
11771187
}
11781188
}
@@ -1201,13 +1211,12 @@ private void savePlacesAsGPX(LatLng latLng, LatLng nextlatLng) {
12011211
String fileName =
12021212
"GPX_" + timeStamp + "_" + System.currentTimeMillis() + ".gpx";
12031213
boolean saved = saveFile(gpxString, fileName);
1204-
setProgressBarVisibility(false);
1214+
progressDialog.hide();
12051215
if (saved) {
1206-
Toast.makeText(this.getContext(),
1207-
"GPX file saved successfully at /Downloads/" + fileName,
1208-
Toast.LENGTH_SHORT).show();
1216+
showOpenFileDialog(getContext(), fileName, true);
12091217
} else {
1210-
Toast.makeText(this.getContext(), "Failed to save KML file.",
1218+
Toast.makeText(this.getContext(),
1219+
getString(R.string.failed_to_save_gpx_file),
12111220
Toast.LENGTH_SHORT).show();
12121221
}
12131222
}
@@ -1243,6 +1252,38 @@ public static boolean saveFile(String string, String fileName) {
12431252
}
12441253
}
12451254

1255+
private void showOpenFileDialog(Context context, String fileName, Boolean isGPX) {
1256+
String title = getString(R.string.file_saved_successfully);
1257+
String message =
1258+
(isGPX) ? getString(R.string.do_you_want_to_open_gpx_file)
1259+
: getString(R.string.do_you_want_to_open_kml_file);
1260+
Runnable runnable = () -> openFile(context, fileName, isGPX);
1261+
DialogUtil.showAlertDialog(getActivity(), title, message, runnable,() -> {});
1262+
}
1263+
1264+
private void openFile(Context context, String fileName, Boolean isGPX) {
1265+
File file = new File(
1266+
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
1267+
fileName);
1268+
Uri uri = FileProvider.getUriForFile(context,
1269+
context.getApplicationContext().getPackageName() + ".provider", file);
1270+
Intent intent = new Intent(Intent.ACTION_VIEW);
1271+
1272+
if (isGPX) {
1273+
intent.setDataAndType(uri, "application/gpx");
1274+
} else {
1275+
intent.setDataAndType(uri, "application/kml");
1276+
}
1277+
1278+
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
1279+
try {
1280+
context.startActivity(intent);
1281+
} catch (ActivityNotFoundException e) {
1282+
Toast.makeText(context, R.string.no_application_available_to_open_gpx_files,
1283+
Toast.LENGTH_SHORT).show();
1284+
}
1285+
}
1286+
12461287
private static boolean isExternalStorageWritable() {
12471288
String state = Environment.getExternalStorageState();
12481289
return Environment.MEDIA_MOUNTED.equals(state);
@@ -1486,7 +1527,8 @@ public void displayLoginSkippedWarning() {
14861527
.setMessage(R.string.login_alert_message)
14871528
.setPositiveButton(R.string.login, (dialog, which) -> {
14881529
// logout of the app
1489-
BaseLogoutListener logoutListener = new BaseLogoutListener(getActivity()); CommonsApplication app = (CommonsApplication) getActivity().getApplication();
1530+
BaseLogoutListener logoutListener = new BaseLogoutListener(getActivity());
1531+
CommonsApplication app = (CommonsApplication) getActivity().getApplication();
14901532
app.clearApplicationData(getContext(), logoutListener);
14911533
})
14921534
.show();
@@ -1557,14 +1599,15 @@ public void enableFABRecenter() {
15571599
* Adds a marker for the user's current position. Adds a circle which uses the accuracy * 2, to
15581600
* draw a circle which represents the user's position with an accuracy of 95%.
15591601
* <p>
1560-
* Should be called only on creation of Map, there is other method to update markers
1561-
* ___location with users move.
1602+
* Should be called only on creation of Map, there is other method to update markers ___location
1603+
* with users move.
15621604
*
15631605
* @param currentLatLng current ___location
15641606
*/
15651607
@Override
15661608
public void addCurrentLocationMarker(final fr.free.nrw.commons.___location.LatLng currentLatLng) {
1567-
if (null != currentLatLng && !isPermissionDenied && locationManager.isGPSProviderEnabled()) {
1609+
if (null != currentLatLng && !isPermissionDenied
1610+
&& locationManager.isGPSProviderEnabled()) {
15681611
ExecutorUtils.get().submit(() -> {
15691612
Timber.d("Adds current ___location marker");
15701613
recenterMarkerToPosition(
@@ -1668,9 +1711,9 @@ public fr.free.nrw.commons.___location.LatLng getCameraTarget() {
16681711
/**
16691712
* Sets marker icon according to marker status. Sets title and distance.
16701713
*
1671-
* @param isBookmarked true if place is bookmarked
1714+
* @param isBookmarked true if place is bookmarked
16721715
* @param place
1673-
* @param currentLatLng current ___location
1716+
* @param currentLatLng current ___location
16741717
*/
16751718
public void updateMarker(final boolean isBookmarked, final Place place,
16761719
@Nullable final fr.free.nrw.commons.___location.LatLng currentLatLng) {
@@ -1691,18 +1734,18 @@ private void highlightNearestPlace(Place nearestPlace) {
16911734
/**
16921735
* Returns drawable of marker icon for given place
16931736
*
1694-
* @param place where marker is to be added
1737+
* @param place where marker is to be added
16951738
* @param isBookmarked true if place is bookmarked
16961739
* @return returns the drawable of marker according to the place information
16971740
*/
16981741
private @DrawableRes int getIconFor(Place place, Boolean isBookmarked) {
1699-
if(nearestPlace!=null) {
1700-
if(place.name.equals(nearestPlace.name)) {
1742+
if (nearestPlace != null) {
1743+
if (place.name.equals(nearestPlace.name)) {
17011744
// Highlight nearest place only when user clicks on the home nearby banner
17021745
highlightNearestPlace(place);
1703-
return (isBookmarked?
1704-
R.drawable.ic_custom_map_marker_purple_bookmarked:
1705-
R.drawable.ic_custom_map_marker_purple);
1746+
return (isBookmarked ?
1747+
R.drawable.ic_custom_map_marker_purple_bookmarked :
1748+
R.drawable.ic_custom_map_marker_purple);
17061749
}
17071750
}
17081751
if (place.isMonument()) {
@@ -1743,10 +1786,10 @@ public boolean onItemSingleTapUp(int index, OverlayItem item) {
17431786
hideBottomSheet();
17441787
if (clickedMarkerPlace != null) {
17451788
removeMarker(clickedMarkerPlace);
1746-
addMarkerToMap(clickedMarkerPlace,isClickedMarkerBookmarked);
1789+
addMarkerToMap(clickedMarkerPlace, isClickedMarkerBookmarked);
17471790
}
17481791
clickedMarkerPlace = place;
1749-
isClickedMarkerBookmarked = isBookMarked ;
1792+
isClickedMarkerBookmarked = isBookMarked;
17501793
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
17511794
return true;
17521795
}
@@ -1789,10 +1832,10 @@ public boolean onItemSingleTapUp(int index, OverlayItem item) {
17891832
hideBottomSheet();
17901833
if (clickedMarkerPlace != null) {
17911834
removeMarker(clickedMarkerPlace);
1792-
addMarkerToMap(clickedMarkerPlace,isClickedMarkerBookmarked);
1835+
addMarkerToMap(clickedMarkerPlace, isClickedMarkerBookmarked);
17931836
}
1794-
clickedMarkerPlace = place ;
1795-
isClickedMarkerBookmarked = false ;
1837+
clickedMarkerPlace = place;
1838+
isClickedMarkerBookmarked = false;
17961839
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
17971840
return true;
17981841
}
@@ -2134,10 +2177,10 @@ public void clearAllMarkers() {
21342177
binding.map.getOverlays().add(new MapEventsOverlay(new MapEventsReceiver() {
21352178
@Override
21362179
public boolean singleTapConfirmedHelper(GeoPoint p) {
2137-
if (clickedMarkerPlace != null){
2180+
if (clickedMarkerPlace != null) {
21382181
removeMarker(clickedMarkerPlace);
2139-
addMarkerToMap(clickedMarkerPlace,isClickedMarkerBookmarked);
2140-
}else {
2182+
addMarkerToMap(clickedMarkerPlace, isClickedMarkerBookmarked);
2183+
} else {
21412184
Timber.e("CLICKED MARKER IS NULL");
21422185
}
21432186
if (isListBottomSheetExpanded()) {

app/src/main/res/values-yue-hant/error.xml

Lines changed: 0 additions & 9 deletions
This file was deleted.

app/src/main/res/values/strings.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,14 @@ Upload your first media by tapping on the add button.</string>
793793
<string name="send_thanks_to_author">Thank the author</string>
794794
<string name="error_sending_thanks">Error sending thanks to author.</string>
795795
<string name="invalid_login_message">Your log-in has expired. Please log in again.</string>
796+
<string name="no_application_available_to_open_gpx_files">No application available to open GPX files</string>
797+
<string name="file_saved_successfully">File Saved Successfully</string>
798+
<string name="do_you_want_to_open_gpx_file">Do you want to open GPX file?</string>
799+
<string name="do_you_want_to_open_kml_file">Do you want to open KML file?</string>
800+
<string name="failed_to_save_kml_file">Failed to save KML file.</string>
801+
<string name="failed_to_save_gpx_file">Failed to save GPX file.</string>
802+
<string name="saving_kml_file">Saving KML File</string>
803+
<string name="saving_gpx_file">Saving GPX File</string>
796804
<plurals name="custom_picker_images_selected_title_appendix">
797805
<item quantity="one">%d image selected</item>
798806
<item quantity="other">%d images selected</item>

0 commit comments

Comments
 (0)