Fixes 1848 : Option for adding location for those pictures which have no location (#4755)

* Location wizard

* Location wizard

* Minor fix

* message changed

* Test fail fixed

* Test fail fixed

* Test fail fixed

* last location triggered

* last location added

* Some test added

* Java docs added

* More java docs added
This commit is contained in:
Ayan Sarkar 2022-02-05 06:26:59 +05:30 committed by GitHub
parent 587ff3b54f
commit e135fea20d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 161 additions and 44 deletions

View file

@ -6,6 +6,7 @@ import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION;
import android.content.Intent;
import android.graphics.BitmapFactory;
@ -49,13 +50,17 @@ import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import fr.free.nrw.commons.theme.BaseActivity;
import javax.inject.Inject;
import javax.inject.Named;
import org.jetbrains.annotations.NotNull;
import timber.log.Timber;
/**
* Helps to pick location and return the result with an intent
*/
public class LocationPickerActivity extends AppCompatActivity implements OnMapReadyCallback,
public class LocationPickerActivity extends BaseActivity implements OnMapReadyCallback,
OnCameraMoveStartedListener, OnCameraIdleListener, Observer<CameraPosition> {
/**
@ -114,6 +119,13 @@ public class LocationPickerActivity extends AppCompatActivity implements OnMapRe
* smallToolbarText : textView of shadow
*/
private TextView smallToolbarText;
/**
* applicationKvStore : for storing values
*/
@Inject
@Named("default_preferences")
public
JsonKvStore applicationKvStore;
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
@ -365,6 +377,12 @@ public class LocationPickerActivity extends AppCompatActivity implements OnMapRe
* Return the intent with required data
*/
void placeSelected() {
if (activity.equals("NoLocationUploadActivity")) {
applicationKvStore.putString(LAST_LOCATION,
mapboxMap.getCameraPosition().target.getLatitude()
+ ","
+ mapboxMap.getCameraPosition().target.getLongitude());
}
final Intent returningIntent = new Intent();
returningIntent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION,
mapboxMap.getCameraPosition());

View file

@ -3,6 +3,7 @@ package fr.free.nrw.commons.di;
import dagger.Module;
import dagger.android.ContributesAndroidInjector;
import fr.free.nrw.commons.AboutActivity;
import fr.free.nrw.commons.LocationPicker.LocationPickerActivity;
import fr.free.nrw.commons.WelcomeActivity;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.auth.SignupActivity;
@ -44,6 +45,9 @@ public abstract class ActivityBuilderModule {
@ContributesAndroidInjector
abstract AboutActivity bindAboutActivity();
@ContributesAndroidInjector
abstract LocationPickerActivity bindLocationPickerActivity();
@ContributesAndroidInjector
abstract SignupActivity bindSignupActivity();

View file

@ -44,6 +44,7 @@ import fr.free.nrw.commons.utils.ImageUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.lang3.StringUtils;
@ -53,6 +54,12 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
UploadMediaDetailsContract.View, UploadMediaDetailAdapter.EventListener {
private static final int REQUEST_CODE = 1211;
/**
* A key for applicationKvStore.
* By this key we can retrieve the location of last UploadItem ex. 12.3433,54.78897
* from applicationKvStore.
*/
public static final String LAST_LOCATION = "last_location_while_uploading";
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.ib_map)
@ -397,10 +404,6 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
() -> {}, true);
}
@Override public void showMapWithImageCoordinates(boolean shouldShow) {
ibMap.setVisibility(shouldShow ? View.VISIBLE : View.GONE);
}
@Override
public void showExternalMap(final UploadItem uploadItem) {
goToLocationPickerActivity(uploadItem);
@ -414,14 +417,36 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
private void goToLocationPickerActivity(final UploadItem uploadItem) {
editableUploadItem = uploadItem;
startActivityForResult(new LocationPicker.IntentBuilder()
.defaultLocation(new CameraPosition.Builder()
.target(new com.mapbox.mapboxsdk.geometry.LatLng(uploadItem.getGpsCoords()
.getDecLatitude(),
uploadItem.getGpsCoords().getDecLongitude()))
.zoom(16).build())
.activityKey("UploadActivity")
.build(getActivity()), REQUEST_CODE);
double defaultLatitude = 37.773972;
double defaultLongitude = -122.431297;
if (uploadItem.getGpsCoords()
.getDecLatitude() != 0.0 && uploadItem.getGpsCoords().getDecLongitude() != 0.0) {
defaultLatitude = uploadItem.getGpsCoords()
.getDecLatitude();
defaultLongitude = uploadItem.getGpsCoords().getDecLongitude();
startActivityForResult(new LocationPicker.IntentBuilder()
.defaultLocation(new CameraPosition.Builder()
.target(
new com.mapbox.mapboxsdk.geometry.LatLng(defaultLatitude, defaultLongitude))
.zoom(16).build())
.activityKey("UploadActivity")
.build(getActivity()), REQUEST_CODE);
} else {
if (defaultKvStore.getString(LAST_LOCATION) != null) {
final String[] locationLatLng
= defaultKvStore.getString(LAST_LOCATION).split(",");
defaultLatitude = Double.parseDouble(locationLatLng[0]);
defaultLongitude = Double.parseDouble(locationLatLng[1]);
}
startActivityForResult(new LocationPicker.IntentBuilder()
.defaultLocation(new CameraPosition.Builder()
.target(
new com.mapbox.mapboxsdk.geometry.LatLng(defaultLatitude, defaultLongitude))
.zoom(16).build())
.activityKey("NoLocationUploadActivity")
.build(getActivity()), REQUEST_CODE);
}
}
/**
@ -470,6 +495,22 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
uploadMediaDetailAdapter.setItems(uploadMediaDetails);
}
/**
* Showing dialog for adding location
*
* @param onSkipClicked proceed for verifying image quality
*/
@Override
public void displayAddLocationDialog(final Runnable onSkipClicked) {
DialogUtil.showAlertDialog(Objects.requireNonNull(getActivity()),
getString(R.string.no_location_found_title),
getString(R.string.no_location_found_message),
getString(R.string.add_location),
getString(R.string.skip_login),
this::onIbMapClicked,
onSkipClicked);
}
private void deleteThisPicture() {
callback.deletePictureAtIndex(callback.getIndexInViewFlipper(this));
}

View file

@ -34,11 +34,11 @@ public interface UploadMediaDetailsContract {
void showConnectionErrorPopup();
void showMapWithImageCoordinates(boolean shouldShow);
void showExternalMap(UploadItem uploadItem);
void updateMediaDetails(List<UploadMediaDetail> uploadMediaDetails);
void displayAddLocationDialog(Runnable runnable);
}
interface UserActionListener extends BasePresenter<View> {

View file

@ -114,7 +114,6 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
final ImageCoordinates gpsCoords = uploadItem.getGpsCoords();
final boolean hasImageCoordinates =
gpsCoords != null && gpsCoords.getImageCoordsExists();
view.showMapWithImageCoordinates(hasImageCoordinates);
view.showProgress(false);
if (hasImageCoordinates && place == null) {
checkNearbyPlaces(uploadItem);
@ -169,28 +168,54 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
*/
@Override
public void verifyImageQuality(int uploadItemIndex) {
view.showProgress(true);
final UploadItem uploadItem = repository.getUploads().get(uploadItemIndex);
compositeDisposable.add(
repository
.getImageQuality(uploadItem)
.observeOn(mainThreadScheduler)
.subscribe(imageResult -> {
view.showProgress(false);
handleImageResult(imageResult, uploadItem);
},
throwable -> {
view.showProgress(false);
if (throwable instanceof UnknownHostException) {
if (uploadItem.getGpsCoords().getDecimalCoords() == null) {
final Runnable onSkipClicked = () -> {
view.showProgress(true);
compositeDisposable.add(
repository
.getImageQuality(uploadItem)
.observeOn(mainThreadScheduler)
.subscribe(imageResult -> {
view.showProgress(false);
handleImageResult(imageResult, uploadItem);
},
throwable -> {
view.showProgress(false);
if (throwable instanceof UnknownHostException) {
view.showConnectionErrorPopup();
} else {
view.showMessage("" + throwable.getLocalizedMessage(),
R.color.color_error);
}
Timber.e(throwable, "Error occurred while handling image");
})
);
};
view.displayAddLocationDialog(onSkipClicked);
} else {
view.showProgress(true);
compositeDisposable.add(
repository
.getImageQuality(uploadItem)
.observeOn(mainThreadScheduler)
.subscribe(imageResult -> {
view.showProgress(false);
handleImageResult(imageResult, uploadItem);
},
throwable -> {
view.showProgress(false);
if (throwable instanceof UnknownHostException) {
view.showConnectionErrorPopup();
} else {
} else {
view.showMessage("" + throwable.getLocalizedMessage(),
R.color.color_error);
}
Timber.e(throwable, "Error occurred while handling image");
})
);
}
Timber.e(throwable, "Error occurred while handling image");
})
);
}
}