From 771f370f9a3e34d17d29c2b0d39e89d380d4e311 Mon Sep 17 00:00:00 2001 From: Saifuddin Adenwala Date: Mon, 2 Dec 2024 13:24:26 +0530 Subject: [PATCH] Migration of locationpicker module from Java to Kotlin (#5981) * Rename .java to .kt * Migrated location picker module from Java to Kotlin --- .../LocationPicker/LocationPicker.java | 77 -- .../commons/LocationPicker/LocationPicker.kt | 72 ++ .../LocationPickerActivity.java | 681 ------------------ .../LocationPicker/LocationPickerActivity.kt | 678 +++++++++++++++++ .../LocationPickerConstants.java | 20 - .../LocationPicker/LocationPickerConstants.kt | 13 + .../LocationPickerViewModel.java | 63 -- .../LocationPicker/LocationPickerViewModel.kt | 44 ++ 8 files changed, 807 insertions(+), 841 deletions(-) delete mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.java create mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java create mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.java create mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.java create mode 100644 app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.kt diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.java b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.java deleted file mode 100644 index 58801c499..000000000 --- a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.java +++ /dev/null @@ -1,77 +0,0 @@ -package fr.free.nrw.commons.LocationPicker; - -import android.app.Activity; -import android.content.Intent; -import fr.free.nrw.commons.CameraPosition; -import fr.free.nrw.commons.Media; - -/** - * Helper class for starting the activity - */ -public final class LocationPicker { - - /** - * Getting camera position from the intent using constants - * - * @param data intent - * @return CameraPosition - */ - public static CameraPosition getCameraPosition(final Intent data) { - return data.getParcelableExtra(LocationPickerConstants.MAP_CAMERA_POSITION); - } - - public static class IntentBuilder { - - private final Intent intent; - - /** - * Creates a new builder that creates an intent to launch the place picker activity. - */ - public IntentBuilder() { - intent = new Intent(); - } - - /** - * Gets and puts location in intent - * @param position CameraPosition - * @return LocationPicker.IntentBuilder - */ - public LocationPicker.IntentBuilder defaultLocation( - final CameraPosition position) { - intent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION, position); - return this; - } - - /** - * Gets and puts activity name in intent - * @param activity activity key - * @return LocationPicker.IntentBuilder - */ - public LocationPicker.IntentBuilder activityKey( - final String activity) { - intent.putExtra(LocationPickerConstants.ACTIVITY_KEY, activity); - return this; - } - - /** - * Gets and puts media in intent - * @param media Media - * @return LocationPicker.IntentBuilder - */ - public LocationPicker.IntentBuilder media( - final Media media) { - intent.putExtra(LocationPickerConstants.MEDIA, media); - return this; - } - - /** - * Gets and sets the activity - * @param activity Activity - * @return Intent - */ - public Intent build(final Activity activity) { - intent.setClass(activity, LocationPickerActivity.class); - return intent; - } - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.kt b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.kt new file mode 100644 index 000000000..0bab50201 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPicker.kt @@ -0,0 +1,72 @@ +package fr.free.nrw.commons.LocationPicker + +import android.app.Activity +import android.content.Intent +import fr.free.nrw.commons.CameraPosition +import fr.free.nrw.commons.Media + + +/** + * Helper class for starting the activity + */ +object LocationPicker { + + /** + * Getting camera position from the intent using constants + * + * @param data intent + * @return CameraPosition + */ + @JvmStatic + fun getCameraPosition(data: Intent): CameraPosition? { + return data.getParcelableExtra(LocationPickerConstants.MAP_CAMERA_POSITION) + } + + class IntentBuilder + /** + * Creates a new builder that creates an intent to launch the place picker activity. + */() { + + private val intent: Intent = Intent() + + /** + * Gets and puts location in intent + * @param position CameraPosition + * @return LocationPicker.IntentBuilder + */ + fun defaultLocation(position: CameraPosition): IntentBuilder { + intent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION, position) + return this + } + + /** + * Gets and puts activity name in intent + * @param activity activity key + * @return LocationPicker.IntentBuilder + */ + fun activityKey(activity: String): IntentBuilder { + intent.putExtra(LocationPickerConstants.ACTIVITY_KEY, activity) + return this + } + + /** + * Gets and puts media in intent + * @param media Media + * @return LocationPicker.IntentBuilder + */ + fun media(media: Media): IntentBuilder { + intent.putExtra(LocationPickerConstants.MEDIA, media) + return this + } + + /** + * Gets and sets the activity + * @param activity Activity + * @return Intent + */ + fun build(activity: Activity): Intent { + intent.setClass(activity, LocationPickerActivity::class.java) + return intent + } + } +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java deleted file mode 100644 index 40f360a24..000000000 --- a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java +++ /dev/null @@ -1,681 +0,0 @@ -package fr.free.nrw.commons.LocationPicker; - -import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION; -import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_ZOOM; -import static fr.free.nrw.commons.utils.MapUtils.ZOOM_LEVEL; - -import android.Manifest.permission; -import android.annotation.SuppressLint; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.drawable.Drawable; -import android.location.LocationManager; -import android.os.Bundle; -import android.preference.PreferenceManager; -import android.text.Html; -import android.text.method.LinkMovementMethod; -import android.view.MotionEvent; -import android.view.View; -import android.view.Window; -import android.view.animation.OvershootInterpolator; -import android.widget.Button; -import android.widget.ImageView; -import android.widget.TextView; -import android.widget.Toast; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.app.ActionBar; -import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.AppCompatTextView; -import androidx.constraintlayout.widget.ConstraintLayout; -import androidx.core.app.ActivityCompat; -import androidx.core.content.ContextCompat; -import com.google.android.material.floatingactionbutton.FloatingActionButton; -import fr.free.nrw.commons.CameraPosition; -import fr.free.nrw.commons.CommonsApplication; -import fr.free.nrw.commons.Media; -import fr.free.nrw.commons.R; -import fr.free.nrw.commons.Utils; -import fr.free.nrw.commons.auth.SessionManager; -import fr.free.nrw.commons.auth.csrf.CsrfTokenClient; -import fr.free.nrw.commons.coordinates.CoordinateEditHelper; -import fr.free.nrw.commons.filepicker.Constants; -import fr.free.nrw.commons.kvstore.BasicKvStore; -import fr.free.nrw.commons.kvstore.JsonKvStore; -import fr.free.nrw.commons.location.LocationPermissionsHelper; -import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermissionCallback; -import fr.free.nrw.commons.location.LocationServiceManager; -import fr.free.nrw.commons.theme.BaseActivity; -import fr.free.nrw.commons.utils.DialogUtil; -import fr.free.nrw.commons.utils.SystemThemeUtils; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.schedulers.Schedulers; -import java.util.List; -import java.util.Locale; -import javax.inject.Inject; -import javax.inject.Named; -import org.osmdroid.tileprovider.tilesource.TileSourceFactory; -import org.osmdroid.util.GeoPoint; -import org.osmdroid.util.constants.GeoConstants; -import org.osmdroid.views.CustomZoomButtonsController; -import org.osmdroid.views.overlay.Marker; -import org.osmdroid.views.overlay.Overlay; -import org.osmdroid.views.overlay.ScaleDiskOverlay; -import org.osmdroid.views.overlay.TilesOverlay; -import timber.log.Timber; - -/** - * Helps to pick location and return the result with an intent - */ -public class LocationPickerActivity extends BaseActivity implements - LocationPermissionCallback { - /** - * coordinateEditHelper: helps to edit coordinates - */ - @Inject - CoordinateEditHelper coordinateEditHelper; - /** - * media : Media object - */ - private Media media; - /** - * cameraPosition : position of picker - */ - private CameraPosition cameraPosition; - /** - * markerImage : picker image - */ - private ImageView markerImage; - /** - * mapView : OSM Map - */ - private org.osmdroid.views.MapView mapView; - /** - * tvAttribution : credit - */ - private AppCompatTextView tvAttribution; - /** - * activity : activity key - */ - private String activity; - /** - * modifyLocationButton : button for start editing location - */ - Button modifyLocationButton; - /** - * removeLocationButton : button to remove location metadata - */ - Button removeLocationButton; - /** - * showInMapButton : button for showing in map - */ - TextView showInMapButton; - /** - * placeSelectedButton : fab for selecting location - */ - FloatingActionButton placeSelectedButton; - /** - * fabCenterOnLocation: button for center on location; - */ - FloatingActionButton fabCenterOnLocation; - /** - * shadow : imageview of shadow - */ - private ImageView shadow; - /** - * largeToolbarText : textView of shadow - */ - private TextView largeToolbarText; - /** - * smallToolbarText : textView of shadow - */ - private TextView smallToolbarText; - /** - * applicationKvStore : for storing values - */ - @Inject - @Named("default_preferences") - public - JsonKvStore applicationKvStore; - BasicKvStore store; - /** - * isDarkTheme: for keeping a track of the device theme and modifying the map theme accordingly - */ - @Inject - SystemThemeUtils systemThemeUtils; - private boolean isDarkTheme; - private boolean moveToCurrentLocation; - - @Inject - LocationServiceManager locationManager; - LocationPermissionsHelper locationPermissionsHelper; - - @Inject - SessionManager sessionManager; - - /** - * Constants - */ - private static final String CAMERA_POS = "cameraPosition"; - private static final String ACTIVITY = "activity"; - - - @SuppressLint("ClickableViewAccessibility") - @Override - protected void onCreate(@Nullable final Bundle savedInstanceState) { - getWindow().requestFeature(Window.FEATURE_ACTION_BAR); - super.onCreate(savedInstanceState); - - isDarkTheme = systemThemeUtils.isDeviceInNightMode(); - moveToCurrentLocation = false; - store = new BasicKvStore(this, "LocationPermissions"); - - getWindow().requestFeature(Window.FEATURE_ACTION_BAR); - final ActionBar actionBar = getSupportActionBar(); - if (actionBar != null) { - actionBar.hide(); - } - setContentView(R.layout.activity_location_picker); - - if (savedInstanceState == null) { - cameraPosition = getIntent() - .getParcelableExtra(LocationPickerConstants.MAP_CAMERA_POSITION); - activity = getIntent().getStringExtra(LocationPickerConstants.ACTIVITY_KEY); - media = getIntent().getParcelableExtra(LocationPickerConstants.MEDIA); - }else{ - cameraPosition = savedInstanceState.getParcelable(CAMERA_POS); - activity = savedInstanceState.getString(ACTIVITY); - media = savedInstanceState.getParcelable("sMedia"); - } - bindViews(); - addBackButtonListener(); - addPlaceSelectedButton(); - addCredits(); - getToolbarUI(); - addCenterOnGPSButton(); - - org.osmdroid.config.Configuration.getInstance().load(getApplicationContext(), - PreferenceManager.getDefaultSharedPreferences(getApplicationContext())); - - mapView.setTileSource(TileSourceFactory.WIKIMEDIA); - mapView.setTilesScaledToDpi(true); - mapView.setMultiTouchControls(true); - - org.osmdroid.config.Configuration.getInstance().getAdditionalHttpRequestProperties().put( - "Referer", "http://maps.wikimedia.org/" - ); - mapView.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER); - mapView.getController().setZoom(ZOOM_LEVEL); - mapView.setOnTouchListener((v, event) -> { - if (event.getAction() == MotionEvent.ACTION_MOVE) { - if (markerImage.getTranslationY() == 0) { - markerImage.animate().translationY(-75) - .setInterpolator(new OvershootInterpolator()).setDuration(250).start(); - } - } else if (event.getAction() == MotionEvent.ACTION_UP) { - markerImage.animate().translationY(0) - .setInterpolator(new OvershootInterpolator()).setDuration(250).start(); - } - return false; - }); - - if ("UploadActivity".equals(activity)) { - placeSelectedButton.setVisibility(View.GONE); - modifyLocationButton.setVisibility(View.VISIBLE); - removeLocationButton.setVisibility(View.VISIBLE); - showInMapButton.setVisibility(View.VISIBLE); - largeToolbarText.setText(getResources().getString(R.string.image_location)); - smallToolbarText.setText(getResources(). - getString(R.string.check_whether_location_is_correct)); - fabCenterOnLocation.setVisibility(View.GONE); - markerImage.setVisibility(View.GONE); - shadow.setVisibility(View.GONE); - assert cameraPosition != null; - showSelectedLocationMarker(new GeoPoint(cameraPosition.getLatitude(), - cameraPosition.getLongitude())); - } - setupMapView(); - } - - /** - * Moves the center of the map to the specified coordinates - * - */ - private void moveMapTo(double latitude, double longitude){ - if(mapView != null && mapView.getController() != null){ - GeoPoint point = new GeoPoint(latitude, longitude); - - mapView.getController().setCenter(point); - mapView.getController().animateTo(point); - } - } - - /** - * Moves the center of the map to the specified coordinates - * @param point The GeoPoint object which contains the coordinates to move to - */ - private void moveMapTo(GeoPoint point){ - if(point != null){ - moveMapTo(point.getLatitude(), point.getLongitude()); - } - } - - /** - * For showing credits - */ - private void addCredits() { - tvAttribution.setText(Html.fromHtml(getString(R.string.map_attribution))); - tvAttribution.setMovementMethod(LinkMovementMethod.getInstance()); - } - - /** - * For setting up Dark Theme - */ - private void darkThemeSetup() { - if (isDarkTheme) { - shadow.setColorFilter(Color.argb(255, 255, 255, 255)); - mapView.getOverlayManager().getTilesOverlay() - .setColorFilter(TilesOverlay.INVERT_COLORS); - } - } - - /** - * Clicking back button destroy locationPickerActivity - */ - private void addBackButtonListener() { - final ImageView backButton = findViewById(R.id.maplibre_place_picker_toolbar_back_button); - backButton.setOnClickListener(v -> { - finish(); - }); - - } - - /** - * Binds mapView and location picker icon - */ - private void bindViews() { - mapView = findViewById(R.id.map_view); - markerImage = findViewById(R.id.location_picker_image_view_marker); - tvAttribution = findViewById(R.id.tv_attribution); - modifyLocationButton = findViewById(R.id.modify_location); - removeLocationButton = findViewById(R.id.remove_location); - showInMapButton = findViewById(R.id.show_in_map); - showInMapButton.setText(getResources().getString(R.string.show_in_map_app).toUpperCase( - Locale.ROOT)); - shadow = findViewById(R.id.location_picker_image_view_shadow); - } - - /** - * Gets toolbar color - */ - private void getToolbarUI() { - final ConstraintLayout toolbar = findViewById(R.id.location_picker_toolbar); - largeToolbarText = findViewById(R.id.location_picker_toolbar_primary_text_view); - smallToolbarText = findViewById(R.id.location_picker_toolbar_secondary_text_view); - toolbar.setBackgroundColor(getResources().getColor(R.color.primaryColor)); - } - - private void setupMapView() { - requestLocationPermissions(); - - //If location metadata is available, move map to that location. - if(activity.equals("UploadActivity") || activity.equals("MediaActivity")){ - moveMapToMediaLocation(); - } else { - //If location metadata is not available, move map to device GPS location. - moveMapToGPSLocation(); - } - - modifyLocationButton.setOnClickListener(v -> onClickModifyLocation()); - removeLocationButton.setOnClickListener(v -> onClickRemoveLocation()); - showInMapButton.setOnClickListener(v -> showInMapApp()); - darkThemeSetup(); - } - - /** - * Handles onclick event of modifyLocationButton - */ - private void onClickModifyLocation() { - placeSelectedButton.setVisibility(View.VISIBLE); - modifyLocationButton.setVisibility(View.GONE); - removeLocationButton.setVisibility(View.GONE); - showInMapButton.setVisibility(View.GONE); - markerImage.setVisibility(View.VISIBLE); - shadow.setVisibility(View.VISIBLE); - largeToolbarText.setText(getResources().getString(R.string.choose_a_location)); - smallToolbarText.setText(getResources().getString(R.string.pan_and_zoom_to_adjust)); - fabCenterOnLocation.setVisibility(View.VISIBLE); - removeSelectedLocationMarker(); - moveMapToMediaLocation(); - } - - /** - * Handles onclick event of removeLocationButton - */ - private void onClickRemoveLocation() { - DialogUtil.showAlertDialog(this, - getString(R.string.remove_location_warning_title), - getString(R.string.remove_location_warning_desc), - getString(R.string.continue_message), - getString(R.string.cancel), () -> removeLocationFromImage(), null); - } - - /** - * Method to remove the location from the picture - */ - private void removeLocationFromImage() { - if (media != null) { - getCompositeDisposable().add(coordinateEditHelper.makeCoordinatesEdit(getApplicationContext() - , media, "0.0", "0.0", "0.0f") - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(s -> { - Timber.d("Coordinates are removed from the image"); - })); - } - final Intent returningIntent = new Intent(); - setResult(AppCompatActivity.RESULT_OK, returningIntent); - finish(); - } - - /** - * Show the location in map app. Map will center on the location metadata, if available. - * If there is no location metadata, the map will center on the commons app map center. - */ - private void showInMapApp() { - fr.free.nrw.commons.location.LatLng position = null; - - if(activity.equals("UploadActivity") && cameraPosition != null){ - //location metadata is available - position = new fr.free.nrw.commons.location.LatLng(cameraPosition.getLatitude(), - cameraPosition.getLongitude(), 0.0f); - } else if(mapView != null){ - //location metadata is not available - position = new fr.free.nrw.commons.location.LatLng(mapView.getMapCenter().getLatitude(), - mapView.getMapCenter().getLongitude(), 0.0f); - } - - if(position != null){ - Utils.handleGeoCoordinates(this, position); - } - } - - /** - * Moves the center of the map to the media's location, if that data - * is available. - */ - private void moveMapToMediaLocation() { - if (cameraPosition != null) { - - GeoPoint point = new GeoPoint(cameraPosition.getLatitude(), - cameraPosition.getLongitude()); - - moveMapTo(point); - } - } - - /** - * Moves the center of the map to the device's GPS location, if that data is available. - */ - private void moveMapToGPSLocation(){ - if(locationManager != null){ - fr.free.nrw.commons.location.LatLng location = locationManager.getLastLocation(); - - if(location != null){ - GeoPoint point = new GeoPoint(location.getLatitude(), location.getLongitude()); - - moveMapTo(point); - } - } - } - - /** - * Select the preferable location - */ - private void addPlaceSelectedButton() { - placeSelectedButton = findViewById(R.id.location_chosen_button); - placeSelectedButton.setOnClickListener(view -> placeSelected()); - } - - /** - * Return the intent with required data - */ - void placeSelected() { - if (activity.equals("NoLocationUploadActivity")) { - applicationKvStore.putString(LAST_LOCATION, - mapView.getMapCenter().getLatitude() - + "," - + mapView.getMapCenter().getLongitude()); - applicationKvStore.putString(LAST_ZOOM, mapView.getZoomLevel() + ""); - } - - if (media == null) { - final Intent returningIntent = new Intent(); - returningIntent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION, - new CameraPosition(mapView.getMapCenter().getLatitude(), - mapView.getMapCenter().getLongitude(), 14.0)); - setResult(AppCompatActivity.RESULT_OK, returningIntent); - } else { - updateCoordinates(String.valueOf(mapView.getMapCenter().getLatitude()), - String.valueOf(mapView.getMapCenter().getLongitude()), - String.valueOf(0.0f)); - } - - finish(); - } - - /** - * Fetched coordinates are replaced with existing coordinates by a POST API call. - * @param Latitude to be added - * @param Longitude to be added - * @param Accuracy to be added - */ - public void updateCoordinates(final String Latitude, final String Longitude, - final String Accuracy) { - if (media == null) { - return; - } - - try { - getCompositeDisposable().add( - coordinateEditHelper.makeCoordinatesEdit(getApplicationContext(), media, - Latitude, Longitude, Accuracy) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(s -> { - Timber.d("Coordinates are added."); - })); - } catch (Exception e) { - if (e.getLocalizedMessage().equals(CsrfTokenClient.ANONYMOUS_TOKEN_MESSAGE)) { - final String username = sessionManager.getUserName(); - final CommonsApplication.BaseLogoutListener logoutListener = new CommonsApplication.BaseLogoutListener( - this, - getString(R.string.invalid_login_message), - username - ); - - CommonsApplication.getInstance().clearApplicationData( - this, logoutListener); - } - } - } - - /** - * Center the camera on the last saved location - */ - private void addCenterOnGPSButton() { - fabCenterOnLocation = findViewById(R.id.center_on_gps); - fabCenterOnLocation.setOnClickListener(view -> { - moveToCurrentLocation = true; - requestLocationPermissions(); - }); - } - - /** - * Adds selected location marker on the map - */ - private void showSelectedLocationMarker(GeoPoint point) { - Drawable icon = ContextCompat.getDrawable(this, R.drawable.map_default_map_marker); - Marker marker = new Marker(mapView); - marker.setPosition(point); - marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM); - marker.setIcon(icon); - marker.setInfoWindow(null); - mapView.getOverlays().add(marker); - mapView.invalidate(); - } - - /** - * Removes selected location marker from the map - */ - private void removeSelectedLocationMarker() { - List overlays = mapView.getOverlays(); - for (int i = 0; i < overlays.size(); i++) { - if (overlays.get(i) instanceof Marker) { - Marker item = (Marker) overlays.get(i); - if (cameraPosition.getLatitude() == item.getPosition().getLatitude() - && cameraPosition.getLongitude() == item.getPosition().getLongitude()) { - mapView.getOverlays().remove(i); - mapView.invalidate(); - break; - } - } - } - } - - /** - * Center the map at user's current location - */ - private void requestLocationPermissions() { - locationPermissionsHelper = new LocationPermissionsHelper( - this, locationManager, this); - locationPermissionsHelper.requestForLocationAccess(R.string.location_permission_title, - R.string.upload_map_location_access); - } - - @Override - public void onRequestPermissionsResult(final int requestCode, - @NonNull final String[] permissions, - @NonNull final int[] grantResults) { - if (requestCode == Constants.RequestCodes.LOCATION - && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - onLocationPermissionGranted(); - } else { - onLocationPermissionDenied(getString(R.string.upload_map_location_access)); - } - super.onRequestPermissionsResult(requestCode, permissions, grantResults); - } - - @Override - protected void onResume() { - super.onResume(); - mapView.onResume(); - } - - @Override - protected void onPause() { - super.onPause(); - mapView.onPause(); - } - - @Override - public void onLocationPermissionDenied(String toastMessage) { - if (!ActivityCompat.shouldShowRequestPermissionRationale(this, - permission.ACCESS_FINE_LOCATION)) { - if (!locationPermissionsHelper.checkLocationPermission(this)) { - if (store.getBoolean("isPermissionDenied", false)) { - // means user has denied location permission twice or checked the "Don't show again" - locationPermissionsHelper.showAppSettingsDialog(this, - R.string.upload_map_location_access); - } else { - Toast.makeText(getBaseContext(), toastMessage, Toast.LENGTH_LONG).show(); - } - store.putBoolean("isPermissionDenied", true); - } - } else { - Toast.makeText(getBaseContext(), toastMessage, Toast.LENGTH_LONG).show(); - } - } - - @Override - public void onLocationPermissionGranted() { - if (moveToCurrentLocation || !(activity.equals("MediaActivity"))) { - if (locationPermissionsHelper.isLocationAccessToAppsTurnedOn()) { - locationManager.requestLocationUpdatesFromProvider( - LocationManager.NETWORK_PROVIDER); - locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER); - addMarkerAtGPSLocation(); - } else { - addMarkerAtGPSLocation(); - locationPermissionsHelper.showLocationOffDialog(this, - R.string.ask_to_turn_location_on_text); - } - } - } - - /** - * Adds a marker to the map at the most recent GPS location - * (which may be the current GPS location). - */ - private void addMarkerAtGPSLocation() { - fr.free.nrw.commons.location.LatLng currLocation = locationManager.getLastLocation(); - if (currLocation != null) { - GeoPoint currLocationGeopoint = new GeoPoint(currLocation.getLatitude(), - currLocation.getLongitude()); - addLocationMarker(currLocationGeopoint); - markerImage.setTranslationY(0); - } - } - - private void addLocationMarker(GeoPoint geoPoint) { - if (moveToCurrentLocation) { - mapView.getOverlays().clear(); - } - ScaleDiskOverlay diskOverlay = - new ScaleDiskOverlay(this, - geoPoint, 2000, GeoConstants.UnitOfMeasure.foot); - Paint circlePaint = new Paint(); - circlePaint.setColor(Color.rgb(128, 128, 128)); - circlePaint.setStyle(Paint.Style.STROKE); - circlePaint.setStrokeWidth(2f); - diskOverlay.setCirclePaint2(circlePaint); - Paint diskPaint = new Paint(); - diskPaint.setColor(Color.argb(40, 128, 128, 128)); - diskPaint.setStyle(Paint.Style.FILL_AND_STROKE); - diskOverlay.setCirclePaint1(diskPaint); - diskOverlay.setDisplaySizeMin(900); - diskOverlay.setDisplaySizeMax(1700); - mapView.getOverlays().add(diskOverlay); - org.osmdroid.views.overlay.Marker startMarker = new org.osmdroid.views.overlay.Marker( - mapView); - startMarker.setPosition(geoPoint); - startMarker.setAnchor(org.osmdroid.views.overlay.Marker.ANCHOR_CENTER, - org.osmdroid.views.overlay.Marker.ANCHOR_BOTTOM); - startMarker.setIcon( - ContextCompat.getDrawable(this, R.drawable.current_location_marker)); - startMarker.setTitle("Your Location"); - startMarker.setTextLabelFontSize(24); - mapView.getOverlays().add(startMarker); - } - - /** - * Saves the state of the activity - * @param outState Bundle - */ - @Override - public void onSaveInstanceState(@NonNull final Bundle outState) { - super.onSaveInstanceState(outState); - if(cameraPosition!=null){ - outState.putParcelable(CAMERA_POS, cameraPosition); - } - if(activity!=null){ - outState.putString(ACTIVITY, activity); - } - - if(media!=null){ - outState.putParcelable("sMedia", media); - } - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.kt b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.kt new file mode 100644 index 000000000..6508c4f25 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.kt @@ -0,0 +1,678 @@ +package fr.free.nrw.commons.LocationPicker + +import android.Manifest.permission +import android.annotation.SuppressLint +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Color +import android.graphics.Paint +import android.location.LocationManager +import android.os.Bundle +import android.preference.PreferenceManager +import android.text.Html +import android.text.method.LinkMovementMethod +import android.view.MotionEvent +import android.view.View +import android.view.Window +import android.view.animation.OvershootInterpolator +import android.widget.Button +import android.widget.ImageView +import android.widget.TextView +import android.widget.Toast +import androidx.appcompat.widget.AppCompatTextView +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.app.ActivityCompat +import androidx.core.content.ContextCompat +import com.google.android.material.floatingactionbutton.FloatingActionButton +import fr.free.nrw.commons.CameraPosition +import fr.free.nrw.commons.CommonsApplication +import fr.free.nrw.commons.Media +import fr.free.nrw.commons.R +import fr.free.nrw.commons.Utils +import fr.free.nrw.commons.auth.SessionManager +import fr.free.nrw.commons.auth.csrf.CsrfTokenClient +import fr.free.nrw.commons.coordinates.CoordinateEditHelper +import fr.free.nrw.commons.filepicker.Constants +import fr.free.nrw.commons.kvstore.BasicKvStore +import fr.free.nrw.commons.kvstore.JsonKvStore +import fr.free.nrw.commons.location.LocationPermissionsHelper +import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermissionCallback +import fr.free.nrw.commons.location.LocationServiceManager +import fr.free.nrw.commons.theme.BaseActivity +import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION +import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_ZOOM +import fr.free.nrw.commons.utils.DialogUtil +import fr.free.nrw.commons.utils.MapUtils.ZOOM_LEVEL +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.schedulers.Schedulers +import org.osmdroid.tileprovider.tilesource.TileSourceFactory +import org.osmdroid.util.GeoPoint +import org.osmdroid.util.constants.GeoConstants +import org.osmdroid.views.CustomZoomButtonsController +import org.osmdroid.views.overlay.Marker +import org.osmdroid.views.overlay.ScaleDiskOverlay +import org.osmdroid.views.overlay.TilesOverlay +import timber.log.Timber +import java.util.Locale +import javax.inject.Inject +import javax.inject.Named + + +/** + * Helps to pick location and return the result with an intent + */ +class LocationPickerActivity : BaseActivity(), LocationPermissionCallback { + /** + * coordinateEditHelper: helps to edit coordinates + */ + @Inject + lateinit var coordinateEditHelper: CoordinateEditHelper + + /** + * media : Media object + */ + private var media: Media? = null + + /** + * cameraPosition : position of picker + */ + private var cameraPosition: CameraPosition? = null + + /** + * markerImage : picker image + */ + private lateinit var markerImage: ImageView + + /** + * mapView : OSM Map + */ + private var mapView: org.osmdroid.views.MapView? = null + + /** + * tvAttribution : credit + */ + private lateinit var tvAttribution: AppCompatTextView + + /** + * activity : activity key + */ + private var activity: String? = null + + /** + * modifyLocationButton : button for start editing location + */ + private lateinit var modifyLocationButton: Button + + /** + * removeLocationButton : button to remove location metadata + */ + private lateinit var removeLocationButton: Button + + /** + * showInMapButton : button for showing in map + */ + private lateinit var showInMapButton: TextView + + /** + * placeSelectedButton : fab for selecting location + */ + private lateinit var placeSelectedButton: FloatingActionButton + + /** + * fabCenterOnLocation: button for center on location; + */ + private lateinit var fabCenterOnLocation: FloatingActionButton + + /** + * shadow : imageview of shadow + */ + private lateinit var shadow: ImageView + + /** + * largeToolbarText : textView of shadow + */ + private lateinit var largeToolbarText: TextView + + /** + * smallToolbarText : textView of shadow + */ + private lateinit var smallToolbarText: TextView + + /** + * applicationKvStore : for storing values + */ + @Inject + @field: Named("default_preferences") + lateinit var applicationKvStore: JsonKvStore + private lateinit var store: BasicKvStore + + /** + * isDarkTheme: for keeping a track of the device theme and modifying the map theme accordingly + */ + private var isDarkTheme: Boolean = false + private var moveToCurrentLocation: Boolean = false + + @Inject + lateinit var locationManager: LocationServiceManager + private lateinit var locationPermissionsHelper: LocationPermissionsHelper + + @Inject + lateinit var sessionManager: SessionManager + + /** + * Constants + */ + companion object { + private const val CAMERA_POS = "cameraPosition" + private const val ACTIVITY = "activity" + } + + @SuppressLint("ClickableViewAccessibility") + override fun onCreate(savedInstanceState: Bundle?) { + requestWindowFeature(Window.FEATURE_ACTION_BAR) + super.onCreate(savedInstanceState) + + isDarkTheme = systemThemeUtils.isDeviceInNightMode() + moveToCurrentLocation = false + store = BasicKvStore(this, "LocationPermissions") + + requestWindowFeature(Window.FEATURE_ACTION_BAR) + supportActionBar?.hide() + setContentView(R.layout.activity_location_picker) + + if (savedInstanceState == null) { + cameraPosition = intent.getParcelableExtra(LocationPickerConstants.MAP_CAMERA_POSITION) + activity = intent.getStringExtra(LocationPickerConstants.ACTIVITY_KEY) + media = intent.getParcelableExtra(LocationPickerConstants.MEDIA) + } else { + cameraPosition = savedInstanceState.getParcelable(CAMERA_POS) + activity = savedInstanceState.getString(ACTIVITY) + media = savedInstanceState.getParcelable("sMedia") + } + + bindViews() + addBackButtonListener() + addPlaceSelectedButton() + addCredits() + getToolbarUI() + addCenterOnGPSButton() + + org.osmdroid.config.Configuration.getInstance() + .load( + applicationContext, PreferenceManager.getDefaultSharedPreferences( + applicationContext + ) + ) + + mapView?.setTileSource(TileSourceFactory.WIKIMEDIA) + mapView?.setTilesScaledToDpi(true) + mapView?.setMultiTouchControls(true) + + org.osmdroid.config.Configuration.getInstance().additionalHttpRequestProperties["Referer"] = + "http://maps.wikimedia.org/" + mapView?.zoomController?.setVisibility(CustomZoomButtonsController.Visibility.NEVER) + mapView?.controller?.setZoom(ZOOM_LEVEL.toDouble()) + mapView?.setOnTouchListener { _, event -> + when (event.action) { + MotionEvent.ACTION_MOVE -> { + if (markerImage.translationY == 0f) { + markerImage.animate().translationY(-75f) + .setInterpolator(OvershootInterpolator()).duration = 250 + } + } + MotionEvent.ACTION_UP -> { + markerImage.animate().translationY(0f) + .setInterpolator(OvershootInterpolator()).duration = 250 + } + } + false + } + + if (activity == "UploadActivity") { + placeSelectedButton.visibility = View.GONE + modifyLocationButton.visibility = View.VISIBLE + removeLocationButton.visibility = View.VISIBLE + showInMapButton.visibility = View.VISIBLE + largeToolbarText.text = getString(R.string.image_location) + smallToolbarText.text = getString(R.string.check_whether_location_is_correct) + fabCenterOnLocation.visibility = View.GONE + markerImage.visibility = View.GONE + shadow.visibility = View.GONE + cameraPosition?.let { + showSelectedLocationMarker(GeoPoint(it.latitude, it.longitude)) + } + } + setupMapView() + } + + /** + * Moves the center of the map to the specified coordinates + */ + private fun moveMapTo(latitude: Double, longitude: Double) { + mapView?.controller?.let { + val point = GeoPoint(latitude, longitude) + it.setCenter(point) + it.animateTo(point) + } + } + + /** + * Moves the center of the map to the specified coordinates + * @param point The GeoPoint object which contains the coordinates to move to + */ + private fun moveMapTo(point: GeoPoint?) { + point?.let { + moveMapTo(it.latitude, it.longitude) + } + } + + /** + * For showing credits + */ + private fun addCredits() { + tvAttribution.text = Html.fromHtml(getString(R.string.map_attribution)) + tvAttribution.movementMethod = LinkMovementMethod.getInstance() + } + + /** + * For setting up Dark Theme + */ + private fun darkThemeSetup() { + if (isDarkTheme) { + shadow.setColorFilter(Color.argb(255, 255, 255, 255)) + mapView?.overlayManager?.tilesOverlay?.setColorFilter(TilesOverlay.INVERT_COLORS) + } + } + + /** + * Clicking back button destroy locationPickerActivity + */ + private fun addBackButtonListener() { + val backButton = findViewById(R.id.maplibre_place_picker_toolbar_back_button) + backButton.setOnClickListener { + finish() + } + } + + /** + * Binds mapView and location picker icon + */ + private fun bindViews() { + mapView = findViewById(R.id.map_view) + markerImage = findViewById(R.id.location_picker_image_view_marker) + tvAttribution = findViewById(R.id.tv_attribution) + modifyLocationButton = findViewById(R.id.modify_location) + removeLocationButton = findViewById(R.id.remove_location) + showInMapButton = findViewById(R.id.show_in_map) + showInMapButton.text = getString(R.string.show_in_map_app).uppercase(Locale.ROOT) + shadow = findViewById(R.id.location_picker_image_view_shadow) + } + + /** + * Gets toolbar color + */ + private fun getToolbarUI() { + val toolbar: ConstraintLayout = findViewById(R.id.location_picker_toolbar) + largeToolbarText = findViewById(R.id.location_picker_toolbar_primary_text_view) + smallToolbarText = findViewById(R.id.location_picker_toolbar_secondary_text_view) + toolbar.setBackgroundColor(ContextCompat.getColor(this, R.color.primaryColor)) + } + + private fun setupMapView() { + requestLocationPermissions() + + //If location metadata is available, move map to that location. + if (activity == "UploadActivity" || activity == "MediaActivity") { + moveMapToMediaLocation() + } else { + //If location metadata is not available, move map to device GPS location. + moveMapToGPSLocation() + } + + modifyLocationButton.setOnClickListener { onClickModifyLocation() } + removeLocationButton.setOnClickListener { onClickRemoveLocation() } + showInMapButton.setOnClickListener { showInMapApp() } + darkThemeSetup() + } + + /** + * Handles onClick event of modifyLocationButton + */ + private fun onClickModifyLocation() { + placeSelectedButton.visibility = View.VISIBLE + modifyLocationButton.visibility = View.GONE + removeLocationButton.visibility = View.GONE + showInMapButton.visibility = View.GONE + markerImage.visibility = View.VISIBLE + shadow.visibility = View.VISIBLE + largeToolbarText.text = getString(R.string.choose_a_location) + smallToolbarText.text = getString(R.string.pan_and_zoom_to_adjust) + fabCenterOnLocation.visibility = View.VISIBLE + removeSelectedLocationMarker() + moveMapToMediaLocation() + } + + /** + * Handles onClick event of removeLocationButton + */ + private fun onClickRemoveLocation() { + DialogUtil.showAlertDialog( + this, + getString(R.string.remove_location_warning_title), + getString(R.string.remove_location_warning_desc), + getString(R.string.continue_message), + getString(R.string.cancel), + { removeLocationFromImage() }, + null + ) + } + + /** + * Removes location metadata from the image + */ + private fun removeLocationFromImage() { + media?.let { + compositeDisposable.add( + coordinateEditHelper.makeCoordinatesEdit( + applicationContext, it, "0.0", "0.0", "0.0f" + ) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { _ -> + Timber.d("Coordinates removed from the image") + } + ) + } + setResult(RESULT_OK, Intent()) + finish() + } + + /** + * Show location in map app + */ + private fun showInMapApp() { + val position = when { + //location metadata is available + activity == "UploadActivity" && cameraPosition != null -> { + fr.free.nrw.commons.location.LatLng(cameraPosition!!.latitude, cameraPosition!!.longitude, 0.0f) + } + //location metadata is not available + mapView != null -> { + fr.free.nrw.commons.location.LatLng( + mapView?.mapCenter?.latitude!!, + mapView?.mapCenter?.longitude!!, + 0.0f + ) + } + else -> null + } + + position?.let { Utils.handleGeoCoordinates(this, it) } + } + + /** + * Moves map to media's location + */ + private fun moveMapToMediaLocation() { + cameraPosition?.let { + moveMapTo(GeoPoint(it.latitude, it.longitude)) + } + } + + /** + * Moves map to GPS location + */ + private fun moveMapToGPSLocation() { + locationManager.lastLocation?.let { + moveMapTo(GeoPoint(it.latitude, it.longitude)) + } + } + + /** + * Adds "Place Selected" button + */ + private fun addPlaceSelectedButton() { + placeSelectedButton = findViewById(R.id.location_chosen_button) + placeSelectedButton.setOnClickListener { placeSelected() } + } + + /** + * Handles "Place Selected" action + */ + private fun placeSelected() { + if (activity == "NoLocationUploadActivity") { + applicationKvStore.putString( + LAST_LOCATION, + "${mapView?.mapCenter?.latitude},${mapView?.mapCenter?.longitude}" + ) + applicationKvStore.putString(LAST_ZOOM, mapView?.zoomLevel?.toString()!!) + } + + if (media == null) { + val intent = Intent().apply { + putExtra( + LocationPickerConstants.MAP_CAMERA_POSITION, + CameraPosition(mapView?.mapCenter?.latitude!!, mapView?.mapCenter?.longitude!!, 14.0) + ) + } + setResult(RESULT_OK, intent) + } else { + updateCoordinates( + mapView?.mapCenter?.latitude.toString(), + mapView?.mapCenter?.longitude.toString(), + "0.0f" + ) + } + + finish() + } + + /** + * Updates image with new coordinates + */ + fun updateCoordinates(latitude: String, longitude: String, accuracy: String) { + media?.let { + try { + compositeDisposable.add( + coordinateEditHelper.makeCoordinatesEdit( + applicationContext, + it, + latitude, + longitude, + accuracy + ).subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe { _ -> + Timber.d("Coordinates updated") + } + ) + } catch (e: Exception) { + if (e.localizedMessage == CsrfTokenClient.ANONYMOUS_TOKEN_MESSAGE) { + val username = sessionManager.userName + CommonsApplication.BaseLogoutListener( + this, + getString(R.string.invalid_login_message) + , username + ).let { + CommonsApplication.instance.clearApplicationData(this, it) + } + } else { } + } + } + } + + /** + * Adds a button to center the map at user's location + */ + private fun addCenterOnGPSButton() { + fabCenterOnLocation = findViewById(R.id.center_on_gps) + fabCenterOnLocation.setOnClickListener { + moveToCurrentLocation = true + requestLocationPermissions() + } + } + + /** + * Shows a selected location marker + */ + private fun showSelectedLocationMarker(point: GeoPoint) { + val icon = ContextCompat.getDrawable(this, R.drawable.map_default_map_marker) + Marker(mapView).apply { + position = point + setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM) + setIcon(icon) + infoWindow = null + mapView?.overlays?.add(this) + } + mapView?.invalidate() + } + + /** + * Removes selected location marker + */ + private fun removeSelectedLocationMarker() { + val overlays = mapView?.overlays + overlays?.filterIsInstance()?.firstOrNull { + it.position.latitude == + cameraPosition?.latitude && it.position.longitude == cameraPosition?.longitude + }?.let { + overlays.remove(it) + mapView?.invalidate() + } + } + + /** + * Centers map at user's location + */ + private fun requestLocationPermissions() { + locationPermissionsHelper = LocationPermissionsHelper(this, locationManager, this) + locationPermissionsHelper.requestForLocationAccess( + R.string.location_permission_title, + R.string.upload_map_location_access + ) + } + + override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) { + if (requestCode == Constants.RequestCodes.LOCATION && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + onLocationPermissionGranted() + } else { + onLocationPermissionDenied(getString(R.string.upload_map_location_access)) + } + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + } + + override fun onResume() { + super.onResume() + mapView?.onResume() + } + + override fun onPause() { + super.onPause() + mapView?.onPause() + } + + override fun onLocationPermissionDenied(toastMessage: String) { + val isDeniedBefore = store.getBoolean("isPermissionDenied", false) + val showRationale = ActivityCompat.shouldShowRequestPermissionRationale(this, permission.ACCESS_FINE_LOCATION) + + if (!showRationale) { + if (!locationPermissionsHelper.checkLocationPermission(this)) { + if (isDeniedBefore) { + locationPermissionsHelper.showAppSettingsDialog(this, R.string.upload_map_location_access) + } else { + Toast.makeText(this, toastMessage, Toast.LENGTH_LONG).show() + } + store.putBoolean("isPermissionDenied", true) + } + } else { + Toast.makeText(this, toastMessage, Toast.LENGTH_LONG).show() + } + } + + override fun onLocationPermissionGranted() { + if (moveToCurrentLocation || activity != "MediaActivity") { + if (locationPermissionsHelper.isLocationAccessToAppsTurnedOn) { + locationManager.requestLocationUpdatesFromProvider(LocationManager.NETWORK_PROVIDER) + locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER) + addMarkerAtGPSLocation() + } else { + addMarkerAtGPSLocation() + locationPermissionsHelper.showLocationOffDialog(this, R.string.ask_to_turn_location_on_text) + } + } + } + + /** + * Adds a marker at the user's GPS location + */ + private fun addMarkerAtGPSLocation() { + locationManager.lastLocation?.let { + addLocationMarker(GeoPoint(it.latitude, it.longitude)) + markerImage.translationY = 0f + } + } + + private fun addLocationMarker(geoPoint: GeoPoint) { + if (moveToCurrentLocation) { + mapView?.overlays?.clear() + } + + val diskOverlay = ScaleDiskOverlay( + this, + geoPoint, + 2000, + GeoConstants.UnitOfMeasure.foot + ) + + val circlePaint = Paint().apply { + color = Color.rgb(128, 128, 128) + style = Paint.Style.STROKE + strokeWidth = 2f + } + diskOverlay.setCirclePaint2(circlePaint) + + val diskPaint = Paint().apply { + color = Color.argb(40, 128, 128, 128) + style = Paint.Style.FILL_AND_STROKE + } + diskOverlay.setCirclePaint1(diskPaint) + + diskOverlay.setDisplaySizeMin(900) + diskOverlay.setDisplaySizeMax(1700) + + mapView?.overlays?.add(diskOverlay) + + val startMarker = Marker(mapView).apply { + position = geoPoint + setAnchor( + Marker.ANCHOR_CENTER, + Marker.ANCHOR_BOTTOM + ) + icon = ContextCompat.getDrawable(this@LocationPickerActivity, R.drawable.current_location_marker) + title = "Your Location" + textLabelFontSize = 24 + } + + mapView?.overlays?.add(startMarker) + } + + /** + * Saves the state of the activity + * @param outState Bundle + */ + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + + cameraPosition?.let { + outState.putParcelable(CAMERA_POS, it) + } + + activity?.let { + outState.putString(ACTIVITY, it) + } + + media?.let { + outState.putParcelable("sMedia", it) + } + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.java b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.java deleted file mode 100644 index 060a15c88..000000000 --- a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.java +++ /dev/null @@ -1,20 +0,0 @@ -package fr.free.nrw.commons.LocationPicker; - -/** - * Constants need for location picking - */ -public final class LocationPickerConstants { - - public static final String ACTIVITY_KEY - = "location.picker.activity"; - - public static final String MAP_CAMERA_POSITION - = "location.picker.cameraPosition"; - - public static final String MEDIA - = "location.picker.media"; - - - private LocationPickerConstants() { - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.kt b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.kt new file mode 100644 index 000000000..a1c9d989a --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerConstants.kt @@ -0,0 +1,13 @@ +package fr.free.nrw.commons.LocationPicker + +/** + * Constants need for location picking + */ +object LocationPickerConstants { + + const val ACTIVITY_KEY = "location.picker.activity" + + const val MAP_CAMERA_POSITION = "location.picker.cameraPosition" + + const val MEDIA = "location.picker.media" +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.java b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.java deleted file mode 100644 index 57bb238d2..000000000 --- a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.java +++ /dev/null @@ -1,63 +0,0 @@ -package fr.free.nrw.commons.LocationPicker; - -import android.app.Application; -import androidx.annotation.NonNull; -import androidx.lifecycle.AndroidViewModel; -import androidx.lifecycle.MutableLiveData; -import fr.free.nrw.commons.CameraPosition; -import org.jetbrains.annotations.NotNull; -import retrofit2.Call; -import retrofit2.Callback; -import retrofit2.Response; -import timber.log.Timber; - -/** - * Observes live camera position data - */ -public class LocationPickerViewModel extends AndroidViewModel implements Callback { - - /** - * Wrapping CameraPosition with MutableLiveData - */ - private final MutableLiveData result = new MutableLiveData<>(); - - /** - * Constructor for this class - * - * @param application Application - */ - public LocationPickerViewModel(@NonNull final Application application) { - super(application); - } - - /** - * Responses on camera position changing - * - * @param call Call - * @param response Response - */ - @Override - public void onResponse(final @NotNull Call call, - final Response response) { - if (response.body() == null) { - result.setValue(null); - return; - } - result.setValue(response.body()); - } - - @Override - public void onFailure(final @NotNull Call call, final @NotNull Throwable t) { - Timber.e(t); - } - - /** - * Gets live CameraPosition - * - * @return MutableLiveData - */ - public MutableLiveData getResult() { - return result; - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.kt b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.kt new file mode 100644 index 000000000..b0b2ce6de --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerViewModel.kt @@ -0,0 +1,44 @@ +package fr.free.nrw.commons.LocationPicker + +import android.app.Application +import androidx.lifecycle.AndroidViewModel +import androidx.lifecycle.MutableLiveData +import fr.free.nrw.commons.CameraPosition +import retrofit2.Call +import retrofit2.Callback +import retrofit2.Response +import timber.log.Timber + +/** + * Observes live camera position data + */ +class LocationPickerViewModel( + application: Application +): AndroidViewModel(application), Callback { + + /** + * Wrapping CameraPosition with MutableLiveData + */ + val result = MutableLiveData() + + /** + * Responses on camera position changing + * + * @param call Call + * @param response Response + */ + override fun onResponse( + call: Call, + response: Response + ) { + if(response.body() == null) { + result.value = null + return + } + result.value = response.body() + } + + override fun onFailure(call: Call, t: Throwable) { + Timber.e(t) + } +} \ No newline at end of file