[GSoC] Image Selection (#4457)
* Localisation updates from https://translatewiki.net.
* Fixes #4357 After switching to different account, contributions screen shows pictures of previous account (#4421)
* Update UploadMediaDetailFragment.java
* Update LoginActivity.java
Clear CompositeDisposable after logging in successfully. It may help solve the problem of saving the contribution to the previous account
* Revert "Update UploadMediaDetailFragment.java"
This reverts commit b1b4257f20.
Co-authored-by: Obsidian_zero <1198474846@qq.com>
* Remove unnecessary whitespace from a message (#4439)
* Merge v3.0.1 into master (#4446)
* Versioning and changelog for v3.0.0 (#4152)
* Versioning for v3.0.0
* Update changelog.md
* Handled migration 8-9-10 in BookmarksLocationDao (#4154)
* #Fixes #4141
- Handled migrations for BookmarkLocationsDao from 8-9-10
* #Fixes #4141
- Handled migrations for BookmarkLocationsDao from 8-9-10
* Fixes #4179 (#4180)
* Handled null pointer exception in MainActivity->ContributionsFragment#backButtonClicked()
* Updated >ContributionsFragment#backButtonClicked() to handle back press properly
* Fixes #4179 (#4181)
* Handled possible null check on MediaDetails in BookmarkListRootFragment#backPressed()
* Cherrypick for hotfix3.1 (#4205)
* Fixes #4159 On Explore Tab, All Available Options on toolbar in media detail view are only targeting the first media in the list.
Fixes #4159 On Explore Tab, All Available Options on toolbar in media detail view are only targeting the first media in the list.
* fixed bug: App crashes on viewing review in Review Fragment #4132 (#4146)
* fixed bug:app crashes on viewing review in Review Fragment #4135
* Fixed the issue with back button in contribution tab. (#4177)
Co-authored-by: Pratham2305 <Pratham2305@users.noreply.github.com>
* Fixed the issue with back navigation button on toolbar in explore tab. (#4175)
* Fix (#4148) Issues on theme change
* fixed themeChange crashes
* fixed comments
* Overlooked the title bar
Co-authored-by: Pratham Pahariya <54663429+Pratham2305@users.noreply.github.com>
Co-authored-by: Shabir Ahmad <56585337+shabar-shab@users.noreply.github.com>
Co-authored-by: Pratham2305 <Pratham2305@users.noreply.github.com>
Co-authored-by: Aditya-Srivastav <54016427+4D17Y4@users.noreply.github.com>
* Fixes #4173 (#4396)
* Fix #4147 Pre-fill desc in Nearby uploads with Wikidata item's label + description (#4390)
* Update query to fetch descriptions
* Make description added to NearbyResultItem
* Make string operations to display description and label in a combined way
* Fix reviews, remove long description from list and swap label and description texts
* Fix repeated information issue
* Fix double information issue
* fix style issues
* Remove douplicated information
* Changes made (#4354)
* Remove nonexistent method
* Fix #4283 IllegalStateException (#4440)
* Fix #4283 IllegalStateException
* Fix flickering issue
* Versioning for v3.0.1
* Update changelog.md
Co-authored-by: Ashish <ashishkumar468@gmail.com>
Co-authored-by: neslihanturan <tur.neslihan@gmail.com>
Co-authored-by: Pratham Pahariya <54663429+Pratham2305@users.noreply.github.com>
Co-authored-by: Shabir Ahmad <56585337+shabar-shab@users.noreply.github.com>
Co-authored-by: Pratham2305 <Pratham2305@users.noreply.github.com>
Co-authored-by: Aditya-Srivastav <54016427+4D17Y4@users.noreply.github.com>
Co-authored-by: Madhur Gupta <30932899+madhurgupta10@users.noreply.github.com>
Co-authored-by: Vinayak Aggarwal <56196007+vinayak0505@users.noreply.github.com>
* Localisation updates from https://translatewiki.net.
* Added basic Fetch
* added permission request
* Folder count rectified
* Loaded thumbnail
* disabled overlay
* Added sha1 function
* Documented the code
* Added a feature for editing coordinates (#4418)
* not
* Place Picker added
* Pick location and API call linked
* minor warnings resolved
* Code conventions followed
* issue fixed
* Wikitext edited properly
* minor modification
* Location Picker added
* Bottom sheet removed
* Location picker fully implemented
* credit added
* credit added
* issues fixed
* issues fixed
* minor issue fixed
* Some build issues occured merging release v3.0 are fixed. One paranthesis issue is solved, a method about UploadService is removed, since we don't use it anymore. (#4451)
* Localisation updates from https://translatewiki.net.
* Fixes 4344 - Duplicate Uploads (#4442)
* Fixes 4344
- Update the retention policy of the Work Manager to ExistingWorkPolicy.APPEND_OR_REPLACE- which would append the new work to the end of existing one. This helps remove the while loop in UploadWorker which was meant to handle the cases where a new worker would be created for retries. The while loop seemed to have race conditions uploading duplicate entries.
* Update states to IN_PROGRESS before uploads are processed
* Image selection added
* Forwarded activity result to upload wizard
* Initialised xmls, made folder and image item.
* xmls done
* xmls completed
* removed unwanted attribute
* Created models, adapters and view models (#4441)
* created models, adapters and view models
* Added Image Fragment
* back button linked
* Documentation and refractor
* spaces
* Butterknife annotation
* DiffUtil
* Added Examples
* Extended Custom selector From Base Activity
* made view model injectable
* Added basic Fetch
* added permission request
* Folder count rectified
* Loaded thumbnail
* disabled overlay
* Added sha1 function
* Documented the code
* Image selection added
* Forwarded activity result to upload wizard
* [GSOC] Added Image Fetch (#4449)
* Added basic Fetch
* added permission request
* Folder count rectified
* Loaded thumbnail
* disabled overlay
* Added sha1 function
* Documented the code
* fixed merge errors
* Documented the remaining function
Co-authored-by: translatewiki.net <l10n-bot@translatewiki.net>
Co-authored-by: obsidian-zero <63155026+obsidian-zero@users.noreply.github.com>
Co-authored-by: Obsidian_zero <1198474846@qq.com>
Co-authored-by: Amir E. Aharoni <amir.aharoni@mail.huji.ac.il>
Co-authored-by: Josephine Lim <josephinelim86@gmail.com>
Co-authored-by: Ashish <ashishkumar468@gmail.com>
Co-authored-by: neslihanturan <tur.neslihan@gmail.com>
Co-authored-by: Pratham Pahariya <54663429+Pratham2305@users.noreply.github.com>
Co-authored-by: Shabir Ahmad <56585337+shabar-shab@users.noreply.github.com>
Co-authored-by: Pratham2305 <Pratham2305@users.noreply.github.com>
Co-authored-by: Madhur Gupta <30932899+madhurgupta10@users.noreply.github.com>
Co-authored-by: Vinayak Aggarwal <56196007+vinayak0505@users.noreply.github.com>
Co-authored-by: Ayan Sarkar <71203077+Ayan-10@users.noreply.github.com>
|
|
@ -1,5 +1,10 @@
|
||||||
# Wikimedia Commons for Android
|
# Wikimedia Commons for Android
|
||||||
|
|
||||||
|
## v3.0.1
|
||||||
|
- Pre-fill desc in Nearby uploads with Wikidata item's label + description
|
||||||
|
- Improved ACRA crash reporting
|
||||||
|
- Fixed various crashes
|
||||||
|
|
||||||
## v3.0.0
|
## v3.0.0
|
||||||
- Added Structured Data to upload workflow, users can now add depicts
|
- Added Structured Data to upload workflow, users can now add depicts
|
||||||
- Added Leaderboard in Achievements screen
|
- Added Leaderboard in Achievements screen
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ dependencies {
|
||||||
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
|
implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
|
||||||
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
implementation 'com.github.chrisbanes:PhotoView:2.0.0'
|
||||||
implementation 'com.github.pedrovgs:renderers:3.3.3'
|
implementation 'com.github.pedrovgs:renderers:3.3.3'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:8.6.2'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-sdk:9.1.0'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-localization-v8:0.11.0'
|
||||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
|
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-scalebar-v9:0.4.0'
|
||||||
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
|
implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
|
||||||
|
|
@ -58,8 +58,8 @@ dependencies {
|
||||||
implementation "com.squareup.okhttp3:okhttp-ws:$OKHTTP_VERSION"
|
implementation "com.squareup.okhttp3:okhttp-ws:$OKHTTP_VERSION"
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation 'ch.acra:acra-dialog:5.3.0'
|
implementation 'ch.acra:acra-dialog:5.8.1-beta11'
|
||||||
implementation 'ch.acra:acra-mail:5.3.0'
|
implementation 'ch.acra:acra-mail:5.8.1-beta11'
|
||||||
implementation 'org.slf4j:slf4j-api:1.7.25'
|
implementation 'org.slf4j:slf4j-api:1.7.25'
|
||||||
api('com.github.tony19:logback-android-classic:1.1.1-6') {
|
api('com.github.tony19:logback-android-classic:1.1.1-6') {
|
||||||
exclude group: 'com.google.android', module: 'android'
|
exclude group: 'com.google.android', module: 'android'
|
||||||
|
|
@ -153,8 +153,9 @@ android {
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
//applicationId 'fr.free.nrw.commons'
|
//applicationId 'fr.free.nrw.commons'
|
||||||
versionCode 876
|
|
||||||
versionName '3.0.0'
|
versionCode 1016
|
||||||
|
versionName '3.0.1'
|
||||||
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName())
|
||||||
|
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,10 @@
|
||||||
android:name=".review.ReviewActivity"
|
android:name=".review.ReviewActivity"
|
||||||
android:label="@string/title_activity_review" />
|
android:label="@string/title_activity_review" />
|
||||||
|
|
||||||
|
<activity
|
||||||
|
android:name=".LocationPicker.LocationPickerActivity"
|
||||||
|
android:label="Location Picker" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".auth.WikiAccountAuthenticatorService"
|
android:name=".auth.WikiAccountAuthenticatorService"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,8 @@ import timber.log.Timber;
|
||||||
)
|
)
|
||||||
|
|
||||||
@AcraMailSender(
|
@AcraMailSender(
|
||||||
mailTo = "commons-app-android-private@googlegroups.com"
|
mailTo = "commons-app-android-private@googlegroups.com",
|
||||||
|
reportAsFile = false
|
||||||
)
|
)
|
||||||
|
|
||||||
@AcraDialog(
|
@AcraDialog(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
package fr.free.nrw.commons.LocationPicker;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 sets the activity
|
||||||
|
* @param activity Activity
|
||||||
|
* @return Intent
|
||||||
|
*/
|
||||||
|
public Intent build(final Activity activity) {
|
||||||
|
intent.setClass(activity, LocationPickerActivity.class);
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,288 @@
|
||||||
|
package fr.free.nrw.commons.LocationPicker;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.method.LinkMovementMethod;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.animation.OvershootInterpolator;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
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.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.mapbox.android.core.permissions.PermissionsManager;
|
||||||
|
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||||
|
import com.mapbox.mapboxsdk.camera.CameraPosition.Builder;
|
||||||
|
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||||
|
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||||
|
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||||
|
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||||
|
import com.mapbox.mapboxsdk.location.modes.CameraMode;
|
||||||
|
import com.mapbox.mapboxsdk.location.modes.RenderMode;
|
||||||
|
import com.mapbox.mapboxsdk.maps.MapView;
|
||||||
|
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||||
|
import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener;
|
||||||
|
import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener;
|
||||||
|
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||||
|
import com.mapbox.mapboxsdk.maps.Style;
|
||||||
|
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||||
|
import fr.free.nrw.commons.R;
|
||||||
|
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,
|
||||||
|
OnCameraMoveStartedListener, OnCameraIdleListener, Observer<CameraPosition> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cameraPosition : position of picker
|
||||||
|
*/
|
||||||
|
private CameraPosition cameraPosition;
|
||||||
|
/**
|
||||||
|
* markerImage : picker image
|
||||||
|
*/
|
||||||
|
private ImageView markerImage;
|
||||||
|
/**
|
||||||
|
* mapboxMap : map
|
||||||
|
*/
|
||||||
|
private MapboxMap mapboxMap;
|
||||||
|
/**
|
||||||
|
* mapView : view of the map
|
||||||
|
*/
|
||||||
|
private MapView mapView;
|
||||||
|
/**
|
||||||
|
* tvAttribution : credit
|
||||||
|
*/
|
||||||
|
private AppCompatTextView tvAttribution;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
final LocationPickerViewModel viewModel = new ViewModelProvider(this)
|
||||||
|
.get(LocationPickerViewModel.class);
|
||||||
|
viewModel.getResult().observe(this, this);
|
||||||
|
|
||||||
|
bindViews();
|
||||||
|
addBackButtonListener();
|
||||||
|
addPlaceSelectedButton();
|
||||||
|
addCredits();
|
||||||
|
getToolbarUI();
|
||||||
|
|
||||||
|
mapView.onCreate(savedInstanceState);
|
||||||
|
mapView.getMapAsync(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For showing credits
|
||||||
|
*/
|
||||||
|
private void addCredits() {
|
||||||
|
tvAttribution.setText(Html.fromHtml(getString(R.string.map_attribution)));
|
||||||
|
tvAttribution.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clicking back button destroy locationPickerActivity
|
||||||
|
*/
|
||||||
|
private void addBackButtonListener() {
|
||||||
|
final ImageView backButton = findViewById(R.id.mapbox_place_picker_toolbar_back_button);
|
||||||
|
backButton.setOnClickListener(view -> 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the listeners
|
||||||
|
*/
|
||||||
|
private void bindListeners() {
|
||||||
|
mapboxMap.addOnCameraMoveStartedListener(
|
||||||
|
this);
|
||||||
|
mapboxMap.addOnCameraIdleListener(
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets toolbar color
|
||||||
|
*/
|
||||||
|
private void getToolbarUI() {
|
||||||
|
final ConstraintLayout toolbar = findViewById(R.id.location_picker_toolbar);
|
||||||
|
toolbar.setBackgroundColor(getResources().getColor(R.color.primaryColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes action when map is ready to show
|
||||||
|
* @param mapboxMap map
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onMapReady(final MapboxMap mapboxMap) {
|
||||||
|
this.mapboxMap = mapboxMap;
|
||||||
|
mapboxMap.setStyle(Style.MAPBOX_STREETS, style -> {
|
||||||
|
adjustCameraBasedOnOptions();
|
||||||
|
bindListeners();
|
||||||
|
enableLocationComponent(style);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* move the location to the current media coordinates
|
||||||
|
*/
|
||||||
|
private void adjustCameraBasedOnOptions() {
|
||||||
|
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables location components
|
||||||
|
* @param loadedMapStyle Style
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( {"MissingPermission"})
|
||||||
|
private void enableLocationComponent(@NonNull final Style loadedMapStyle) {
|
||||||
|
final UiSettings uiSettings = mapboxMap.getUiSettings();
|
||||||
|
uiSettings.setAttributionEnabled(false);
|
||||||
|
|
||||||
|
// Check if permissions are enabled and if not request
|
||||||
|
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||||
|
|
||||||
|
// Get an instance of the component
|
||||||
|
final LocationComponent locationComponent = mapboxMap.getLocationComponent();
|
||||||
|
|
||||||
|
// Activate with options
|
||||||
|
locationComponent.activateLocationComponent(
|
||||||
|
LocationComponentActivationOptions.builder(this, loadedMapStyle).build());
|
||||||
|
|
||||||
|
// Enable to make component visible
|
||||||
|
locationComponent.setLocationComponentEnabled(true);
|
||||||
|
|
||||||
|
// Set the component's camera mode
|
||||||
|
locationComponent.setCameraMode(CameraMode.NONE);
|
||||||
|
|
||||||
|
// Set the component's render mode
|
||||||
|
locationComponent.setRenderMode(RenderMode.NORMAL);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acts on camera moving
|
||||||
|
* @param reason int
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onCameraMoveStarted(final int reason) {
|
||||||
|
Timber.v("Map camera has begun moving.");
|
||||||
|
if (markerImage.getTranslationY() == 0) {
|
||||||
|
markerImage.animate().translationY(-75)
|
||||||
|
.setInterpolator(new OvershootInterpolator()).setDuration(250).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acts on camera idle
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onCameraIdle() {
|
||||||
|
Timber.v("Map camera is now idling.");
|
||||||
|
markerImage.animate().translationY(0)
|
||||||
|
.setInterpolator(new OvershootInterpolator()).setDuration(250).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes action on camera position
|
||||||
|
* @param position position of picker
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onChanged(@Nullable CameraPosition position) {
|
||||||
|
if (position == null) {
|
||||||
|
position = new Builder()
|
||||||
|
.target(new LatLng(mapboxMap.getCameraPosition().target.getLatitude(),
|
||||||
|
mapboxMap.getCameraPosition().target.getLongitude()))
|
||||||
|
.zoom(16).build();
|
||||||
|
}
|
||||||
|
cameraPosition = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select the preferable location
|
||||||
|
*/
|
||||||
|
private void addPlaceSelectedButton() {
|
||||||
|
final FloatingActionButton placeSelectedButton = findViewById(R.id.location_chosen_button);
|
||||||
|
placeSelectedButton.setOnClickListener(view -> placeSelected());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the intent with required data
|
||||||
|
*/
|
||||||
|
void placeSelected() {
|
||||||
|
final Intent returningIntent = new Intent();
|
||||||
|
returningIntent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION,
|
||||||
|
mapboxMap.getCameraPosition());
|
||||||
|
setResult(AppCompatActivity.RESULT_OK, returningIntent);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
mapView.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
mapView.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
mapView.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
mapView.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(final @NotNull Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
mapView.onSaveInstanceState(outState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
mapView.onDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLowMemory() {
|
||||||
|
super.onLowMemory();
|
||||||
|
mapView.onLowMemory();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
package fr.free.nrw.commons.LocationPicker;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants need for location picking
|
||||||
|
*/
|
||||||
|
public final class LocationPickerConstants {
|
||||||
|
|
||||||
|
public static final String MAP_CAMERA_POSITION
|
||||||
|
= "location.picker.cameraPosition";
|
||||||
|
|
||||||
|
private LocationPickerConstants() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,60 @@
|
||||||
|
package fr.free.nrw.commons.LocationPicker;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.AndroidViewModel;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import com.mapbox.mapboxsdk.camera.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<CameraPosition> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapping CameraPosition with MutableLiveData
|
||||||
|
*/
|
||||||
|
private final MutableLiveData<CameraPosition> 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<CameraPosition>
|
||||||
|
* @param response Response<CameraPosition>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onResponse(final @NotNull Call<CameraPosition> call,
|
||||||
|
final Response<CameraPosition> response) {
|
||||||
|
if(response.body()==null){
|
||||||
|
result.setValue(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
result.setValue(response.body());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(final @NotNull Call<CameraPosition> call, final @NotNull Throwable t) {
|
||||||
|
Timber.e(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets live CameraPosition
|
||||||
|
* @return MutableLiveData<CameraPosition>
|
||||||
|
*/
|
||||||
|
public MutableLiveData<CameraPosition> getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -74,7 +74,7 @@ class Media constructor(
|
||||||
* Gets the coordinates of where the file was created.
|
* Gets the coordinates of where the file was created.
|
||||||
* @return file coordinates as a LatLng
|
* @return file coordinates as a LatLng
|
||||||
*/
|
*/
|
||||||
val coordinates: LatLng? = null,
|
var coordinates: LatLng? = null,
|
||||||
val captions: Map<String, String> = emptyMap(),
|
val captions: Map<String, String> = emptyMap(),
|
||||||
val descriptions: Map<String, String> = emptyMap(),
|
val descriptions: Map<String, String> = emptyMap(),
|
||||||
val depictionIds: List<String> = emptyList()
|
val depictionIds: List<String> = emptyList()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package fr.free.nrw.commons.actions
|
package fr.free.nrw.commons.actions
|
||||||
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.Single
|
||||||
import org.wikipedia.csrf.CsrfTokenClient
|
import org.wikipedia.csrf.CsrfTokenClient
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -62,4 +63,15 @@ class PageEditClient(
|
||||||
Observable.just(false)
|
Observable.just(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whole WikiText of required file
|
||||||
|
* @param title : Name of the file
|
||||||
|
* @return Observable<MwQueryResult>
|
||||||
|
*/
|
||||||
|
fun getCurrentWikiText(title: String): Single<String?> {
|
||||||
|
return pageEditInterface.getWikiText(title).map {
|
||||||
|
it.query()?.pages()?.get(0)?.revisions()?.get(0)?.content()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
package fr.free.nrw.commons.actions
|
package fr.free.nrw.commons.actions
|
||||||
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import io.reactivex.Single
|
||||||
import org.wikipedia.dataclient.Service
|
import org.wikipedia.dataclient.Service
|
||||||
|
import org.wikipedia.dataclient.mwapi.MwQueryResponse
|
||||||
import org.wikipedia.edit.Edit
|
import org.wikipedia.edit.Edit
|
||||||
import retrofit2.http.Field
|
import retrofit2.http.*
|
||||||
import retrofit2.http.FormUrlEncoded
|
|
||||||
import retrofit2.http.Headers
|
|
||||||
import retrofit2.http.POST
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface facilitates wiki commons page editing services to the Networking module
|
* This interface facilitates wiki commons page editing services to the Networking module
|
||||||
|
|
@ -73,4 +72,17 @@ interface PageEditInterface {
|
||||||
@Field("prependtext") prependText: String,
|
@Field("prependtext") prependText: String,
|
||||||
@Field("token") token: String
|
@Field("token") token: String
|
||||||
): Observable<Edit>
|
): Observable<Edit>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get wiki text for provided file names
|
||||||
|
* @param titles : Name of the file
|
||||||
|
* @return Single<MwQueryResult>
|
||||||
|
*/
|
||||||
|
@GET(
|
||||||
|
Service.MW_API_PREFIX +
|
||||||
|
"action=query&prop=revisions&rvprop=content|timestamp&rvlimit=1&converttitles="
|
||||||
|
)
|
||||||
|
fun getWikiText(
|
||||||
|
@Query("titles") title: String
|
||||||
|
): Single<MwQueryResponse?>
|
||||||
}
|
}
|
||||||
|
|
@ -339,6 +339,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
||||||
// no longer attached to activity!
|
// no longer attached to activity!
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
compositeDisposable.clear();
|
||||||
sessionManager.setUserLoggedIn(true);
|
sessionManager.setUserLoggedIn(true);
|
||||||
AppAdapter.get().updateAccount(loginResult);
|
AppAdapter.get().updateAccount(loginResult);
|
||||||
progressDialog.dismiss();
|
progressDialog.dismiss();
|
||||||
|
|
|
||||||
|
|
@ -269,7 +269,7 @@ public class BookmarkLocationsDao {
|
||||||
onUpdate(db, from, to);
|
onUpdate(db, from, to);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (from == 8) {
|
if (from < 10) {
|
||||||
from++;
|
from++;
|
||||||
onUpdate(db, from, to);
|
onUpdate(db, from, to);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.customselector.ui.selector.CustomSelectorActivity;
|
|
||||||
import fr.free.nrw.commons.filepicker.DefaultCallback;
|
import fr.free.nrw.commons.filepicker.DefaultCallback;
|
||||||
import fr.free.nrw.commons.filepicker.FilePicker;
|
import fr.free.nrw.commons.filepicker.FilePicker;
|
||||||
import fr.free.nrw.commons.filepicker.FilePicker.ImageSource;
|
import fr.free.nrw.commons.filepicker.FilePicker.ImageSource;
|
||||||
|
|
@ -63,16 +62,11 @@ public class ContributionController {
|
||||||
* Initiate gallery picker with permission
|
* Initiate gallery picker with permission
|
||||||
*/
|
*/
|
||||||
public void initiateCustomGalleryPickWithPermission(final Activity activity) {
|
public void initiateCustomGalleryPickWithPermission(final Activity activity) {
|
||||||
boolean useExtStorage = defaultKvStore.getBoolean("useExternalStorage", true);
|
setPickerConfiguration(activity,true);
|
||||||
Intent intent = new Intent(activity,CustomSelectorActivity.class);
|
|
||||||
if (!useExtStorage) {
|
|
||||||
activity.startActivity(intent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PermissionUtils.checkPermissionsAndPerformAction(activity,
|
PermissionUtils.checkPermissionsAndPerformAction(activity,
|
||||||
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
Manifest.permission.WRITE_EXTERNAL_STORAGE,
|
||||||
() -> activity.startActivity(intent),
|
() -> FilePicker.openCustomSelector(activity, 0),
|
||||||
R.string.storage_permission_title,
|
R.string.storage_permission_title,
|
||||||
R.string.write_storage_permission_rationale);
|
R.string.write_storage_permission_rationale);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
|
@ -24,6 +25,14 @@ import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
|
import androidx.fragment.app.FragmentManager.OnBackStackChangedListener;
|
||||||
import androidx.fragment.app.FragmentTransaction;
|
import androidx.fragment.app.FragmentTransaction;
|
||||||
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
|
import fr.free.nrw.commons.notification.Notification;
|
||||||
|
import fr.free.nrw.commons.notification.NotificationController;
|
||||||
|
import fr.free.nrw.commons.theme.BaseActivity;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
import butterknife.BindView;
|
import butterknife.BindView;
|
||||||
import butterknife.ButterKnife;
|
import butterknife.ButterKnife;
|
||||||
import fr.free.nrw.commons.CommonsApplication;
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
|
|
@ -531,6 +540,13 @@ public class ContributionsFragment
|
||||||
presenter.onDetachView();
|
presenter.onDetachView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notifyDataSetChanged() {
|
||||||
|
if (mediaDetailPagerFragment != null) {
|
||||||
|
mediaDetailPagerFragment.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retry upload when it is failed
|
* Retry upload when it is failed
|
||||||
*
|
*
|
||||||
|
|
@ -604,12 +620,8 @@ public class ContributionsFragment
|
||||||
return contributionsListFragment.getContributionStateAt(position);
|
return contributionsListFragment.getContributionStateAt(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void backButtonClicked() {
|
public boolean backButtonClicked() {
|
||||||
if (mediaDetailPagerFragment.isVisible()) {
|
if (null != mediaDetailPagerFragment && mediaDetailPagerFragment.isVisible()) {
|
||||||
if(mediaDetailPagerFragment.backButtonClicked()) {
|
|
||||||
// MediaDetailed handled the backPressed no further action required.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (store.getBoolean("displayNearbyCardView", true)) {
|
if (store.getBoolean("displayNearbyCardView", true)) {
|
||||||
if (nearbyNotificationCardView.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
|
if (nearbyNotificationCardView.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
|
||||||
nearbyNotificationCardView.setVisibility(View.VISIBLE);
|
nearbyNotificationCardView.setVisibility(View.VISIBLE);
|
||||||
|
|
@ -622,7 +634,9 @@ public class ContributionsFragment
|
||||||
((BaseActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
((BaseActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||||
((MainActivity)getActivity()).showTabs();
|
((MainActivity)getActivity()).showTabs();
|
||||||
fetchCampaigns();
|
fetchCampaigns();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Getter for mediaDetailPagerFragment
|
// Getter for mediaDetailPagerFragment
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,8 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
private final int SPAN_COUNT_LANDSCAPE = 3;
|
private final int SPAN_COUNT_LANDSCAPE = 3;
|
||||||
private final int SPAN_COUNT_PORTRAIT = 1;
|
private final int SPAN_COUNT_PORTRAIT = 1;
|
||||||
|
|
||||||
|
private int contributionsSize;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(
|
public View onCreateView(
|
||||||
|
|
@ -154,7 +156,11 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
}
|
}
|
||||||
|
|
||||||
contributionsListPresenter.setup();
|
contributionsListPresenter.setup();
|
||||||
contributionsListPresenter.contributionList.observe(this.getViewLifecycleOwner(), adapter::submitList);
|
contributionsListPresenter.contributionList.observe(this.getViewLifecycleOwner(), list -> {
|
||||||
|
contributionsSize = list.size();
|
||||||
|
adapter.submitList(list);
|
||||||
|
callback.notifyDataSetChanged();
|
||||||
|
});
|
||||||
rvContributionsList.setAdapter(adapter);
|
rvContributionsList.setAdapter(adapter);
|
||||||
adapter.registerAdapterDataObserver(new AdapterDataObserver() {
|
adapter.registerAdapterDataObserver(new AdapterDataObserver() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -405,10 +411,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTotalMediaCount() {
|
public int getTotalMediaCount() {
|
||||||
if(adapter != null) {
|
return contributionsSize;
|
||||||
return adapter.getItemCount();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -435,6 +438,8 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment impl
|
||||||
|
|
||||||
public interface Callback {
|
public interface Callback {
|
||||||
|
|
||||||
|
void notifyDataSetChanged();
|
||||||
|
|
||||||
void retryUpload(Contribution contribution);
|
void retryUpload(Contribution contribution);
|
||||||
|
|
||||||
void showDetail(int position, boolean isWikipediaButtonDisplayed);
|
void showDetail(int position, boolean isWikipediaButtonDisplayed);
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,9 @@ public class MainActivity extends BaseActivity
|
||||||
@Override
|
@Override
|
||||||
public boolean onSupportNavigateUp() {
|
public boolean onSupportNavigateUp() {
|
||||||
if (activeFragment == ActiveFragment.CONTRIBUTIONS) {
|
if (activeFragment == ActiveFragment.CONTRIBUTIONS) {
|
||||||
contributionsFragment.backButtonClicked();
|
if (!contributionsFragment.backButtonClicked()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
onBackPressed();
|
onBackPressed();
|
||||||
showTabs();
|
showTabs();
|
||||||
|
|
@ -264,16 +266,10 @@ public class MainActivity extends BaseActivity
|
||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (contributionsFragment != null && activeFragment == ActiveFragment.CONTRIBUTIONS) {
|
if (contributionsFragment != null && activeFragment == ActiveFragment.CONTRIBUTIONS) {
|
||||||
// Meas that contribution fragment is visible
|
// Means that contribution fragment is visible
|
||||||
mediaDetailPagerFragment=contributionsFragment.getMediaDetailPagerFragment();
|
if (!contributionsFragment.backButtonClicked()) {//If this one does not wan't to handle
|
||||||
if (mediaDetailPagerFragment ==null) { //means you open the app currently and not open mediaDetailPage fragment
|
// the back press, let the activity do so
|
||||||
super.onBackPressed();
|
super.onBackPressed();
|
||||||
} else if (mediaDetailPagerFragment!=null) {
|
|
||||||
if(!mediaDetailPagerFragment.isVisible()){ //means you are at contributions fragement
|
|
||||||
super.onBackPressed();
|
|
||||||
} else { //mean you are at mediaDetailPager Fragment
|
|
||||||
contributionsFragment.backButtonClicked();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (nearbyParentFragment != null && activeFragment == ActiveFragment.NEARBY) {
|
} else if (nearbyParentFragment != null && activeFragment == ActiveFragment.NEARBY) {
|
||||||
// Means that nearby fragment is visible
|
// Means that nearby fragment is visible
|
||||||
|
|
@ -322,7 +318,7 @@ public class MainActivity extends BaseActivity
|
||||||
} else {
|
} else {
|
||||||
WorkManager.getInstance(getApplicationContext()).enqueueUniqueWork(
|
WorkManager.getInstance(getApplicationContext()).enqueueUniqueWork(
|
||||||
UploadWorker.class.getSimpleName(),
|
UploadWorker.class.getSimpleName(),
|
||||||
ExistingWorkPolicy.KEEP, OneTimeWorkRequest.from(UploadWorker.class));
|
ExistingWorkPolicy.APPEND_OR_REPLACE, OneTimeWorkRequest.from(UploadWorker.class));
|
||||||
|
|
||||||
viewUtilWrapper
|
viewUtilWrapper
|
||||||
.showShortToast(getBaseContext(), getString(R.string.limited_connection_disabled));
|
.showShortToast(getBaseContext(), getString(R.string.limited_connection_disabled));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,197 @@
|
||||||
|
package fr.free.nrw.commons.coordinates;
|
||||||
|
|
||||||
|
import static fr.free.nrw.commons.notification.NotificationHelper.NOTIFICATION_EDIT_COORDINATES;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import fr.free.nrw.commons.BuildConfig;
|
||||||
|
import fr.free.nrw.commons.Media;
|
||||||
|
import fr.free.nrw.commons.R;
|
||||||
|
import fr.free.nrw.commons.actions.PageEditClient;
|
||||||
|
import fr.free.nrw.commons.notification.NotificationHelper;
|
||||||
|
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.Single;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import java.util.Objects;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for edit and update given coordinates and showing notification about new coordinates
|
||||||
|
* upgradation
|
||||||
|
*/
|
||||||
|
public class CoordinateEditHelper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* notificationHelper: helps creating notification
|
||||||
|
*/
|
||||||
|
private final NotificationHelper notificationHelper;
|
||||||
|
/**
|
||||||
|
* * pageEditClient: methods provided by this member posts the edited coordinates
|
||||||
|
* to the Media wiki api
|
||||||
|
*/
|
||||||
|
public final PageEditClient pageEditClient;
|
||||||
|
/**
|
||||||
|
* viewUtil: helps to show Toast
|
||||||
|
*/
|
||||||
|
private final ViewUtilWrapper viewUtil;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public CoordinateEditHelper(final NotificationHelper notificationHelper,
|
||||||
|
@Named("commons-page-edit") final PageEditClient pageEditClient,
|
||||||
|
final ViewUtilWrapper viewUtil) {
|
||||||
|
this.notificationHelper = notificationHelper;
|
||||||
|
this.pageEditClient = pageEditClient;
|
||||||
|
this.viewUtil = viewUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public interface to edit coordinates
|
||||||
|
* @param context to be added
|
||||||
|
* @param media to be added
|
||||||
|
* @param Accuracy to be added
|
||||||
|
* @return Single<Boolean>
|
||||||
|
*/
|
||||||
|
public Single<Boolean> makeCoordinatesEdit(final Context context, final Media media,
|
||||||
|
final String Latitude, final String Longitude, final String Accuracy) {
|
||||||
|
viewUtil.showShortToast(context,
|
||||||
|
context.getString(R.string.coordinates_edit_helper_make_edit_toast));
|
||||||
|
return addCoordinates(media, Latitude, Longitude, Accuracy)
|
||||||
|
.flatMapSingle(result -> Single.just(showCoordinatesEditNotification(context, media,
|
||||||
|
Latitude, Longitude, Accuracy, result)))
|
||||||
|
.firstOrError();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces new coordinates
|
||||||
|
* @param media to be added
|
||||||
|
* @param Latitude to be added
|
||||||
|
* @param Longitude to be added
|
||||||
|
* @param Accuracy to be added
|
||||||
|
* @return Observable<Boolean>
|
||||||
|
*/
|
||||||
|
private Observable<Boolean> addCoordinates(final Media media, final String Latitude,
|
||||||
|
final String Longitude, final String Accuracy) {
|
||||||
|
Timber.d("thread is coordinates adding %s", Thread.currentThread().getName());
|
||||||
|
final String summary = "Adding Coordinates";
|
||||||
|
|
||||||
|
final StringBuilder buffer = new StringBuilder();
|
||||||
|
|
||||||
|
final String wikiText = pageEditClient.getCurrentWikiText(media.getFilename())
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.blockingGet();
|
||||||
|
|
||||||
|
if (Latitude != null) {
|
||||||
|
buffer.append("\n{{Location|").append(Latitude).append("|").append(Longitude)
|
||||||
|
.append("|").append(Accuracy).append("}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
final String editedLocation = buffer.toString();
|
||||||
|
final String appendText = getFormattedWikiText(wikiText, editedLocation);
|
||||||
|
|
||||||
|
return pageEditClient.edit(Objects.requireNonNull(media.getFilename())
|
||||||
|
, appendText, summary);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps to get formatted wikitext with upgraded location
|
||||||
|
* @param wikiText current wikitext
|
||||||
|
* @param editedLocation new location
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
private String getFormattedWikiText(final String wikiText, final String editedLocation){
|
||||||
|
|
||||||
|
if (wikiText.contains("filedesc") && wikiText.contains("Location")) {
|
||||||
|
|
||||||
|
final String fromLocationToEnd = wikiText.substring(wikiText.indexOf("{{Location"));
|
||||||
|
final String firstHalf = wikiText.substring(0, wikiText.indexOf("{{Location"));
|
||||||
|
final String lastHalf = fromLocationToEnd.substring(
|
||||||
|
fromLocationToEnd.indexOf("}}") + 2);
|
||||||
|
|
||||||
|
final int startOfSecondSection = StringUtils.ordinalIndexOf(wikiText,
|
||||||
|
"==", 3);
|
||||||
|
final StringBuilder buffer = new StringBuilder();
|
||||||
|
if (wikiText.charAt(wikiText.indexOf("{{Location")-1) == '\n') {
|
||||||
|
buffer.append(editedLocation.substring(1));
|
||||||
|
} else {
|
||||||
|
buffer.append(editedLocation);
|
||||||
|
}
|
||||||
|
if (startOfSecondSection != -1 && wikiText.charAt(startOfSecondSection-1)!= '\n') {
|
||||||
|
buffer.append("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstHalf + buffer + lastHalf;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (wikiText.contains("filedesc") && !wikiText.contains("Location")) {
|
||||||
|
|
||||||
|
final int startOfSecondSection = StringUtils.ordinalIndexOf(wikiText,
|
||||||
|
"==", 3);
|
||||||
|
|
||||||
|
if (startOfSecondSection != -1) {
|
||||||
|
final String firstHalf = wikiText.substring(0, startOfSecondSection);
|
||||||
|
final String lastHalf = wikiText.substring(startOfSecondSection);
|
||||||
|
final String buffer = editedLocation.substring(1)
|
||||||
|
+ "\n";
|
||||||
|
return firstHalf + buffer + lastHalf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return wikiText + editedLocation;
|
||||||
|
}
|
||||||
|
if (!wikiText.contains("filedesc") && !wikiText.contains("Location")) {
|
||||||
|
|
||||||
|
return "== {{int:filedesc}} ==" + editedLocation + wikiText;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (!wikiText.contains("filedesc") && wikiText.contains("Location")) {
|
||||||
|
|
||||||
|
return "== {{int:filedesc}} ==" + editedLocation + wikiText;
|
||||||
|
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update coordinates and shows notification about coordinates update
|
||||||
|
* @param context to be added
|
||||||
|
* @param media to be added
|
||||||
|
* @param latitude to be added
|
||||||
|
* @param longitude to be added
|
||||||
|
* @param Accuracy to be added
|
||||||
|
* @param result to be added
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
private boolean showCoordinatesEditNotification(final Context context, final Media media,
|
||||||
|
final String latitude, final String longitude, final String Accuracy,
|
||||||
|
final boolean result) {
|
||||||
|
final String message;
|
||||||
|
String title = context.getString(R.string.coordinates_edit_helper_show_edit_title);
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
media.setCoordinates(
|
||||||
|
new fr.free.nrw.commons.location.LatLng(Double.parseDouble(latitude),
|
||||||
|
Double.parseDouble(longitude),
|
||||||
|
Float.parseFloat(Accuracy)));
|
||||||
|
title += ": " + context
|
||||||
|
.getString(R.string.coordinates_edit_helper_show_edit_title_success);
|
||||||
|
final StringBuilder coordinatesInMessage = new StringBuilder();
|
||||||
|
final String mediaCoordinate = String.valueOf(media.getCoordinates());
|
||||||
|
coordinatesInMessage.append(mediaCoordinate);
|
||||||
|
message = context.getString(R.string.coordinates_edit_helper_show_edit_message,
|
||||||
|
coordinatesInMessage.toString());
|
||||||
|
} else {
|
||||||
|
title += ": " + context.getString(R.string.coordinates_edit_helper_show_edit_title);
|
||||||
|
message = context.getString(R.string.coordinates_edit_helper_edit_message_else) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
final String urlForFile = BuildConfig.COMMONS_URL + "/wiki/" + media.getFilename();
|
||||||
|
final Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlForFile));
|
||||||
|
notificationHelper.showNotification(context, title, message, NOTIFICATION_EDIT_COORDINATES,
|
||||||
|
browserIntent);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -11,7 +11,7 @@ import kotlin.collections.ArrayList
|
||||||
import kotlin.collections.LinkedHashMap
|
import kotlin.collections.LinkedHashMap
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Helper object, includes all the static functions required by custom selector
|
* Image Helper object, includes all the static functions required by custom selector.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
object ImageHelper {
|
object ImageHelper {
|
||||||
|
|
@ -49,6 +49,34 @@ object ImageHelper {
|
||||||
return filteredImages
|
return filteredImages
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getIndex: Returns the index of image in given list.
|
||||||
|
*/
|
||||||
|
fun getIndex(list: ArrayList<Image>, image: Image): Int {
|
||||||
|
return list.indexOf(image)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of indices from the master list.
|
||||||
|
*/
|
||||||
|
fun getIndexList(list: ArrayList<Image>, masterList: ArrayList<Image>): ArrayList<Int> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
* Can be optimised as masterList is sorted by time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
val indexes = arrayListOf<Int>()
|
||||||
|
for(image in list) {
|
||||||
|
val index = getIndex(masterList,image)
|
||||||
|
if (index == -1) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
indexes.add(index)
|
||||||
|
}
|
||||||
|
return indexes
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the file sha1 from file input stream.
|
* Generates the file sha1 from file input stream.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import androidx.constraintlayout.widget.Group
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
|
import fr.free.nrw.commons.customselector.helper.ImageHelper
|
||||||
import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
|
import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
|
||||||
import fr.free.nrw.commons.customselector.model.Image
|
import fr.free.nrw.commons.customselector.model.Image
|
||||||
|
|
||||||
|
|
@ -26,6 +27,16 @@ class ImageAdapter(
|
||||||
|
|
||||||
RecyclerViewAdapter<ImageAdapter.ImageViewHolder>(context) {
|
RecyclerViewAdapter<ImageAdapter.ImageViewHolder>(context) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ImageSelectedOrUpdated payload class.
|
||||||
|
*/
|
||||||
|
class ImageSelectedOrUpdated
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ImageUnselected payload class.
|
||||||
|
*/
|
||||||
|
class ImageUnselected
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Currently selected images.
|
* Currently selected images.
|
||||||
*/
|
*/
|
||||||
|
|
@ -49,18 +60,41 @@ class ImageAdapter(
|
||||||
*/
|
*/
|
||||||
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {
|
||||||
val image=images[position]
|
val image=images[position]
|
||||||
// todo load image thumbnail, set selected view.
|
val selectedIndex = ImageHelper.getIndex(selectedImages,image)
|
||||||
|
val isSelected = selectedIndex != -1
|
||||||
|
if(isSelected){
|
||||||
|
holder.itemSelected(selectedIndex+1)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
holder.itemUnselected();
|
||||||
|
}
|
||||||
Glide.with(context).load(image.uri).into(holder.image)
|
Glide.with(context).load(image.uri).into(holder.image)
|
||||||
holder.itemView.setOnClickListener {
|
holder.itemView.setOnClickListener {
|
||||||
selectOrRemoveImage(image, position)
|
selectOrRemoveImage(holder, position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle click event on an image, update counter on images.
|
* Handle click event on an image, update counter on images.
|
||||||
*/
|
*/
|
||||||
private fun selectOrRemoveImage(image:Image, position:Int){
|
private fun selectOrRemoveImage(holder:ImageViewHolder, position:Int){
|
||||||
// todo select the image if not selected and remove it if already selected
|
val clickedIndex = ImageHelper.getIndex(selectedImages,images[position])
|
||||||
|
if (clickedIndex != -1) {
|
||||||
|
selectedImages.removeAt(clickedIndex)
|
||||||
|
notifyItemChanged(position,ImageUnselected())
|
||||||
|
val indexes = ImageHelper.getIndexList(selectedImages, images)
|
||||||
|
for (index in indexes) {
|
||||||
|
notifyItemChanged(index, ImageSelectedOrUpdated())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
* Show toast on tapping an uploaded item.
|
||||||
|
*/
|
||||||
|
selectedImages.add(images[position])
|
||||||
|
notifyItemChanged(position, ImageSelectedOrUpdated())
|
||||||
|
}
|
||||||
|
imageSelectListener.onSelectedImagesChanged(selectedImages)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -90,9 +124,39 @@ class ImageAdapter(
|
||||||
*/
|
*/
|
||||||
class ImageViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
|
class ImageViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {
|
||||||
val image: ImageView = itemView.findViewById(R.id.image_thumbnail)
|
val image: ImageView = itemView.findViewById(R.id.image_thumbnail)
|
||||||
val selectedNumber: TextView = itemView.findViewById(R.id.selected_count)
|
private val selectedNumber: TextView = itemView.findViewById(R.id.selected_count)
|
||||||
val uploadedGroup: Group = itemView.findViewById(R.id.uploaded_group)
|
private val uploadedGroup: Group = itemView.findViewById(R.id.uploaded_group)
|
||||||
val selectedGroup: Group = itemView.findViewById(R.id.selected_group)
|
private val selectedGroup: Group = itemView.findViewById(R.id.selected_group)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item selected view.
|
||||||
|
*/
|
||||||
|
fun itemSelected(index: Int) {
|
||||||
|
selectedGroup.visibility = View.VISIBLE
|
||||||
|
selectedNumber.text = index.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item Unselected view.
|
||||||
|
*/
|
||||||
|
fun itemUnselected() {
|
||||||
|
selectedGroup.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item Uploaded view.
|
||||||
|
*/
|
||||||
|
fun itemUploaded() {
|
||||||
|
uploadedGroup.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Item Not Uploaded view.
|
||||||
|
*/
|
||||||
|
fun itemNotUploaded() {
|
||||||
|
uploadedGroup.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package fr.free.nrw.commons.customselector.ui.selector
|
package fr.free.nrw.commons.customselector.ui.selector
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
|
@ -10,6 +12,7 @@ import fr.free.nrw.commons.customselector.listeners.ImageSelectListener
|
||||||
import fr.free.nrw.commons.customselector.model.Folder
|
import fr.free.nrw.commons.customselector.model.Folder
|
||||||
import fr.free.nrw.commons.customselector.model.Image
|
import fr.free.nrw.commons.customselector.model.Image
|
||||||
import fr.free.nrw.commons.theme.BaseActivity
|
import fr.free.nrw.commons.theme.BaseActivity
|
||||||
|
import java.io.File
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectListener {
|
class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectListener {
|
||||||
|
|
@ -73,7 +76,8 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL
|
||||||
val back : ImageButton = findViewById(R.id.back)
|
val back : ImageButton = findViewById(R.id.back)
|
||||||
back.setOnClickListener { onBackPressed() }
|
back.setOnClickListener { onBackPressed() }
|
||||||
|
|
||||||
// todo done listener.
|
val done : ImageButton = findViewById(R.id.done)
|
||||||
|
done.setOnClickListener { onDone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -91,9 +95,44 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL
|
||||||
* override Selected Images Change, update view model selected images.
|
* override Selected Images Change, update view model selected images.
|
||||||
*/
|
*/
|
||||||
override fun onSelectedImagesChanged(selectedImages: ArrayList<Image>) {
|
override fun onSelectedImagesChanged(selectedImages: ArrayList<Image>) {
|
||||||
|
viewModel.selectedImages.value = selectedImages
|
||||||
// todo update selected images in view model.
|
// todo update selected images in view model.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OnDone clicked.
|
||||||
|
* Get the selected images. Remove any non existent file, forward the data to finish selector.
|
||||||
|
*/
|
||||||
|
fun onDone() {
|
||||||
|
val selectedImages = viewModel.selectedImages.value
|
||||||
|
if(selectedImages.isNullOrEmpty()) {
|
||||||
|
finishPickImages(arrayListOf())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var i = 0
|
||||||
|
while (i < selectedImages.size) {
|
||||||
|
val path = selectedImages[i].path
|
||||||
|
val file = File(path)
|
||||||
|
if (!file.exists()) {
|
||||||
|
selectedImages.removeAt(i)
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
finishPickImages(selectedImages)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* finishPickImages, Load the data to the intent and set result.
|
||||||
|
* Finish the activity.
|
||||||
|
*/
|
||||||
|
private fun finishPickImages(images: ArrayList<Image>) {
|
||||||
|
val data = Intent()
|
||||||
|
data.putParcelableArrayListExtra("Images", images)
|
||||||
|
setResult(Activity.RESULT_OK, data)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Back pressed.
|
* Back pressed.
|
||||||
* Change toolbar title.
|
* Change toolbar title.
|
||||||
|
|
@ -106,16 +145,4 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* TODO
|
|
||||||
* Permission check.
|
|
||||||
* OnDone
|
|
||||||
* Activity Result.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package fr.free.nrw.commons.customselector.ui.selector
|
package fr.free.nrw.commons.customselector.ui.selector
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
import androidx.lifecycle.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import fr.free.nrw.commons.customselector.listeners.ImageLoaderListener
|
import fr.free.nrw.commons.customselector.listeners.ImageLoaderListener
|
||||||
|
|
@ -14,10 +13,18 @@ import kotlinx.coroutines.cancel
|
||||||
|
|
||||||
class CustomSelectorViewModel(var context: Context,var imageFileLoader: ImageFileLoader) : ViewModel() {
|
class CustomSelectorViewModel(var context: Context,var imageFileLoader: ImageFileLoader) : ViewModel() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope for coroutine task (image fetch).
|
||||||
|
*/
|
||||||
private val scope = CoroutineScope(Dispatchers.Main)
|
private val scope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result Live Data
|
* Stores selected images.
|
||||||
|
*/
|
||||||
|
var selectedImages: MutableLiveData<ArrayList<Image>> = MutableLiveData()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Result Live Data.
|
||||||
*/
|
*/
|
||||||
val result = MutableLiveData(Result(CallbackStatus.IDLE, arrayListOf()))
|
val result = MutableLiveData(Result(CallbackStatus.IDLE, arrayListOf()))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao;
|
||||||
public class DBOpenHelper extends SQLiteOpenHelper {
|
public class DBOpenHelper extends SQLiteOpenHelper {
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "commons.db";
|
private static final String DATABASE_NAME = "commons.db";
|
||||||
private static final int DATABASE_VERSION = 15;
|
private static final int DATABASE_VERSION = 14;
|
||||||
public static final String CONTRIBUTIONS_TABLE = "contributions";
|
public static final String CONTRIBUTIONS_TABLE = "contributions";
|
||||||
private final String DROP_TABLE_STATEMENT="DROP TABLE IF EXISTS %s";
|
private final String DROP_TABLE_STATEMENT="DROP TABLE IF EXISTS %s";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@ public class ExploreListRootFragment extends CommonsDaggerSupportFragment implem
|
||||||
container.setVisibility(View.VISIBLE);
|
container.setVisibility(View.VISIBLE);
|
||||||
((ExploreFragment)getParentFragment()).tabLayout.setVisibility(View.GONE);
|
((ExploreFragment)getParentFragment()).tabLayout.setVisibility(View.GONE);
|
||||||
mediaDetails = new MediaDetailPagerFragment(false, true);
|
mediaDetails = new MediaDetailPagerFragment(false, true);
|
||||||
((ExploreFragment) getParentFragment()).setScroll(false);
|
|
||||||
setFragment(mediaDetails, listFragment);
|
setFragment(mediaDetails, listFragment);
|
||||||
mediaDetails.showImage(position);
|
mediaDetails.showImage(position);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ public interface Constants {
|
||||||
int FILE_PICKER_IMAGE_IDENTIFICATOR = 0b1101101100; //876
|
int FILE_PICKER_IMAGE_IDENTIFICATOR = 0b1101101100; //876
|
||||||
int SOURCE_CHOOSER = 1 << 15;
|
int SOURCE_CHOOSER = 1 << 15;
|
||||||
|
|
||||||
|
int PICK_PICTURE_FROM_CUSTOM_SELECTOR = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 10);
|
||||||
int PICK_PICTURE_FROM_DOCUMENTS = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 11);
|
int PICK_PICTURE_FROM_DOCUMENTS = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 11);
|
||||||
int PICK_PICTURE_FROM_GALLERY = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 12);
|
int PICK_PICTURE_FROM_GALLERY = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 12);
|
||||||
int TAKE_PICTURE = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 13);
|
int TAKE_PICTURE = FILE_PICKER_IMAGE_IDENTIFICATOR + (1 << 13);
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import android.text.TextUtils;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.customselector.model.Image;
|
||||||
|
import fr.free.nrw.commons.customselector.ui.selector.CustomSelectorActivity;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
|
@ -51,6 +53,11 @@ public class FilePicker implements Constants {
|
||||||
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, configuration(context).allowsMultiplePickingInGallery());
|
.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, configuration(context).allowsMultiplePickingInGallery());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Intent createCustomSelectorIntent(@NonNull Context context, int type) {
|
||||||
|
storeType(context, type);
|
||||||
|
return new Intent(context, CustomSelectorActivity.class);
|
||||||
|
}
|
||||||
|
|
||||||
private static Intent createCameraForImageIntent(@NonNull Context context, int type) {
|
private static Intent createCameraForImageIntent(@NonNull Context context, int type) {
|
||||||
storeType(context, type);
|
storeType(context, type);
|
||||||
|
|
||||||
|
|
@ -97,6 +104,14 @@ public class FilePicker implements Constants {
|
||||||
activity.startActivityForResult(intent, RequestCodes.PICK_PICTURE_FROM_GALLERY);
|
activity.startActivityForResult(intent, RequestCodes.PICK_PICTURE_FROM_GALLERY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens Custom Selector
|
||||||
|
*/
|
||||||
|
public static void openCustomSelector(Activity activity, int type) {
|
||||||
|
Intent intent = createCustomSelectorIntent(activity, type);
|
||||||
|
activity.startActivityForResult(intent, RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the camera app to pick image clicked by user
|
* Opens the camera app to pick image clicked by user
|
||||||
*/
|
*/
|
||||||
|
|
@ -135,12 +150,15 @@ public class FilePicker implements Constants {
|
||||||
if (requestCode == RequestCodes.PICK_PICTURE_FROM_GALLERY ||
|
if (requestCode == RequestCodes.PICK_PICTURE_FROM_GALLERY ||
|
||||||
requestCode == RequestCodes.TAKE_PICTURE ||
|
requestCode == RequestCodes.TAKE_PICTURE ||
|
||||||
requestCode == RequestCodes.CAPTURE_VIDEO ||
|
requestCode == RequestCodes.CAPTURE_VIDEO ||
|
||||||
requestCode == RequestCodes.PICK_PICTURE_FROM_DOCUMENTS) {
|
requestCode == RequestCodes.PICK_PICTURE_FROM_DOCUMENTS ||
|
||||||
|
requestCode == RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR) {
|
||||||
if (resultCode == Activity.RESULT_OK) {
|
if (resultCode == Activity.RESULT_OK) {
|
||||||
if (requestCode == RequestCodes.PICK_PICTURE_FROM_DOCUMENTS && !isPhoto(data)) {
|
if (requestCode == RequestCodes.PICK_PICTURE_FROM_DOCUMENTS && !isPhoto(data)) {
|
||||||
onPictureReturnedFromDocuments(data, activity, callbacks);
|
onPictureReturnedFromDocuments(data, activity, callbacks);
|
||||||
} else if (requestCode == RequestCodes.PICK_PICTURE_FROM_GALLERY && !isPhoto(data)) {
|
} else if (requestCode == RequestCodes.PICK_PICTURE_FROM_GALLERY && !isPhoto(data)) {
|
||||||
onPictureReturnedFromGallery(data, activity, callbacks);
|
onPictureReturnedFromGallery(data, activity, callbacks);
|
||||||
|
} else if (requestCode == RequestCodes.PICK_PICTURE_FROM_CUSTOM_SELECTOR) {
|
||||||
|
onPictureReturnedFromCustomSelector(data, activity, callbacks);
|
||||||
} else if (requestCode == RequestCodes.TAKE_PICTURE) {
|
} else if (requestCode == RequestCodes.TAKE_PICTURE) {
|
||||||
onPictureReturnedFromCamera(activity, callbacks);
|
onPictureReturnedFromCamera(activity, callbacks);
|
||||||
} else if (requestCode == RequestCodes.CAPTURE_VIDEO) {
|
} else if (requestCode == RequestCodes.CAPTURE_VIDEO) {
|
||||||
|
|
@ -197,6 +215,32 @@ public class FilePicker implements Constants {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void onPictureReturnedFromCustomSelector(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) {
|
||||||
|
try {
|
||||||
|
List<UploadableFile> files = getFilesFromCustomSelector(data, activity);
|
||||||
|
callbacks.onImagesPicked(files, ImageSource.CUSTOM_SELECTOR, restoreType(activity));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
callbacks.onImagePickerError(e, ImageSource.CUSTOM_SELECTOR, restoreType(activity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<UploadableFile> getFilesFromCustomSelector(Intent data, Activity activity) throws IOException, SecurityException {
|
||||||
|
List<UploadableFile> files = new ArrayList<>();
|
||||||
|
ArrayList<Image> images = data.getParcelableArrayListExtra("Images");
|
||||||
|
for(Image image : images) {
|
||||||
|
Uri uri = image.getUri();
|
||||||
|
UploadableFile file = PickedFiles.pickedExistingPicture(activity, uri);
|
||||||
|
files.add(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (configuration(activity).shouldCopyPickedImagesToPublicGalleryAppFolder()) {
|
||||||
|
PickedFiles.copyFilesInSeparateThread(activity, files);
|
||||||
|
}
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
private static void onPictureReturnedFromGallery(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) {
|
private static void onPictureReturnedFromGallery(Intent data, Activity activity, @NonNull FilePicker.Callbacks callbacks) {
|
||||||
try {
|
try {
|
||||||
List<UploadableFile> files = getFilesFromGalleryPictures(data, activity);
|
List<UploadableFile> files = getFilesFromGalleryPictures(data, activity);
|
||||||
|
|
@ -301,7 +345,7 @@ public class FilePicker implements Constants {
|
||||||
|
|
||||||
|
|
||||||
public enum ImageSource {
|
public enum ImageSource {
|
||||||
GALLERY, DOCUMENTS, CAMERA_IMAGE, CAMERA_VIDEO
|
GALLERY, DOCUMENTS, CAMERA_IMAGE, CAMERA_VIDEO, CUSTOM_SELECTOR
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Callbacks {
|
public interface Callbacks {
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,16 @@ package fr.free.nrw.commons.logging;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||||
import fr.free.nrw.commons.utils.DeviceInfoUtil;
|
import fr.free.nrw.commons.utils.DeviceInfoUtil;
|
||||||
|
import org.acra.data.CrashReportData;
|
||||||
|
import org.acra.sender.ReportSenderException;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class responsible for sending logs to developers
|
* Class responsible for sending logs to developers
|
||||||
|
|
@ -87,4 +91,15 @@ public class CommonsLogSender extends LogsSender {
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresForeground() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void send(@NotNull Context context, @NotNull CrashReportData crashReportData,
|
||||||
|
@NotNull Bundle bundle) throws ReportSenderException {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package fr.free.nrw.commons.media;
|
package fr.free.nrw.commons.media;
|
||||||
|
|
||||||
|
import static android.app.Activity.RESULT_CANCELED;
|
||||||
|
import static android.app.Activity.RESULT_OK;
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_NEEDING_CATEGORIES;
|
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_NEEDING_CATEGORIES;
|
||||||
|
|
@ -16,11 +18,8 @@ import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnKeyListener;
|
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||||
|
|
@ -50,6 +49,9 @@ import com.facebook.imagepipeline.image.ImageInfo;
|
||||||
import com.facebook.imagepipeline.request.ImageRequest;
|
import com.facebook.imagepipeline.request.ImageRequest;
|
||||||
import com.jakewharton.rxbinding2.view.RxView;
|
import com.jakewharton.rxbinding2.view.RxView;
|
||||||
import com.jakewharton.rxbinding2.widget.RxSearchView;
|
import com.jakewharton.rxbinding2.widget.RxSearchView;
|
||||||
|
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||||
|
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||||
|
import fr.free.nrw.commons.LocationPicker.LocationPicker;
|
||||||
import fr.free.nrw.commons.Media;
|
import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.MediaDataExtractor;
|
import fr.free.nrw.commons.MediaDataExtractor;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
|
|
@ -62,10 +64,11 @@ import fr.free.nrw.commons.category.CategoryEditHelper;
|
||||||
import fr.free.nrw.commons.category.CategoryEditSearchRecyclerViewAdapter;
|
import fr.free.nrw.commons.category.CategoryEditSearchRecyclerViewAdapter;
|
||||||
import fr.free.nrw.commons.category.CategoryEditSearchRecyclerViewAdapter.Callback;
|
import fr.free.nrw.commons.category.CategoryEditSearchRecyclerViewAdapter.Callback;
|
||||||
import fr.free.nrw.commons.contributions.ContributionsFragment;
|
import fr.free.nrw.commons.contributions.ContributionsFragment;
|
||||||
|
import fr.free.nrw.commons.coordinates.CoordinateEditHelper;
|
||||||
import fr.free.nrw.commons.delete.DeleteHelper;
|
import fr.free.nrw.commons.delete.DeleteHelper;
|
||||||
import fr.free.nrw.commons.delete.ReasonBuilder;
|
import fr.free.nrw.commons.delete.ReasonBuilder;
|
||||||
import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity;
|
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
|
import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.nearby.Label;
|
import fr.free.nrw.commons.nearby.Label;
|
||||||
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
||||||
|
|
@ -77,8 +80,9 @@ import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
@ -88,6 +92,7 @@ import timber.log.Timber;
|
||||||
public class MediaDetailFragment extends CommonsDaggerSupportFragment implements Callback,
|
public class MediaDetailFragment extends CommonsDaggerSupportFragment implements Callback,
|
||||||
CategoryEditHelper.Callback {
|
CategoryEditHelper.Callback {
|
||||||
|
|
||||||
|
private static final int REQUEST_CODE = 1001 ;
|
||||||
private boolean editable;
|
private boolean editable;
|
||||||
private boolean isCategoryImage;
|
private boolean isCategoryImage;
|
||||||
private MediaDetailPagerFragment.MediaDetailProvider detailProvider;
|
private MediaDetailPagerFragment.MediaDetailProvider detailProvider;
|
||||||
|
|
@ -125,6 +130,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
@Inject
|
@Inject
|
||||||
CategoryEditHelper categoryEditHelper;
|
CategoryEditHelper categoryEditHelper;
|
||||||
@Inject
|
@Inject
|
||||||
|
CoordinateEditHelper coordinateEditHelper;
|
||||||
|
@Inject
|
||||||
ViewUtilWrapper viewUtil;
|
ViewUtilWrapper viewUtil;
|
||||||
@Inject
|
@Inject
|
||||||
CategoryClient categoryClient;
|
CategoryClient categoryClient;
|
||||||
|
|
@ -760,6 +767,75 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OnClick(R.id.coordinate_edit)
|
||||||
|
public void onUpdateCoordinatesClicked(){
|
||||||
|
goToLocationPickerActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start location picker activity with a request code and get the coordinates from the activity.
|
||||||
|
*/
|
||||||
|
private void goToLocationPickerActivity() {
|
||||||
|
/*
|
||||||
|
If location is not provided in media this coordinates will act as a placeholder in
|
||||||
|
location picker activity
|
||||||
|
*/
|
||||||
|
double defaultLatitude = 37.773972;
|
||||||
|
double defaultLongitude = -122.431297;
|
||||||
|
|
||||||
|
if (media.getCoordinates() != null) {
|
||||||
|
defaultLatitude = media.getCoordinates().getLatitude();
|
||||||
|
defaultLongitude = media.getCoordinates().getLongitude();
|
||||||
|
}
|
||||||
|
startActivityForResult(new LocationPicker.IntentBuilder()
|
||||||
|
.defaultLocation(new CameraPosition.Builder()
|
||||||
|
.target(new LatLng(defaultLatitude, defaultLongitude))
|
||||||
|
.zoom(16).build())
|
||||||
|
.build(getActivity()), REQUEST_CODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the coordinates and update the existing coordinates.
|
||||||
|
* @param requestCode
|
||||||
|
* @param resultCode
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(final int requestCode, final int resultCode,
|
||||||
|
@Nullable final Intent data) {
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
|
||||||
|
|
||||||
|
assert data != null;
|
||||||
|
final CameraPosition cameraPosition = LocationPicker.getCameraPosition(data);
|
||||||
|
|
||||||
|
if (cameraPosition != null) {
|
||||||
|
|
||||||
|
final String latitude = String.valueOf(cameraPosition.target.getLatitude());
|
||||||
|
final String longitude = String.valueOf(cameraPosition.target.getLongitude());
|
||||||
|
final String accuracy = String.valueOf(cameraPosition.target.getAltitude());
|
||||||
|
String currentLatitude = null;
|
||||||
|
String currentLongitude = null;
|
||||||
|
|
||||||
|
if (media.getCoordinates() != null) {
|
||||||
|
currentLatitude = String.valueOf(media.getCoordinates().getLatitude());
|
||||||
|
currentLongitude = String.valueOf(media.getCoordinates().getLongitude());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!latitude.equals(currentLatitude) || !longitude.equals(currentLongitude)) {
|
||||||
|
updateCoordinates(latitude, longitude, accuracy);
|
||||||
|
} else if (media.getCoordinates() == null) {
|
||||||
|
updateCoordinates(latitude, longitude, accuracy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (resultCode == RESULT_CANCELED) {
|
||||||
|
viewUtil.showShortToast(getContext(),
|
||||||
|
Objects.requireNonNull(getContext())
|
||||||
|
.getString(R.string.coordinates_picking_unsuccessful));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OnClick(R.id.update_categories_button)
|
@OnClick(R.id.update_categories_button)
|
||||||
public void onUpdateCategoriesClicked() {
|
public void onUpdateCategoriesClicked() {
|
||||||
updateCategories(categoryEditSearchRecyclerViewAdapter.getNewCategories());
|
updateCategories(categoryEditSearchRecyclerViewAdapter.getNewCategories());
|
||||||
|
|
@ -783,6 +859,24 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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) {
|
||||||
|
compositeDisposable.add(coordinateEditHelper.makeCoordinatesEdit(getContext(), media,
|
||||||
|
Latitude, Longitude, Accuracy)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(s -> {
|
||||||
|
Timber.d("Coordinates are added.");
|
||||||
|
coordinates.setText(prettyCoordinates(media));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("StringFormatInvalid")
|
@SuppressLint("StringFormatInvalid")
|
||||||
@OnClick(R.id.nominateDeletion)
|
@OnClick(R.id.nominateDeletion)
|
||||||
public void onDeleteButtonClicked(){
|
public void onDeleteButtonClicked(){
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
|
|
@ -101,19 +100,13 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
|
||||||
pager.addOnPageChangeListener(this);
|
pager.addOnPageChangeListener(this);
|
||||||
|
|
||||||
adapter = new MediaDetailAdapter(getChildFragmentManager());
|
adapter = new MediaDetailAdapter(getChildFragmentManager());
|
||||||
|
|
||||||
if (((BaseActivity) getActivity()).getSupportActionBar() != null) {
|
|
||||||
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
pager.setAdapter(adapter);
|
pager.setAdapter(adapter);
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
final int pageNumber = savedInstanceState.getInt("current-page");
|
final int pageNumber = savedInstanceState.getInt("current-page");
|
||||||
pager.setCurrentItem(pageNumber, false);
|
pager.setCurrentItem(pageNumber, false);
|
||||||
getActivity().invalidateOptionsMenu();
|
getActivity().invalidateOptionsMenu();
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
adapter.notifyDataSetChanged();
|
||||||
if (getActivity() instanceof MainActivity) {
|
if (getActivity() instanceof MainActivity) {
|
||||||
((MainActivity)getActivity()).hideTabs();
|
((MainActivity)getActivity()).hideTabs();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,11 +63,27 @@ public class Place implements Parcelable {
|
||||||
if(!StringUtils.isBlank(itemClass)) {
|
if(!StringUtils.isBlank(itemClass)) {
|
||||||
classEntityId = itemClass.replace("http://www.wikidata.org/entity/", "");
|
classEntityId = itemClass.replace("http://www.wikidata.org/entity/", "");
|
||||||
}
|
}
|
||||||
|
// Set description when not null and not empty
|
||||||
|
String description = (item.getDescription().getValue() != null && !item.getDescription().getValue().isEmpty()) ? item.getDescription().getValue() : "";
|
||||||
|
// When description is "?" but we have a valid label, just use the label. So replace "?" by "" in description
|
||||||
|
description = (description.equals("?")
|
||||||
|
&& (item.getLabel().getValue() != null
|
||||||
|
&& !item.getLabel().getValue().isEmpty()) ? "" : description);
|
||||||
|
/*
|
||||||
|
* If we have a valid label
|
||||||
|
* - If have a valid label add the description at the end of the string with parenthesis
|
||||||
|
* - If we don't have a valid label, string will include only the description. So add it without paranthesis
|
||||||
|
*/
|
||||||
|
description = ((item.getLabel().getValue() != null && !item.getLabel().getValue().isEmpty())
|
||||||
|
? item.getLabel().getValue()
|
||||||
|
+ ((description != null && !description.isEmpty())
|
||||||
|
? " (" + description + ")" : "")
|
||||||
|
: description);
|
||||||
return new Place(
|
return new Place(
|
||||||
item.getLabel().getLanguage(),
|
item.getLabel().getLanguage(),
|
||||||
item.getLabel().getValue(),
|
item.getLabel().getValue(),
|
||||||
Label.fromText(classEntityId), // list
|
Label.fromText(classEntityId), // list
|
||||||
item.getClassLabel().getValue(), // details
|
description, // description and label of Wikidata item
|
||||||
PlaceUtils.latLngFromPointString(item.getLocation().getValue()),
|
PlaceUtils.latLngFromPointString(item.getLocation().getValue()),
|
||||||
item.getCommonsCategory().getValue(),
|
item.getCommonsCategory().getValue(),
|
||||||
new Sitelinks.Builder()
|
new Sitelinks.Builder()
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,8 @@ fun placeAdapterDelegate(
|
||||||
tvDesc.setText(R.string.no_description_found)
|
tvDesc.setText(R.string.no_description_found)
|
||||||
tvDesc.visibility = INVISIBLE
|
tvDesc.visibility = INVISIBLE
|
||||||
} else {
|
} else {
|
||||||
tvDesc.text = descriptionText
|
// Remove the label and display only texts inside pharentheses (description) since too long
|
||||||
|
tvDesc.text = descriptionText.substringAfter(tvName.text.toString() + " (").substringBeforeLast(")");
|
||||||
}
|
}
|
||||||
distance.text = item.distance
|
distance.text = item.distance
|
||||||
icon.setImageResource(item.label.icon)
|
icon.setImageResource(item.label.icon)
|
||||||
|
|
|
||||||
|
|
@ -1521,7 +1521,12 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
||||||
|
|
||||||
title.setText(selectedPlace.name);
|
title.setText(selectedPlace.name);
|
||||||
distance.setText(selectedPlace.distance);
|
distance.setText(selectedPlace.distance);
|
||||||
description.setText(selectedPlace.getLongDescription());
|
// Remove label since it is double information
|
||||||
|
String descriptionText = selectedPlace.getLongDescription()
|
||||||
|
.replace(selectedPlace.getName() + " (","");
|
||||||
|
descriptionText = (descriptionText.equals(selectedPlace.getLongDescription()) ? descriptionText : descriptionText.replaceFirst(".$",""));
|
||||||
|
// Set the short description after we remove place name from long description
|
||||||
|
description.setText(descriptionText);
|
||||||
|
|
||||||
fabCamera.setOnClickListener(view -> {
|
fabCamera.setOnClickListener(view -> {
|
||||||
if (fabCamera.isShown()) {
|
if (fabCamera.isShown()) {
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ class NearbyResultItem(private val item: ResultTuple?,
|
||||||
@field:SerializedName("commonsCategory") private val commonsCategory: ResultTuple?,
|
@field:SerializedName("commonsCategory") private val commonsCategory: ResultTuple?,
|
||||||
@field:SerializedName("pic") private val pic: ResultTuple?,
|
@field:SerializedName("pic") private val pic: ResultTuple?,
|
||||||
@field:SerializedName("destroyed") private val destroyed: ResultTuple?,
|
@field:SerializedName("destroyed") private val destroyed: ResultTuple?,
|
||||||
|
@field:SerializedName("description") private val description: ResultTuple?,
|
||||||
@field:SerializedName("endTime") private val endTime: ResultTuple?) {
|
@field:SerializedName("endTime") private val endTime: ResultTuple?) {
|
||||||
|
|
||||||
fun getItem(): ResultTuple {
|
fun getItem(): ResultTuple {
|
||||||
|
|
@ -58,8 +59,11 @@ class NearbyResultItem(private val item: ResultTuple?,
|
||||||
return destroyed ?: ResultTuple()
|
return destroyed ?: ResultTuple()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getDescription(): ResultTuple {
|
||||||
|
return description ?: ResultTuple()
|
||||||
|
}
|
||||||
|
|
||||||
fun getEndTime(): ResultTuple {
|
fun getEndTime(): ResultTuple {
|
||||||
return endTime ?: ResultTuple()
|
return endTime ?: ResultTuple()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ public class NotificationHelper {
|
||||||
|
|
||||||
public static final int NOTIFICATION_DELETE = 1;
|
public static final int NOTIFICATION_DELETE = 1;
|
||||||
public static final int NOTIFICATION_EDIT_CATEGORY = 2;
|
public static final int NOTIFICATION_EDIT_CATEGORY = 2;
|
||||||
|
public static final int NOTIFICATION_EDIT_COORDINATES = 3;
|
||||||
|
|
||||||
private NotificationManager notificationManager;
|
private NotificationManager notificationManager;
|
||||||
private NotificationCompat.Builder notificationBuilder;
|
private NotificationCompat.Builder notificationBuilder;
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ public class UploadActivity extends BaseActivity implements UploadContract.View,
|
||||||
public void makeUploadRequest() {
|
public void makeUploadRequest() {
|
||||||
WorkManager.getInstance(getApplicationContext()).enqueueUniqueWork(
|
WorkManager.getInstance(getApplicationContext()).enqueueUniqueWork(
|
||||||
UploadWorker.class.getSimpleName(),
|
UploadWorker.class.getSimpleName(),
|
||||||
ExistingWorkPolicy.KEEP, OneTimeWorkRequest.from(UploadWorker.class));
|
ExistingWorkPolicy.APPEND_OR_REPLACE, OneTimeWorkRequest.from(UploadWorker.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import androidx.work.CoroutineWorker
|
import androidx.work.CoroutineWorker
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.mapbox.mapboxsdk.plugins.localization.BuildConfig
|
import com.mapbox.mapboxsdk.plugins.localization.BuildConfig
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import fr.free.nrw.commons.CommonsApplication
|
import fr.free.nrw.commons.CommonsApplication
|
||||||
|
|
@ -146,15 +147,12 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
||||||
CommonsApplication.NOTIFICATION_CHANNEL_ID_ALL
|
CommonsApplication.NOTIFICATION_CHANNEL_ID_ALL
|
||||||
)!!
|
)!!
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
//Doing this so that retry requests do not create new work requests and while a work is
|
|
||||||
// already running, all the requests should go through this, so kind of a queue
|
|
||||||
while (contributionDao.getContribution(statesToProcess)
|
|
||||||
.blockingGet().isNotEmpty()
|
|
||||||
) {
|
|
||||||
val queuedContributions = contributionDao.getContribution(statesToProcess)
|
val queuedContributions = contributionDao.getContribution(statesToProcess)
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
//Showing initial notification for the number of uploads being processed
|
//Showing initial notification for the number of uploads being processed
|
||||||
|
|
||||||
|
Timber.e("Queued Contributions: "+ queuedContributions.size)
|
||||||
|
|
||||||
processingUploads.setContentTitle(appContext.getString(R.string.starting_uploads))
|
processingUploads.setContentTitle(appContext.getString(R.string.starting_uploads))
|
||||||
processingUploads.setContentText(
|
processingUploads.setContentText(
|
||||||
appContext.resources.getQuantityString(
|
appContext.resources.getQuantityString(
|
||||||
|
|
@ -169,6 +167,15 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
||||||
processingUploads.build()
|
processingUploads.build()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To avoid race condition when multiple of these workers are working, assign this state
|
||||||
|
so that the next one does not process these contribution again
|
||||||
|
*/
|
||||||
|
queuedContributions.forEach {
|
||||||
|
it.state=Contribution.STATE_IN_PROGRESS
|
||||||
|
contributionDao.saveSynchronous(it)
|
||||||
|
}
|
||||||
|
|
||||||
queuedContributions.asFlow().map { contribution ->
|
queuedContributions.asFlow().map { contribution ->
|
||||||
/**
|
/**
|
||||||
* If the limited connection mode is on, lets iterate through the queued
|
* If the limited connection mode is on, lets iterate through the queued
|
||||||
|
|
@ -179,12 +186,12 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
||||||
if (isLimitedConnectionModeEnabled()) {
|
if (isLimitedConnectionModeEnabled()) {
|
||||||
if (contribution.state == Contribution.STATE_QUEUED) {
|
if (contribution.state == Contribution.STATE_QUEUED) {
|
||||||
contribution.state = Contribution.STATE_QUEUED_LIMITED_CONNECTION_MODE
|
contribution.state = Contribution.STATE_QUEUED_LIMITED_CONNECTION_MODE
|
||||||
contributionDao.save(contribution)
|
contributionDao.saveSynchronous(contribution)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
contribution.transferred = 0
|
contribution.transferred = 0
|
||||||
contribution.state = Contribution.STATE_IN_PROGRESS
|
contribution.state = Contribution.STATE_IN_PROGRESS
|
||||||
contributionDao.save(contribution)
|
contributionDao.saveSynchronous(contribution)
|
||||||
uploadContribution(contribution = contribution)
|
uploadContribution(contribution = contribution)
|
||||||
}
|
}
|
||||||
}.collect()
|
}.collect()
|
||||||
|
|
@ -194,13 +201,6 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
||||||
PROCESSING_UPLOADS_NOTIFICATION_TAG,
|
PROCESSING_UPLOADS_NOTIFICATION_TAG,
|
||||||
PROCESSING_UPLOADS_NOTIFICATION_ID
|
PROCESSING_UPLOADS_NOTIFICATION_ID
|
||||||
)
|
)
|
||||||
|
|
||||||
//No need to keep looking if the limited connection mode is on,
|
|
||||||
//If the user toggles it, the work manager will be started again
|
|
||||||
if(isLimitedConnectionModeEnabled()){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//TODO make this smart, think of handling retries in the future
|
//TODO make this smart, think of handling retries in the future
|
||||||
return Result.success()
|
return Result.success()
|
||||||
|
|
@ -307,6 +307,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
||||||
Timber.e(exception)
|
Timber.e(exception)
|
||||||
Timber.e("Upload from stash failed for contribution : $filename")
|
Timber.e("Upload from stash failed for contribution : $filename")
|
||||||
showFailedNotification(contribution)
|
showFailedNotification(contribution)
|
||||||
|
contribution.state=Contribution.STATE_FAILED
|
||||||
if (STASH_ERROR_CODES.contains(exception.message)) {
|
if (STASH_ERROR_CODES.contains(exception.message)) {
|
||||||
clearChunks(contribution)
|
clearChunks(contribution)
|
||||||
}
|
}
|
||||||
|
|
@ -315,26 +316,28 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
|
||||||
StashUploadState.PAUSED -> {
|
StashUploadState.PAUSED -> {
|
||||||
showPausedNotification(contribution)
|
showPausedNotification(contribution)
|
||||||
contribution.state = Contribution.STATE_PAUSED
|
contribution.state = Contribution.STATE_PAUSED
|
||||||
contributionDao.save(contribution).blockingGet()
|
contributionDao.saveSynchronous(contribution)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Timber.e("""upload file to stash failed with status: ${stashUploadResult.state}""")
|
Timber.e("""upload file to stash failed with status: ${stashUploadResult.state}""")
|
||||||
showFailedNotification(contribution)
|
showFailedNotification(contribution)
|
||||||
contribution.state = Contribution.STATE_FAILED
|
contribution.state = Contribution.STATE_FAILED
|
||||||
contribution.chunkInfo = null
|
contribution.chunkInfo = null
|
||||||
contributionDao.save(contribution).blockingAwait()
|
contributionDao.saveSynchronous(contribution)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}catch (exception: Exception){
|
}catch (exception: Exception){
|
||||||
Timber.e(exception)
|
Timber.e(exception)
|
||||||
Timber.e("Stash upload failed for contribution: $filename")
|
Timber.e("Stash upload failed for contribution: $filename")
|
||||||
showFailedNotification(contribution)
|
showFailedNotification(contribution)
|
||||||
|
contribution.state=Contribution.STATE_FAILED
|
||||||
|
clearChunks(contribution)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearChunks(contribution: Contribution) {
|
private fun clearChunks(contribution: Contribution) {
|
||||||
contribution.chunkInfo=null
|
contribution.chunkInfo=null
|
||||||
contributionDao.save(contribution).blockingAwait()
|
contributionDao.saveSynchronous(contribution)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
BIN
app/src/main/res/drawable-hdpi/map_default_map_marker.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
app/src/main/res/drawable-hdpi/map_default_map_marker_shadow.png
Normal file
|
After Width: | Height: | Size: 778 B |
BIN
app/src/main/res/drawable-hdpi/mapbox_logo_icon.png
Normal file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
app/src/main/res/drawable-mdpi/map_default_map_marker.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
app/src/main/res/drawable-mdpi/map_default_map_marker_shadow.png
Normal file
|
After Width: | Height: | Size: 474 B |
BIN
app/src/main/res/drawable-mdpi/mapbox_logo_icon.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
app/src/main/res/drawable-xhdpi/map_default_map_marker.png
Normal file
|
After Width: | Height: | Size: 6 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xhdpi/mapbox_logo_icon.png
Normal file
|
After Width: | Height: | Size: 6.4 KiB |
BIN
app/src/main/res/drawable-xxhdpi/map_default_map_marker.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
BIN
app/src/main/res/drawable-xxhdpi/mapbox_logo_icon.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/map_default_map_marker.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/mapbox_logo_icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
20
app/src/main/res/layout/activity_location_picker.xml
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".LocationPicker.LocationPickerActivity">
|
||||||
|
|
||||||
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
|
android:id="@+id/location_picker_app_bar_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<include layout="@layout/toolbar_location_picker"/>
|
||||||
|
|
||||||
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
|
<include layout="@layout/content_location_picker"/>
|
||||||
|
|
||||||
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
35
app/src/main/res/layout/bottom_container_location_picker.xml
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="bottom">
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
|
android:id="@+id/location_chosen_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:tint="@color/white"
|
||||||
|
app:backgroundTint="@color/wikimedia_green"
|
||||||
|
app:elevation="3dp"
|
||||||
|
app:layout_anchorGravity="top|end"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_check_black_24dp"
|
||||||
|
android:contentDescription="@string/select_location_location_picker" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatTextView
|
||||||
|
android:id="@+id/tv_attribution"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:text="@string/map_attribution"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textSize="10sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
49
app/src/main/res/layout/content_location_picker.xml
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/location_picker_image_view_marker"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:elevation="2dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/map_default_map_marker"
|
||||||
|
android:contentDescription="@string/location_picker_image_view" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/location_picker_image_view_shadow"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:elevation="1dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/map_view"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/location_picker_image_view_marker"
|
||||||
|
app:layout_constraintVertical_bias="0.0"
|
||||||
|
app:srcCompat="@drawable/map_default_map_marker_shadow"
|
||||||
|
android:contentDescription="@string/location_picker_image_view_shadow" />
|
||||||
|
|
||||||
|
<com.mapbox.mapboxsdk.maps.MapView
|
||||||
|
android:id="@+id/map_view"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
app:mapbox_uiLogo="false"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
</com.mapbox.mapboxsdk.maps.MapView>
|
||||||
|
|
||||||
|
<include layout="@layout/bottom_container_location_picker"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -249,6 +249,16 @@
|
||||||
android:drawablePadding="@dimen/tiny_gap"
|
android:drawablePadding="@dimen/tiny_gap"
|
||||||
android:drawableStart="?attr/iconMap24"
|
android:drawableStart="?attr/iconMap24"
|
||||||
tools:text="Coordinates link" />
|
tools:text="Coordinates link" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/coordinate_edit"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginTop="@dimen/standard_gap"
|
||||||
|
android:layout_marginBottom="@dimen/standard_gap"
|
||||||
|
android:layout_gravity="end"
|
||||||
|
android:background="@drawable/ic_baseline_edit_24" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|
|
||||||
50
app/src/main/res/layout/toolbar_location_picker.xml
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/location_picker_toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="78dp"
|
||||||
|
tools:background="@color/primaryColor">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/location_picker_toolbar_primary_text_view"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="72dp"
|
||||||
|
android:text="@string/choose_a_location"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/location_picker_toolbar_secondary_text_view"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/location_picker_toolbar_secondary_text_view"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="72dp"
|
||||||
|
android:text="@string/pan_and_zoom_to_adjust"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="normal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/location_picker_toolbar_primary_text_view"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/mapbox_place_picker_toolbar_back_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:contentDescription="@string/exit_location_picker"
|
||||||
|
android:tint="@color/white"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:srcCompat="@drawable/ic_arrow_back_white"/>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -265,6 +265,7 @@
|
||||||
<string name="upload_problem_different_geolocation">تم التقاط هذه الصورة في موقع مختلف.</string>
|
<string name="upload_problem_different_geolocation">تم التقاط هذه الصورة في موقع مختلف.</string>
|
||||||
<string name="upload_problem_fbmd">من فضلك فقط ارفع الصور التي التقطها بنفسك. لا ترفع الصور التي وجدتها على حسابات الآخرين في فيسبوك.</string>
|
<string name="upload_problem_fbmd">من فضلك فقط ارفع الصور التي التقطها بنفسك. لا ترفع الصور التي وجدتها على حسابات الآخرين في فيسبوك.</string>
|
||||||
<string name="upload_problem_do_you_continue">هل ما زلت تريد رفع هذه الصورة؟</string>
|
<string name="upload_problem_do_you_continue">هل ما زلت تريد رفع هذه الصورة؟</string>
|
||||||
|
<string name="upload_connection_error_alert_title">خطأ في الاتصال</string>
|
||||||
<string name="upload_problem_image">تم العثور على مشاكل في الصورة</string>
|
<string name="upload_problem_image">تم العثور على مشاكل في الصورة</string>
|
||||||
<string name="internet_downloaded">يُرجَى فقط رفع الصور التي التقطتها بنفسك، لا ترفع الصور التي قمت بتنزيلها من الإنترنت.</string>
|
<string name="internet_downloaded">يُرجَى فقط رفع الصور التي التقطتها بنفسك، لا ترفع الصور التي قمت بتنزيلها من الإنترنت.</string>
|
||||||
<string name="use_external_storage" fuzzy="true">استخدم تخزينا خارجيا</string>
|
<string name="use_external_storage" fuzzy="true">استخدم تخزينا خارجيا</string>
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Dieses Bild wurde an einem anderen Ort aufgenommen.</string>
|
<string name="upload_problem_different_geolocation">Dieses Bild wurde an einem anderen Ort aufgenommen.</string>
|
||||||
<string name="upload_problem_fbmd">Lade bitte nur Bilder hoch, die du selber erstellt hast. Lade keine Bilder hoch, die du auf Facebook-Konten anderer Personen gefunden hast.</string>
|
<string name="upload_problem_fbmd">Lade bitte nur Bilder hoch, die du selber erstellt hast. Lade keine Bilder hoch, die du auf Facebook-Konten anderer Personen gefunden hast.</string>
|
||||||
<string name="upload_problem_do_you_continue">Möchtest du immer noch dieses Bild hochladen?</string>
|
<string name="upload_problem_do_you_continue">Möchtest du immer noch dieses Bild hochladen?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Verbindungsfehler</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Der Hochlade-Vorgang erfordert einen aktiven Internetzugang. Bitte prüfe deine Netzwerkverbindung.</string>
|
||||||
<string name="upload_problem_image">Im Bild gefundene Probleme</string>
|
<string name="upload_problem_image">Im Bild gefundene Probleme</string>
|
||||||
<string name="internet_downloaded">Lade bitte nur Bilder hoch, die du selber aufgenommen hast. Lade keine Bilder hoch, die du aus dem Internet heruntergeladen hast.</string>
|
<string name="internet_downloaded">Lade bitte nur Bilder hoch, die du selber aufgenommen hast. Lade keine Bilder hoch, die du aus dem Internet heruntergeladen hast.</string>
|
||||||
<string name="use_external_storage">Speichern von In-App-Aufnahmen</string>
|
<string name="use_external_storage">Speichern von In-App-Aufnahmen</string>
|
||||||
|
|
@ -498,6 +500,12 @@
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="category_edit_helper_edit_message_else">Konnte keine Kategorien hinzufügen.</string>
|
<string name="category_edit_helper_edit_message_else">Konnte keine Kategorien hinzufügen.</string>
|
||||||
<string name="category_edit_button_text">Kategorien aktualisieren</string>
|
<string name="category_edit_button_text">Kategorien aktualisieren</string>
|
||||||
|
<string name="coordinates_edit_helper_make_edit_toast">Versuche, die Koordinaten zu aktualisieren.</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title">Koordinaten aktualisieren</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title_success">Erfolgreich</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_message">Koordinaten %1$s werden hinzugefügt.</string>
|
||||||
|
<string name="coordinates_edit_helper_edit_message_else">Koordinaten konnten nicht hinzugefügt werden.</string>
|
||||||
|
<string name="coordinates_picking_unsuccessful">Es können keine Koordinaten abgerufen werden.</string>
|
||||||
<string name="share_image_via">Bild teilen via</string>
|
<string name="share_image_via">Bild teilen via</string>
|
||||||
<string name="no_achievements_yet">Du hast noch keine Beiträge geleistet</string>
|
<string name="no_achievements_yet">Du hast noch keine Beiträge geleistet</string>
|
||||||
<string name="account_created">Benutzerkonto erstellt!</string>
|
<string name="account_created">Benutzerkonto erstellt!</string>
|
||||||
|
|
@ -574,8 +582,21 @@
|
||||||
<string name="quality_images_info">Qualitätsbilder sind Diagramme oder Fotografien, die bestimmte Qualitätsstandards erfüllen (die meist technischer Natur sind) und für Wikimedia-Projekte wertvoll sind</string>
|
<string name="quality_images_info">Qualitätsbilder sind Diagramme oder Fotografien, die bestimmte Qualitätsstandards erfüllen (die meist technischer Natur sind) und für Wikimedia-Projekte wertvoll sind</string>
|
||||||
<string name="resuming_upload">Hochladen fortsetzen …</string>
|
<string name="resuming_upload">Hochladen fortsetzen …</string>
|
||||||
<string name="pausing_upload">Hochladen pausieren …</string>
|
<string name="pausing_upload">Hochladen pausieren …</string>
|
||||||
|
<string name="limited_connection_explanation">Du hast den eingeschränkten Verbindungsmodus aktiviert. Alle Uploads sind angehalten und werden fortgesetzt, sobald du diesen Modus deaktivierst.</string>
|
||||||
|
<string name="limited_connection_is_on">Der begrenzte Verbindungsmodus ist aktiv.</string>
|
||||||
|
<string name="media_details_tooltip">Bitte schreibe eine kurze Bildunterschrift, die sagt, was dein Bild zeigt. Sage in der Beschreibung, was das Bild interessant oder typisch oder selten macht, und erkläree den Kontext, sichtbar oder nicht. Verwende möglichst genaue Begriffe.</string>
|
||||||
|
<string name="depicts_tooltip">Bitte finde und wähle alle Benennungen, die dieses Bild darstellt. Sei so spezifisch wie möglich. Wenn das Bild mehrere Begriffe darstellt, wähle sie alle in angemessener Weise aus. Wähle keine generischen Begriffe, wenn spezifischere Begriffe verfügbar sind.</string>
|
||||||
|
<string name="categories_tooltip">Bitte wähle die entsprechenden Kategorien aus. Im Gegensatz zu den Darstellungen sind die Kategorien nur in Englisch.</string>
|
||||||
|
<string name="license_tooltip">Commons macht deine Bilder wiederverwendbar und von jedem adaptierbar. Möchtest du auf alle Rechte verzichten? Möchtest du als Urheber genannt werden? Möchtest du, dass Bearbeitungen die gleiche Lizenz verwenden?</string>
|
||||||
|
<string name="depicts_step_title">Stellt dar</string>
|
||||||
<string name="license_step_title">Medienlizenz</string>
|
<string name="license_step_title">Medienlizenz</string>
|
||||||
<string name="media_detail_step_title">Mediendetails</string>
|
<string name="media_detail_step_title">Mediendetails</string>
|
||||||
<string name="menu_view_category_page">Kategorieseite anzeigen</string>
|
<string name="menu_view_category_page">Kategorieseite anzeigen</string>
|
||||||
|
<string name="app_ui_language">Benutzeroberflächensprache</string>
|
||||||
<string name="read_help_link">Mehr lesen</string>
|
<string name="read_help_link">Mehr lesen</string>
|
||||||
|
<string name="choose_a_location">Wähle einen Ort</string>
|
||||||
|
<string name="pan_and_zoom_to_adjust">Schwenken und Zoomen zum Einstellen</string>
|
||||||
|
<string name="exit_location_picker">Beenden der Ortswahl</string>
|
||||||
|
<string name="select_location_location_picker">Ort auswählen</string>
|
||||||
|
<string name="location_picker_image_view">Ortauswahl Bildansicht</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
* Gomoko
|
* Gomoko
|
||||||
* Happy13241
|
* Happy13241
|
||||||
* Jean-Frédéric
|
* Jean-Frédéric
|
||||||
|
* JenyxGym
|
||||||
* KATRINE1992
|
* KATRINE1992
|
||||||
* Melissadeba95
|
* Melissadeba95
|
||||||
* Metroitendo
|
* Metroitendo
|
||||||
|
|
@ -252,6 +253,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Cette image a été prise à un emplacement différent.</string>
|
<string name="upload_problem_different_geolocation">Cette image a été prise à un emplacement différent.</string>
|
||||||
<string name="upload_problem_fbmd">Veuillez ne téléverser que des images que vous avez prises vous-même. Ne téléversez aucune image prise sur les comptes Facebook d’autres personnes.</string>
|
<string name="upload_problem_fbmd">Veuillez ne téléverser que des images que vous avez prises vous-même. Ne téléversez aucune image prise sur les comptes Facebook d’autres personnes.</string>
|
||||||
<string name="upload_problem_do_you_continue">Voulez-vous tout de même téléverser cette image ?</string>
|
<string name="upload_problem_do_you_continue">Voulez-vous tout de même téléverser cette image ?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Erreur de connexion</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Le processus de téléchargement nécessite un accès internet\n actif. Veuillez vérifier votre connexion internet.</string>
|
||||||
<string name="upload_problem_image">Problèmes trouvés dans l’image</string>
|
<string name="upload_problem_image">Problèmes trouvés dans l’image</string>
|
||||||
<string name="internet_downloaded">Veuillez ne téléverser que des images que vous avez prises vous-même. Ne téléversez aucune image que vous avez téléchargée depuis Internet.</string>
|
<string name="internet_downloaded">Veuillez ne téléverser que des images que vous avez prises vous-même. Ne téléversez aucune image que vous avez téléchargée depuis Internet.</string>
|
||||||
<string name="use_external_storage">Enregistrer les prises de vue dans l’application</string>
|
<string name="use_external_storage">Enregistrer les prises de vue dans l’application</string>
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
<string name="provider_contributions">Mi incargamentos</string>
|
<string name="provider_contributions">Mi incargamentos</string>
|
||||||
<string name="menu_share">Divider</string>
|
<string name="menu_share">Divider</string>
|
||||||
<string name="write_storage_permission_rationale">Permission necessari: Scriber sur immagazinage externe. Le app non pote acceder a tu camera/galeria sin isto.</string>
|
<string name="write_storage_permission_rationale">Permission necessari: Scriber sur immagazinage externe. Le app non pote acceder a tu camera/galeria sin isto.</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Error de connexion</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Le processo de incargamento require un accesso a internet active. Per favor verifica tu connexion al rete.</string>
|
||||||
<string name="use_external_storage">Salveguardar photos prendite in app</string>
|
<string name="use_external_storage">Salveguardar photos prendite in app</string>
|
||||||
<string name="use_external_storage_summary">Salveguardar le photos prendite con le camera del application sur le immagazinage de tu apparato</string>
|
<string name="use_external_storage_summary">Salveguardar le photos prendite con le camera del application sur le immagazinage de tu apparato</string>
|
||||||
<string name="nearby_location_not_available">\"A proximitate\" poterea non functionar, perque le position geographic non es disponibile.</string>
|
<string name="nearby_location_not_available">\"A proximitate\" poterea non functionar, perque le position geographic non es disponibile.</string>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
* Arifin.wijaya
|
* Arifin.wijaya
|
||||||
* Daud I.F. Argana
|
* Daud I.F. Argana
|
||||||
* Farras
|
* Farras
|
||||||
|
* Gombang
|
||||||
* Hidayatsrf
|
* Hidayatsrf
|
||||||
* Ilham151096
|
* Ilham151096
|
||||||
* Iwan Novirion
|
* Iwan Novirion
|
||||||
|
|
@ -21,10 +22,10 @@
|
||||||
<item quantity="other">(%1$d)</item>
|
<item quantity="other">(%1$d)</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="starting_uploads">Memulai Unggahan</string>
|
<string name="starting_uploads">Memulai Unggahan</string>
|
||||||
<plurals name="starting_multiple_uploads" fuzzy="true">
|
<plurals name="starting_multiple_uploads">
|
||||||
<item quantity="other">Memulai %1$d unggahan</item>
|
<item quantity="other">Memroses %1$d unggahan</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="multiple_uploads_title" fuzzy="true">
|
<plurals name="multiple_uploads_title">
|
||||||
<item quantity="other">%1$d unggahan</item>
|
<item quantity="other">%1$d unggahan</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="share_license_summary">
|
<plurals name="share_license_summary">
|
||||||
|
|
@ -61,7 +62,7 @@
|
||||||
<string name="uploading_queued">Unggahan dalam antrian (mode sambungan terbatas diaktifkan)</string>
|
<string name="uploading_queued">Unggahan dalam antrian (mode sambungan terbatas diaktifkan)</string>
|
||||||
<string name="upload_completed_notification_title">%1$s terunggah!</string>
|
<string name="upload_completed_notification_title">%1$s terunggah!</string>
|
||||||
<string name="upload_completed_notification_text">Tekan untuk melihat unggahan Anda</string>
|
<string name="upload_completed_notification_text">Tekan untuk melihat unggahan Anda</string>
|
||||||
<string name="upload_progress_notification_title_start" fuzzy="true">Memulai unggahan %1$s</string>
|
<string name="upload_progress_notification_title_start">Mengunggah berkas: %1$s</string>
|
||||||
<string name="upload_progress_notification_title_in_progress">%1$s terunggah!</string>
|
<string name="upload_progress_notification_title_in_progress">%1$s terunggah!</string>
|
||||||
<string name="upload_progress_notification_title_finishing">Menyelesaikan pengunggahan %1$s</string>
|
<string name="upload_progress_notification_title_finishing">Menyelesaikan pengunggahan %1$s</string>
|
||||||
<string name="upload_failed_notification_title">Mengunggah %1$s gagal</string>
|
<string name="upload_failed_notification_title">Mengunggah %1$s gagal</string>
|
||||||
|
|
@ -229,6 +230,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Gambar diambil di lokasi berbeda.</string>
|
<string name="upload_problem_different_geolocation">Gambar diambil di lokasi berbeda.</string>
|
||||||
<string name="upload_problem_fbmd">Tolong hanya unggah gambar-gambar yang Anda ambil sendiri. Jangan unggah gambar yang Anda temukan di akun Facebook orang lain.</string>
|
<string name="upload_problem_fbmd">Tolong hanya unggah gambar-gambar yang Anda ambil sendiri. Jangan unggah gambar yang Anda temukan di akun Facebook orang lain.</string>
|
||||||
<string name="upload_problem_do_you_continue">Apakah Anda masih ingin mengunggah gambar ini?</string>
|
<string name="upload_problem_do_you_continue">Apakah Anda masih ingin mengunggah gambar ini?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Kesalahan koneksi</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Proses pengunggahan memerlukan akses internet aktif. Mohon periksa sambungan jaringan Anda.</string>
|
||||||
<string name="upload_problem_image">Masalah dalam gambar ditemukan</string>
|
<string name="upload_problem_image">Masalah dalam gambar ditemukan</string>
|
||||||
<string name="internet_downloaded">Unggah hanya gambar yang sudah Anda potret sendiri. Jangan unggah gambar yang Anda ambil dari Internet.</string>
|
<string name="internet_downloaded">Unggah hanya gambar yang sudah Anda potret sendiri. Jangan unggah gambar yang Anda ambil dari Internet.</string>
|
||||||
<string name="use_external_storage">Simpan foto dalam aplikasi</string>
|
<string name="use_external_storage">Simpan foto dalam aplikasi</string>
|
||||||
|
|
@ -418,8 +421,8 @@
|
||||||
<string name="review_category_explanation">Gambar ini ada dalam kategori %1$s.</string>
|
<string name="review_category_explanation">Gambar ini ada dalam kategori %1$s.</string>
|
||||||
<string name="review_spam_report_question">Di luar cakupan karena</string>
|
<string name="review_spam_report_question">Di luar cakupan karena</string>
|
||||||
<string name="review_c_violation_report_question">Pelanggaran hak cipta karena</string>
|
<string name="review_c_violation_report_question">Pelanggaran hak cipta karena</string>
|
||||||
<string name="review_thanks_yes_button_text" fuzzy="true">Ya, mengapa tidak</string>
|
<string name="review_thanks_yes_button_text">Gambar selanjutnya</string>
|
||||||
<string name="review_thanks_no_button_text" fuzzy="true">Gambar selanjutnya</string>
|
<string name="review_thanks_no_button_text">Ya, mengapa tidak</string>
|
||||||
<string name="skip_image_explanation">Menekan tombol ini akan memberikan Anda gambar lain yang baru diunggah dari Wikimedia Commons</string>
|
<string name="skip_image_explanation">Menekan tombol ini akan memberikan Anda gambar lain yang baru diunggah dari Wikimedia Commons</string>
|
||||||
<string name="review_image_explanation">Anda dapat meninjau gambar dan meningkatkan kualitas Wikimedia Commons.\n Empat parameter peninjauan adalah: \n - Apakah gambar ini di dalam cakupan? \n - Apakah gambar ini mengikut aturan hak cipta? \n - Apakah gambar ini dikategorikan dengan benar? \n - Jika semuanya berjalan lancar Anda juga bisa berterima kasih kepada kontributor.</string>
|
<string name="review_image_explanation">Anda dapat meninjau gambar dan meningkatkan kualitas Wikimedia Commons.\n Empat parameter peninjauan adalah: \n - Apakah gambar ini di dalam cakupan? \n - Apakah gambar ini mengikut aturan hak cipta? \n - Apakah gambar ini dikategorikan dengan benar? \n - Jika semuanya berjalan lancar Anda juga bisa berterima kasih kepada kontributor.</string>
|
||||||
<string name="no_image">Tidak ada gambar digunakan</string>
|
<string name="no_image">Tidak ada gambar digunakan</string>
|
||||||
|
|
@ -435,6 +438,8 @@
|
||||||
<string name="images_featured_explanation">Gambar pilihan adalah gambar dari fotografer dan ilustrator berkemampuan tinggi yang komunitas Wikimedia Commons telah pilih sebagai salah satu gambar dengan kualitas tertinggi di situs ini.</string>
|
<string name="images_featured_explanation">Gambar pilihan adalah gambar dari fotografer dan ilustrator berkemampuan tinggi yang komunitas Wikimedia Commons telah pilih sebagai salah satu gambar dengan kualitas tertinggi di situs ini.</string>
|
||||||
<string name="images_via_nearby_explanation">Gambar Diunggah via Tempat sekitar adalah gambar yang diunggah dengan menemukan tempat di peta.</string>
|
<string name="images_via_nearby_explanation">Gambar Diunggah via Tempat sekitar adalah gambar yang diunggah dengan menemukan tempat di peta.</string>
|
||||||
<string name="thanks_received_explanation">Fitur ini memungkinkan penyunting mengirimkan sebuah pemberitahuan Terima kasih kepada pengguna yang membuat suntingan yang berguna – dengan menggunakan tautan terima kasih kecil di halaman riwayat atau \'\'diff\'\'.</string>
|
<string name="thanks_received_explanation">Fitur ini memungkinkan penyunting mengirimkan sebuah pemberitahuan Terima kasih kepada pengguna yang membuat suntingan yang berguna – dengan menggunakan tautan terima kasih kecil di halaman riwayat atau \'\'diff\'\'.</string>
|
||||||
|
<string name="copy_image_caption_description">Salin ke media berikutnya</string>
|
||||||
|
<string name="copied_successfully">Berhasil disalin</string>
|
||||||
<string name="welcome_do_upload_content_description">Contoh gambar yang sebaiknya diunggah ke Commons</string>
|
<string name="welcome_do_upload_content_description">Contoh gambar yang sebaiknya diunggah ke Commons</string>
|
||||||
<string name="welcome_dont_upload_content_description">Contoh gambar yang sebaiknya tidak diunggah</string>
|
<string name="welcome_dont_upload_content_description">Contoh gambar yang sebaiknya tidak diunggah</string>
|
||||||
<string name="skip_image">Lewati gambar ini</string>
|
<string name="skip_image">Lewati gambar ini</string>
|
||||||
|
|
@ -573,4 +578,7 @@
|
||||||
<string name="media_detail_step_title">Detail Media</string>
|
<string name="media_detail_step_title">Detail Media</string>
|
||||||
<string name="menu_view_category_page">Lihat halaman kategori</string>
|
<string name="menu_view_category_page">Lihat halaman kategori</string>
|
||||||
<string name="menu_view_item_page">Lihat halaman butir</string>
|
<string name="menu_view_item_page">Lihat halaman butir</string>
|
||||||
|
<string name="app_ui_language">Bahasa antarmuka pengguna aplikasi</string>
|
||||||
|
<string name="remove">Menghapus takarir dan deskripsi</string>
|
||||||
|
<string name="read_help_link">Baca lebih lanjut</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,8 @@
|
||||||
<string name="upload_problem_different_geolocation">התמונה צולמה במקום אחר.</string>
|
<string name="upload_problem_different_geolocation">התמונה צולמה במקום אחר.</string>
|
||||||
<string name="upload_problem_fbmd">נא להעלות רק תמונות שהעלית בעצמך. לא להעלות תמונות שמצאת בחשבונות של כל מיני אנשים בפייסבוק.</string>
|
<string name="upload_problem_fbmd">נא להעלות רק תמונות שהעלית בעצמך. לא להעלות תמונות שמצאת בחשבונות של כל מיני אנשים בפייסבוק.</string>
|
||||||
<string name="upload_problem_do_you_continue">האם ברצונך עדיין להעלות את התמונה הזאת?</string>
|
<string name="upload_problem_do_you_continue">האם ברצונך עדיין להעלות את התמונה הזאת?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">שגיאת חיבור</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">תהליך ההעלאה דורש גישה פעילה לאינטרנט. נא לבדוק את חיבור הרשת שלך.</string>
|
||||||
<string name="upload_problem_image">נמצאו בעיות בתמונה</string>
|
<string name="upload_problem_image">נמצאו בעיות בתמונה</string>
|
||||||
<string name="internet_downloaded">נא להעלות רק תמונות שצילמת בעצמך. לא להעלות תמונות שהורדת מהאינטרנט.</string>
|
<string name="internet_downloaded">נא להעלות רק תמונות שצילמת בעצמך. לא להעלות תמונות שהורדת מהאינטרנט.</string>
|
||||||
<string name="use_external_storage">שמירת צילומים מתוך היישומון</string>
|
<string name="use_external_storage">שמירת צילומים מתוך היישומון</string>
|
||||||
|
|
@ -511,6 +513,12 @@
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="category_edit_helper_edit_message_else">לא ניתן להוסיף קטגוריות.</string>
|
<string name="category_edit_helper_edit_message_else">לא ניתן להוסיף קטגוריות.</string>
|
||||||
<string name="category_edit_button_text">עדכון קטגוריות</string>
|
<string name="category_edit_button_text">עדכון קטגוריות</string>
|
||||||
|
<string name="coordinates_edit_helper_make_edit_toast">מנסים לעדכן נקודות ציון.</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title">עדכון נקודות ציון</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title_success">זה עבד</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_message">נקודות הציון %1$s נוספות.</string>
|
||||||
|
<string name="coordinates_edit_helper_edit_message_else">לא היה אפשר להוסיף נקודות ציון.</string>
|
||||||
|
<string name="coordinates_picking_unsuccessful">לא ניתן לעדכן נקודות ציון.</string>
|
||||||
<string name="share_image_via">שיתוף תמונה דרך</string>
|
<string name="share_image_via">שיתוף תמונה דרך</string>
|
||||||
<string name="no_achievements_yet">לא תרמת שום דבר עדיין</string>
|
<string name="no_achievements_yet">לא תרמת שום דבר עדיין</string>
|
||||||
<string name="account_created">חשבון נוצר!</string>
|
<string name="account_created">חשבון נוצר!</string>
|
||||||
|
|
@ -608,4 +616,9 @@
|
||||||
<string name="app_ui_language">שפת ממשק המשתמש של היישום</string>
|
<string name="app_ui_language">שפת ממשק המשתמש של היישום</string>
|
||||||
<string name="remove">הסרת כיתוב ותיאור</string>
|
<string name="remove">הסרת כיתוב ותיאור</string>
|
||||||
<string name="read_help_link">מידע נוסף</string>
|
<string name="read_help_link">מידע נוסף</string>
|
||||||
|
<string name="choose_a_location">נא לבחור מיקום</string>
|
||||||
|
<string name="pan_and_zoom_to_adjust">לצדד וקרב כדי לכוונן</string>
|
||||||
|
<string name="exit_location_picker">יציאה מבורר המיקום</string>
|
||||||
|
<string name="select_location_location_picker">נא לבחור מיקום</string>
|
||||||
|
<string name="location_picker_image_view">תצוגת תמונה של בורר המיקום</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Authors:
|
<!-- Authors:
|
||||||
|
* Bennylin
|
||||||
* Diki Ananta
|
* Diki Ananta
|
||||||
* N219
|
* N219
|
||||||
* NoiX180
|
* NoiX180
|
||||||
|
|
@ -81,7 +82,7 @@
|
||||||
<string name="contributions_subtitle_zero" fuzzy="true">Durung ana unggahan</string>
|
<string name="contributions_subtitle_zero" fuzzy="true">Durung ana unggahan</string>
|
||||||
<string name="categories_not_found">Ora ana kategori kang cocog karo %1$s</string>
|
<string name="categories_not_found">Ora ana kategori kang cocog karo %1$s</string>
|
||||||
<string name="categories_skip_explanation">Wuwuh kategori supaya gambar-gambaré panjenengan gampang tinemu ing Wikimedia Commons.\nWiwit nulis saperlu muwuhi kategori.</string>
|
<string name="categories_skip_explanation">Wuwuh kategori supaya gambar-gambaré panjenengan gampang tinemu ing Wikimedia Commons.\nWiwit nulis saperlu muwuhi kategori.</string>
|
||||||
<string name="categories_activity_title">Kategori</string>
|
<string name="categories_activity_title">Katégori</string>
|
||||||
<string name="title_activity_settings">Setèlan</string>
|
<string name="title_activity_settings">Setèlan</string>
|
||||||
<string name="title_activity_signup">Ndhaftar</string>
|
<string name="title_activity_signup">Ndhaftar</string>
|
||||||
<string name="title_activity_featured_images">Gambar Pilihan</string>
|
<string name="title_activity_featured_images">Gambar Pilihan</string>
|
||||||
|
|
@ -115,7 +116,7 @@
|
||||||
<string name="tutorial_4_text">Contoné unggahan:</string>
|
<string name="tutorial_4_text">Contoné unggahan:</string>
|
||||||
<string name="welcome_final_text">Panjenengan sumerep, ta?</string>
|
<string name="welcome_final_text">Panjenengan sumerep, ta?</string>
|
||||||
<string name="welcome_final_button_text">Iya!</string>
|
<string name="welcome_final_button_text">Iya!</string>
|
||||||
<string name="detail_panel_cats_label">Kategori</string>
|
<string name="detail_panel_cats_label">Katégori</string>
|
||||||
<string name="detail_panel_cats_loading">Ngamot…</string>
|
<string name="detail_panel_cats_loading">Ngamot…</string>
|
||||||
<string name="detail_panel_cats_none">Ora ana sing dipilih</string>
|
<string name="detail_panel_cats_none">Ora ana sing dipilih</string>
|
||||||
<string name="detail_description_empty">Tanpa katerangan</string>
|
<string name="detail_description_empty">Tanpa katerangan</string>
|
||||||
|
|
@ -163,7 +164,7 @@
|
||||||
<string name="navigation_item_notification">Pambiwara</string>
|
<string name="navigation_item_notification">Pambiwara</string>
|
||||||
<string name="no_description_found">dhèksripsi ora tinemu</string>
|
<string name="no_description_found">dhèksripsi ora tinemu</string>
|
||||||
<string name="nearby_info_menu_commons_article">Kaca barkas Commons</string>
|
<string name="nearby_info_menu_commons_article">Kaca barkas Commons</string>
|
||||||
<string name="nearby_info_menu_wikidata_article">Wiji Wikidhata</string>
|
<string name="nearby_info_menu_wikidata_article">Wiji Wikidata</string>
|
||||||
<string name="nearby_info_menu_wikipedia_article">Artikel Wikipédia</string>
|
<string name="nearby_info_menu_wikipedia_article">Artikel Wikipédia</string>
|
||||||
<string name="use_external_storage" fuzzy="true">Anggo panyimpenan njaba</string>
|
<string name="use_external_storage" fuzzy="true">Anggo panyimpenan njaba</string>
|
||||||
<string name="login_to_your_account">Mlebu log ing akun panjenengan</string>
|
<string name="login_to_your_account">Mlebu log ing akun panjenengan</string>
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
<string name="uploading_started">ಅಪ್ಲೋಡ್ ಪ್ರಾರಂಭವಾಗಿದೆ!</string>
|
<string name="uploading_started">ಅಪ್ಲೋಡ್ ಪ್ರಾರಂಭವಾಗಿದೆ!</string>
|
||||||
<string name="upload_completed_notification_title">%1$s ಅಪ್ಲೋಡ್ ಆಗಿದೆ!</string>
|
<string name="upload_completed_notification_title">%1$s ಅಪ್ಲೋಡ್ ಆಗಿದೆ!</string>
|
||||||
<string name="upload_completed_notification_text">ನಿಮ್ಮ ನಕಲೇರಿಕೆಯನ್ನು ನೋಡಲು ಮೆಲ್ಲಗೆ ತಟ್ಟಿ</string>
|
<string name="upload_completed_notification_text">ನಿಮ್ಮ ನಕಲೇರಿಕೆಯನ್ನು ನೋಡಲು ಮೆಲ್ಲಗೆ ತಟ್ಟಿ</string>
|
||||||
<string name="upload_progress_notification_title_start" fuzzy="true">ನಕಲೇರಿಕೆಯ%1$s ಪ್ರಾರಂಭ</string>
|
<string name="upload_progress_notification_title_start">ಕಡತ ಅಪ್ಲೋಡ್ ಆಗುತ್ತಿದೆ: %s</string>
|
||||||
<string name="upload_progress_notification_title_in_progress">%1$s ನಕಲೇರಿಕೆ ಆಗಿದೆ!</string>
|
<string name="upload_progress_notification_title_in_progress">%1$s ನಕಲೇರಿಕೆ ಆಗಿದೆ!</string>
|
||||||
<string name="upload_progress_notification_title_finishing">%1$s ಅಪ್ಲೋಡ್ ಮಾಡುವಿಕೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ</string>
|
<string name="upload_progress_notification_title_finishing">%1$s ಅಪ್ಲೋಡ್ ಮಾಡುವಿಕೆಯನ್ನು ಪೂರ್ಣಗೊಳಿಸಲಾಗುತ್ತಿದೆ</string>
|
||||||
<string name="upload_failed_notification_title">%1$s ಅಪ್ಲೋಡ್ ಮಾಡುವಿಕೆ ವಿಫಲವಾಗಿದೆ</string>
|
<string name="upload_failed_notification_title">%1$s ಅಪ್ಲೋಡ್ ಮಾಡುವಿಕೆ ವಿಫಲವಾಗಿದೆ</string>
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
<string name="menu_nearby">ಹತ್ತಿರದ</string>
|
<string name="menu_nearby">ಹತ್ತಿರದ</string>
|
||||||
<string name="provider_contributions">ನನ್ನ ನಕಲೇರಿಕೆಗಳು</string>
|
<string name="provider_contributions">ನನ್ನ ನಕಲೇರಿಕೆಗಳು</string>
|
||||||
<string name="menu_share">ಹಂಚು</string>
|
<string name="menu_share">ಹಂಚು</string>
|
||||||
|
<string name="menu_view_file_page">ಕಡತದ ಪುಟ ವೀಕ್ಷಿಸಿ</string>
|
||||||
<string name="share_title_hint">ತಲೆಬರಹ (ಕಡ್ಡಾಯ)</string>
|
<string name="share_title_hint">ತಲೆಬರಹ (ಕಡ್ಡಾಯ)</string>
|
||||||
<string name="share_description_hint">ವಿವರ</string>
|
<string name="share_description_hint">ವಿವರ</string>
|
||||||
<string name="share_caption_hint">ತಲೆಬರಹ</string>
|
<string name="share_caption_hint">ತಲೆಬರಹ</string>
|
||||||
|
|
@ -63,11 +64,13 @@
|
||||||
<string name="contributions_subtitle_zero">(ಇನ್ನೂ ಯಾವುದೇ ಅಪ್ಲೋಡ್ಗಳಿಲ್ಲ)</string>
|
<string name="contributions_subtitle_zero">(ಇನ್ನೂ ಯಾವುದೇ ಅಪ್ಲೋಡ್ಗಳಿಲ್ಲ)</string>
|
||||||
<string name="categories_activity_title">ವರ್ಗಗಳು</string>
|
<string name="categories_activity_title">ವರ್ಗಗಳು</string>
|
||||||
<string name="title_activity_settings">ವ್ಯವಸ್ಥೆಗಳು</string>
|
<string name="title_activity_settings">ವ್ಯವಸ್ಥೆಗಳು</string>
|
||||||
|
<string name="title_activity_signup">ಸೈನ್ ಅಪ್</string>
|
||||||
<string name="title_activity_category_details">ವರ್ಗ</string>
|
<string name="title_activity_category_details">ವರ್ಗ</string>
|
||||||
<string name="menu_about">ಕುರಿತು</string>
|
<string name="menu_about">ಕುರಿತು</string>
|
||||||
<string name="about_privacy_policy">ಗೌಪ್ಯತಾ ನೀತಿ</string>
|
<string name="about_privacy_policy">ಗೌಪ್ಯತಾ ನೀತಿ</string>
|
||||||
<string name="about_credits">ಮನ್ನಣೆಗಳು</string>
|
<string name="about_credits">ಮನ್ನಣೆಗಳು</string>
|
||||||
<string name="title_activity_about">ಕುರಿತು</string>
|
<string name="title_activity_about">ಕುರಿತು</string>
|
||||||
|
<string name="provider_categories">ಇತ್ತೀಚೆಗೆ ಬಳಸಲಾದ ವರ್ಗಗಳು</string>
|
||||||
<string name="menu_retry_upload">ಪುನಃ ಪ್ರಯತ್ನಿಸಿ</string>
|
<string name="menu_retry_upload">ಪುನಃ ಪ್ರಯತ್ನಿಸಿ</string>
|
||||||
<string name="menu_cancel_upload">ರದ್ದುಮಾಡಿ</string>
|
<string name="menu_cancel_upload">ರದ್ದುಮಾಡಿ</string>
|
||||||
<string name="menu_download">ನಕಲಿಳಿಸಿ</string>
|
<string name="menu_download">ನಕಲಿಳಿಸಿ</string>
|
||||||
|
|
@ -89,7 +92,9 @@
|
||||||
<string name="detail_panel_cats_loading">ತುಂಬಿಸಲಾಗುತ್ತಿದೆ….</string>
|
<string name="detail_panel_cats_loading">ತುಂಬಿಸಲಾಗುತ್ತಿದೆ….</string>
|
||||||
<string name="detail_caption_empty">ತಲೆಬರಹ ಇಲ್ಲ</string>
|
<string name="detail_caption_empty">ತಲೆಬರಹ ಇಲ್ಲ</string>
|
||||||
<string name="detail_description_empty">ವಿವರ ಇಲ್ಲ</string>
|
<string name="detail_description_empty">ವಿವರ ಇಲ್ಲ</string>
|
||||||
|
<string name="detail_discussion_empty">ಯಾವುದೇ ಚರ್ಚೆ ಇಲ್ಲ</string>
|
||||||
<string name="detail_license_empty">ಗೊತ್ತಿಲ್ಲದ ಪರವಾನಗಿ</string>
|
<string name="detail_license_empty">ಗೊತ್ತಿಲ್ಲದ ಪರವಾನಗಿ</string>
|
||||||
|
<string name="menu_refresh">ಪುನಶ್ಚೇತನಗೊಳಿಸು</string>
|
||||||
<string name="ok">ಸರಿ</string>
|
<string name="ok">ಸರಿ</string>
|
||||||
<string name="warning">ಎಚ್ಚರಿಕೆ</string>
|
<string name="warning">ಎಚ್ಚರಿಕೆ</string>
|
||||||
<string name="upload">ಅಪ್ಲೋಡ್</string>
|
<string name="upload">ಅಪ್ಲೋಡ್</string>
|
||||||
|
|
@ -97,10 +102,13 @@
|
||||||
<string name="no">ಇಲ್ಲ</string>
|
<string name="no">ಇಲ್ಲ</string>
|
||||||
<string name="media_detail_caption">ತಲೆಬರಹ</string>
|
<string name="media_detail_caption">ತಲೆಬರಹ</string>
|
||||||
<string name="media_detail_title">ಶೀರ್ಷಿಕೆ</string>
|
<string name="media_detail_title">ಶೀರ್ಷಿಕೆ</string>
|
||||||
|
<string name="media_detail_discussion">ಚರ್ಚೆ</string>
|
||||||
<string name="media_detail_author">ಕರ್ತೃ</string>
|
<string name="media_detail_author">ಕರ್ತೃ</string>
|
||||||
<string name="media_detail_license">ಪರವಾನಗಿ</string>
|
<string name="media_detail_license">ಪರವಾನಗಿ</string>
|
||||||
<string name="commons_website">ಕಾಮನ್ಸ್ ಜಾಲತಾಣ</string>
|
<string name="commons_website">ಕಾಮನ್ಸ್ ಜಾಲತಾಣ</string>
|
||||||
<string name="commons_facebook">ಕಾಮನ್ಸ್ ಫೇಸ್ಬುಕ್ ಪುಟ</string>
|
<string name="commons_facebook">ಕಾಮನ್ಸ್ ಫೇಸ್ಬುಕ್ ಪುಟ</string>
|
||||||
|
<string name="welcome_image_mount_zao">ಮೌಂಟ್ ಜಾವ್</string>
|
||||||
|
<string name="welcome_image_llamas">ಲಾಮಾಗಳು</string>
|
||||||
<string name="welcome_image_tulip">ಟ್ಯೂಲಿಪ್</string>
|
<string name="welcome_image_tulip">ಟ್ಯೂಲಿಪ್</string>
|
||||||
<string name="welcome_image_sydney_opera_house">ಸಿಡ್ನಿ ಒಪೆರಾ ಹೌಸ್</string>
|
<string name="welcome_image_sydney_opera_house">ಸಿಡ್ನಿ ಒಪೆರಾ ಹೌಸ್</string>
|
||||||
<string name="cancel">ರದ್ದುಮಾಡಿ</string>
|
<string name="cancel">ರದ್ದುಮಾಡಿ</string>
|
||||||
|
|
@ -114,6 +122,7 @@
|
||||||
<string name="navigation_item_logout">ಲಾಗ್ ಔಟ್</string>
|
<string name="navigation_item_logout">ಲಾಗ್ ಔಟ್</string>
|
||||||
<string name="navigation_item_notification">ಅಧಿಸೂಚನೆಗಳು</string>
|
<string name="navigation_item_notification">ಅಧಿಸೂಚನೆಗಳು</string>
|
||||||
<string name="no_description_found">ಯಾವುದೇ ವಿವರಣೆ ಸಿಗಲಿಲ್ಲ</string>
|
<string name="no_description_found">ಯಾವುದೇ ವಿವರಣೆ ಸಿಗಲಿಲ್ಲ</string>
|
||||||
|
<string name="nearby_info_menu_commons_article">ಕಾಮನ್ಸ್ ಕಡತದ ಪುಟ</string>
|
||||||
<string name="nearby_info_menu_wikidata_article">ವಿಕಿಡೇಟಾ ವಸ್ತು</string>
|
<string name="nearby_info_menu_wikidata_article">ವಿಕಿಡೇಟಾ ವಸ್ತು</string>
|
||||||
<string name="nearby_info_menu_wikipedia_article">ವಿಕಿಪೀಡಿಯ ಲೇಖನ</string>
|
<string name="nearby_info_menu_wikipedia_article">ವಿಕಿಪೀಡಿಯ ಲೇಖನ</string>
|
||||||
<string name="upload_problem_image_dark">ಚಿತ್ರವು ಬಹಳ ಕಪ್ಪಾಗಿದೆ.</string>
|
<string name="upload_problem_image_dark">ಚಿತ್ರವು ಬಹಳ ಕಪ್ಪಾಗಿದೆ.</string>
|
||||||
|
|
@ -134,9 +143,13 @@
|
||||||
<string name="retry">ಪುನಃ ಪ್ರಯತ್ನಿಸಿ</string>
|
<string name="retry">ಪುನಃ ಪ್ರಯತ್ನಿಸಿ</string>
|
||||||
<string name="no_images_found">ಯಾವುದೇ ಚಿತ್ರಗಳು ಸಿಗಲಿಲ್ಲ!</string>
|
<string name="no_images_found">ಯಾವುದೇ ಚಿತ್ರಗಳು ಸಿಗಲಿಲ್ಲ!</string>
|
||||||
<string name="block_notification_title">ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</string>
|
<string name="block_notification_title">ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ</string>
|
||||||
|
<string name="appwidget_img">ದಿನದ ಚಿತ್ರ</string>
|
||||||
|
<string name="app_widget_heading">ದಿನದ ಚಿತ್ರ</string>
|
||||||
<string name="menu_search_button">ಹುಡುಕು</string>
|
<string name="menu_search_button">ಹುಡುಕು</string>
|
||||||
|
<string name="search_commons">ಕಾಮನ್ಸ್ ಹುಡುಕಿ</string>
|
||||||
<string name="title_activity_search">ಹುಡುಕು</string>
|
<string name="title_activity_search">ಹುಡುಕು</string>
|
||||||
<string name="search_recent_header">ಇತ್ತೀಚೆಗಿನ ಹುಡುಕಾಟಗಳು:</string>
|
<string name="search_recent_header">ಇತ್ತೀಚೆಗಿನ ಹುಡುಕಾಟಗಳು:</string>
|
||||||
|
<string name="search_tab_title_media">ಮೀಡಿಯಾ</string>
|
||||||
<string name="search_tab_title_categories">ವರ್ಗಗಳು</string>
|
<string name="search_tab_title_categories">ವರ್ಗಗಳು</string>
|
||||||
<string name="search_tab_title_depictions">ವಸ್ತುಗಳು</string>
|
<string name="search_tab_title_depictions">ವಸ್ತುಗಳು</string>
|
||||||
<string name="question">ಪ್ರಶ್ನೆ</string>
|
<string name="question">ಪ್ರಶ್ನೆ</string>
|
||||||
|
|
|
||||||
|
|
@ -227,6 +227,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Оваа слика е направена на друго место.</string>
|
<string name="upload_problem_different_geolocation">Оваа слика е направена на друго место.</string>
|
||||||
<string name="upload_problem_fbmd">Подигајте само слики кои самите сте ги направиле. Не подигајте слики пронајдени на туѓи профили на Фејсбук.</string>
|
<string name="upload_problem_fbmd">Подигајте само слики кои самите сте ги направиле. Не подигајте слики пронајдени на туѓи профили на Фејсбук.</string>
|
||||||
<string name="upload_problem_do_you_continue">Дали сепак сакате да ја подигнете?</string>
|
<string name="upload_problem_do_you_continue">Дали сепак сакате да ја подигнете?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Грешка при поврзувањето</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Постапката за подигање бара да сте поврзани\n со семрежјето. Проверете си ја врската.</string>
|
||||||
<string name="upload_problem_image">Пронајдени проблеми во сликата</string>
|
<string name="upload_problem_image">Пронајдени проблеми во сликата</string>
|
||||||
<string name="internet_downloaded">Подигајте само слики кои самите сте ги направиле. Не подигајте слики што сте ги нашле некаде на семрежјето.</string>
|
<string name="internet_downloaded">Подигајте само слики кои самите сте ги направиле. Не подигајте слики што сте ги нашле некаде на семрежјето.</string>
|
||||||
<string name="use_external_storage">Зачувај слики направени во прилогот</string>
|
<string name="use_external_storage">Зачувај слики направени во прилогот</string>
|
||||||
|
|
@ -479,6 +481,12 @@
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="category_edit_helper_edit_message_else">Не можев да ги додадам категориите.</string>
|
<string name="category_edit_helper_edit_message_else">Не можев да ги додадам категориите.</string>
|
||||||
<string name="category_edit_button_text">Поднови категории</string>
|
<string name="category_edit_button_text">Поднови категории</string>
|
||||||
|
<string name="coordinates_edit_helper_make_edit_toast">Се обидувам да ги подоновам координатите.</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title">Поднова на координати</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title_success">Успеа</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_message">Координатите %1$s се додадени.</string>
|
||||||
|
<string name="coordinates_edit_helper_edit_message_else">Не можев да додадам координати.</string>
|
||||||
|
<string name="coordinates_picking_unsuccessful">Не можев да добијам координати.</string>
|
||||||
<string name="share_image_via">Сподели ја сликата преку</string>
|
<string name="share_image_via">Сподели ја сликата преку</string>
|
||||||
<string name="no_achievements_yet">Засега немате придонеси</string>
|
<string name="no_achievements_yet">Засега немате придонеси</string>
|
||||||
<string name="account_created">Сметката е создадена!</string>
|
<string name="account_created">Сметката е создадена!</string>
|
||||||
|
|
@ -576,4 +584,10 @@
|
||||||
<string name="app_ui_language">Јазик на прилогот</string>
|
<string name="app_ui_language">Јазик на прилогот</string>
|
||||||
<string name="remove">Острани толкување и опис</string>
|
<string name="remove">Острани толкување и опис</string>
|
||||||
<string name="read_help_link">Прочитајте повеќе</string>
|
<string name="read_help_link">Прочитајте повеќе</string>
|
||||||
|
<string name="choose_a_location">Изберете местоположба</string>
|
||||||
|
<string name="pan_and_zoom_to_adjust">Доведете го местото на картата и приближете го за да прилагодите</string>
|
||||||
|
<string name="exit_location_picker">Излези од избирачот на местоположба</string>
|
||||||
|
<string name="select_location_location_picker">Изберете местоположба</string>
|
||||||
|
<string name="location_picker_image_view">Поглед на слика за избирање местоположба</string>
|
||||||
|
<string name="location_picker_image_view_shadow">Сенчест поглед на слика за избирање местоположба</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
* CiaPan
|
* CiaPan
|
||||||
* DeRudySoulStorm
|
* DeRudySoulStorm
|
||||||
* InternerowyGołąb
|
* InternerowyGołąb
|
||||||
|
* Kareyac
|
||||||
* Krottyianock
|
* Krottyianock
|
||||||
* Matma Rex
|
* Matma Rex
|
||||||
* Mazab IZW
|
* Mazab IZW
|
||||||
|
|
@ -505,6 +506,7 @@
|
||||||
<string name="category_edit_helper_show_edit_title_success">Powodzenie</string>
|
<string name="category_edit_helper_show_edit_title_success">Powodzenie</string>
|
||||||
<string name="category_edit_helper_edit_message_else">Nie udało się dodać kategorii.</string>
|
<string name="category_edit_helper_edit_message_else">Nie udało się dodać kategorii.</string>
|
||||||
<string name="category_edit_button_text">Aktualizuj kategorie</string>
|
<string name="category_edit_button_text">Aktualizuj kategorie</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title_success">Powodzenie</string>
|
||||||
<string name="share_image_via">Udostępnij obraz przez</string>
|
<string name="share_image_via">Udostępnij obraz przez</string>
|
||||||
<string name="no_achievements_yet">Nie wykonałeś jeszcze żadnej edycji</string>
|
<string name="no_achievements_yet">Nie wykonałeś jeszcze żadnej edycji</string>
|
||||||
<string name="account_created">Konto zostało utworzone!</string>
|
<string name="account_created">Konto zostało utworzone!</string>
|
||||||
|
|
|
||||||
|
|
@ -225,6 +225,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Sa fòto a l\'é stàita fàita ant un pòst diferent.</string>
|
<string name="upload_problem_different_geolocation">Sa fòto a l\'é stàita fàita ant un pòst diferent.</string>
|
||||||
<string name="upload_problem_fbmd">Për piasì, ch\'a caria mach dle fòto che a l\'ha fàit chiel-midem. Ch\'a caria pa dle fòto che a l\'ha trovà an sij cont Facebook d\'àutra gent.</string>
|
<string name="upload_problem_fbmd">Për piasì, ch\'a caria mach dle fòto che a l\'ha fàit chiel-midem. Ch\'a caria pa dle fòto che a l\'ha trovà an sij cont Facebook d\'àutra gent.</string>
|
||||||
<string name="upload_problem_do_you_continue">Veul-lo istess carié sta plancia?</string>
|
<string name="upload_problem_do_you_continue">Veul-lo istess carié sta plancia?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Eror ëd conession</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Ël process ëd cariament a l\'ha damanca ëd n\'acess ativ a l\'aragnà. Për piasì, ch\'a verìfica sò colegament a la rej.</string>
|
||||||
<string name="upload_problem_image">Trovà un problema con la plancia</string>
|
<string name="upload_problem_image">Trovà un problema con la plancia</string>
|
||||||
<string name="internet_downloaded">Për piasì, ch\'a caria mach dle fòto ch\'a l\'ha fàit chiel-midem. Ch\'a caria pa dle fòto che a l\'ha dëscarià da \'ns l\'aragnà.</string>
|
<string name="internet_downloaded">Për piasì, ch\'a caria mach dle fòto ch\'a l\'ha fàit chiel-midem. Ch\'a caria pa dle fòto che a l\'ha dëscarià da \'ns l\'aragnà.</string>
|
||||||
<string name="use_external_storage">Argistré le plance d\'aplicassion</string>
|
<string name="use_external_storage">Argistré le plance d\'aplicassion</string>
|
||||||
|
|
@ -477,6 +479,12 @@
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="category_edit_helper_edit_message_else">Impossìbil gionté dle categorìe.</string>
|
<string name="category_edit_helper_edit_message_else">Impossìbil gionté dle categorìe.</string>
|
||||||
<string name="category_edit_button_text">Agiorné le categorìe</string>
|
<string name="category_edit_button_text">Agiorné le categorìe</string>
|
||||||
|
<string name="coordinates_edit_helper_make_edit_toast">Tentativ d\'agiorné le coordinà.</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title">Agiornament ëd le coordinà</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title_success">Sucess</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_message">Giontà la coordinà %1$s.</string>
|
||||||
|
<string name="coordinates_edit_helper_edit_message_else">Impossìbil gionté lé coordinà.</string>
|
||||||
|
<string name="coordinates_picking_unsuccessful">Impossìbil oten-e le coordinà.</string>
|
||||||
<string name="share_image_via">Partagé la plancia via</string>
|
<string name="share_image_via">Partagé la plancia via</string>
|
||||||
<string name="no_achievements_yet">A l\'ha pa ancor fàit ëd contribussion</string>
|
<string name="no_achievements_yet">A l\'ha pa ancor fàit ëd contribussion</string>
|
||||||
<string name="account_created">Cont creà!</string>
|
<string name="account_created">Cont creà!</string>
|
||||||
|
|
@ -574,4 +582,10 @@
|
||||||
<string name="app_ui_language">Lenga d\'antërfassa utent ëd l\'aplicassion</string>
|
<string name="app_ui_language">Lenga d\'antërfassa utent ëd l\'aplicassion</string>
|
||||||
<string name="remove">A gava na legenda e na descrission</string>
|
<string name="remove">A gava na legenda e na descrission</string>
|
||||||
<string name="read_help_link">Lese ëd pi</string>
|
<string name="read_help_link">Lese ëd pi</string>
|
||||||
|
<string name="choose_a_location">Serne na locassion</string>
|
||||||
|
<string name="pan_and_zoom_to_adjust">Slarghé e strenze për buté bin</string>
|
||||||
|
<string name="exit_location_picker">Seurte dal selessionador ëd locassion</string>
|
||||||
|
<string name="select_location_location_picker">Selessioné na locassion</string>
|
||||||
|
<string name="location_picker_image_view">Vista dla plancia dël selessionador ëd locassion</string>
|
||||||
|
<string name="location_picker_image_view_shadow">Locassion ëd picker_image_view_shadow</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
|
|
@ -241,6 +241,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Esta foto foi tirada em um local diferente.</string>
|
<string name="upload_problem_different_geolocation">Esta foto foi tirada em um local diferente.</string>
|
||||||
<string name="upload_problem_fbmd">Por favor, apenas envie fotos que você tirou sozinho. Não faça upload de fotos que você encontrou nas contas do Facebook de outras pessoas.</string>
|
<string name="upload_problem_fbmd">Por favor, apenas envie fotos que você tirou sozinho. Não faça upload de fotos que você encontrou nas contas do Facebook de outras pessoas.</string>
|
||||||
<string name="upload_problem_do_you_continue">Você ainda quer enviar esta foto?</string>
|
<string name="upload_problem_do_you_continue">Você ainda quer enviar esta foto?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Erro de conexão</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">O processo de carregamento requer acesso a internet\n ativa. Verifique sua conexão de rede.</string>
|
||||||
<string name="upload_problem_image">Problemas encontrados na imagem</string>
|
<string name="upload_problem_image">Problemas encontrados na imagem</string>
|
||||||
<string name="internet_downloaded">Por favor, só envie fotos que você tirou. Não faça upload de fotos baixadas da Internet.</string>
|
<string name="internet_downloaded">Por favor, só envie fotos que você tirou. Não faça upload de fotos baixadas da Internet.</string>
|
||||||
<string name="use_external_storage">Salvar fotos no aplicativo</string>
|
<string name="use_external_storage">Salvar fotos no aplicativo</string>
|
||||||
|
|
|
||||||
|
|
@ -269,6 +269,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Это изображение было сделано в другом месте.</string>
|
<string name="upload_problem_different_geolocation">Это изображение было сделано в другом месте.</string>
|
||||||
<string name="upload_problem_fbmd">Пожалуйста, загружайте только те изображения, которые были сделаны вами. Не загружайте изображений, которые вы нашли в Фейсбуке.</string>
|
<string name="upload_problem_fbmd">Пожалуйста, загружайте только те изображения, которые были сделаны вами. Не загружайте изображений, которые вы нашли в Фейсбуке.</string>
|
||||||
<string name="upload_problem_do_you_continue">Всё равно желаете загрузить это изображение?</string>
|
<string name="upload_problem_do_you_continue">Всё равно желаете загрузить это изображение?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Ошибка соединения</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Для загрузки требуется доступ в Интернет. Пожалуйста, проверьте ваше сетевое соединение.</string>
|
||||||
<string name="upload_problem_image">Проблемы, найденные в изображении</string>
|
<string name="upload_problem_image">Проблемы, найденные в изображении</string>
|
||||||
<string name="internet_downloaded">Пожалуйста, загружайте только те изображения, которые были сделаны вами. Не загружайте изображений, которые вы скачали из Интернета.</string>
|
<string name="internet_downloaded">Пожалуйста, загружайте только те изображения, которые были сделаны вами. Не загружайте изображений, которые вы скачали из Интернета.</string>
|
||||||
<string name="use_external_storage">Сохранять сделанные в приложении снимки</string>
|
<string name="use_external_storage">Сохранять сделанные в приложении снимки</string>
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Tento obrázok bol zhotovený na inom mieste.</string>
|
<string name="upload_problem_different_geolocation">Tento obrázok bol zhotovený na inom mieste.</string>
|
||||||
<string name="upload_problem_fbmd">Nahrávajte, prosím, len obrázky, ktoré ste sami zhotovili. Nenahrávajte obrázky, ktoré ste našli na Facebookovom profile niekoho iného.</string>
|
<string name="upload_problem_fbmd">Nahrávajte, prosím, len obrázky, ktoré ste sami zhotovili. Nenahrávajte obrázky, ktoré ste našli na Facebookovom profile niekoho iného.</string>
|
||||||
<string name="upload_problem_do_you_continue">Naozaj chcete nahrať tento obrázok?</string>
|
<string name="upload_problem_do_you_continue">Naozaj chcete nahrať tento obrázok?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Chyba pripojenia</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Proces nahrávania vyžaduje aktívny internetový prístup. Prosím skontrolujte svoje internetové pripojenie.</string>
|
||||||
<string name="upload_problem_image">Na obrázku boli nájdené nejaké problémy</string>
|
<string name="upload_problem_image">Na obrázku boli nájdené nejaké problémy</string>
|
||||||
<string name="internet_downloaded">Nahrávajte, prosím, len obrázky, ktoré ste sami zhotovili. Nenahrávajte obrázky, ktoré ste stiahli z internetu.</string>
|
<string name="internet_downloaded">Nahrávajte, prosím, len obrázky, ktoré ste sami zhotovili. Nenahrávajte obrázky, ktoré ste stiahli z internetu.</string>
|
||||||
<string name="use_external_storage">Použiť externé úložisko</string>
|
<string name="use_external_storage">Použiť externé úložisko</string>
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Bilden togs på en annan plats.</string>
|
<string name="upload_problem_different_geolocation">Bilden togs på en annan plats.</string>
|
||||||
<string name="upload_problem_fbmd">Var god ladda bara upp bilder som du själv har tagit. Ladda inte upp bilder som du har hittat på andra personers Facebook-konton.</string>
|
<string name="upload_problem_fbmd">Var god ladda bara upp bilder som du själv har tagit. Ladda inte upp bilder som du har hittat på andra personers Facebook-konton.</string>
|
||||||
<string name="upload_problem_do_you_continue">Vill du fortfarande ladda upp denna bild?</string>
|
<string name="upload_problem_do_you_continue">Vill du fortfarande ladda upp denna bild?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Anslutningsfel</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Uppladdningsprocessen kräver aktiv internetåtkomst. Kontrollera din nätverksanslutning.</string>
|
||||||
<string name="upload_problem_image">Problem hittades i bilden</string>
|
<string name="upload_problem_image">Problem hittades i bilden</string>
|
||||||
<string name="internet_downloaded">Var god ladda bara upp bilder som du själv har tagit. Ladda inte upp bilder som du har laddat ned från Internet.</string>
|
<string name="internet_downloaded">Var god ladda bara upp bilder som du själv har tagit. Ladda inte upp bilder som du har laddat ned från Internet.</string>
|
||||||
<string name="use_external_storage">Spara bilder i appen</string>
|
<string name="use_external_storage">Spara bilder i appen</string>
|
||||||
|
|
|
||||||
|
|
@ -247,6 +247,8 @@
|
||||||
<string name="upload_problem_different_geolocation">Bu resim farklı bir yerde çekilmiş.</string>
|
<string name="upload_problem_different_geolocation">Bu resim farklı bir yerde çekilmiş.</string>
|
||||||
<string name="upload_problem_fbmd">Lütfen yalnızca kendi çektiğiniz resimleri yükleyin. Başkalarının Facebook hesaplarında bulduğunuz resimleri yüklemeyin.</string>
|
<string name="upload_problem_fbmd">Lütfen yalnızca kendi çektiğiniz resimleri yükleyin. Başkalarının Facebook hesaplarında bulduğunuz resimleri yüklemeyin.</string>
|
||||||
<string name="upload_problem_do_you_continue">Hâlâ bu resmi yüklemek istiyor musunuz?</string>
|
<string name="upload_problem_do_you_continue">Hâlâ bu resmi yüklemek istiyor musunuz?</string>
|
||||||
|
<string name="upload_connection_error_alert_title">Bağlantı Hatası</string>
|
||||||
|
<string name="upload_connection_error_alert_detail">Yükleme işlemi etkin internet erişimine ihtiyaç duyar.\n Lütfen ağ bağlantınızı kontrol edin.</string>
|
||||||
<string name="upload_problem_image">Resimde bulunan sorunlar</string>
|
<string name="upload_problem_image">Resimde bulunan sorunlar</string>
|
||||||
<string name="internet_downloaded">Lütfen yalnızca kendi çektiğiniz resimleri yükleyin. İnternetten indirdiğiniz resimleri yüklemeyin.</string>
|
<string name="internet_downloaded">Lütfen yalnızca kendi çektiğiniz resimleri yükleyin. İnternetten indirdiğiniz resimleri yüklemeyin.</string>
|
||||||
<string name="use_external_storage">Uygulama içi çekimleri kaydedin</string>
|
<string name="use_external_storage">Uygulama içi çekimleri kaydedin</string>
|
||||||
|
|
|
||||||
|
|
@ -228,8 +228,7 @@
|
||||||
<string name="upload_problem_do_you_continue">Do you still want to upload this picture?</string>
|
<string name="upload_problem_do_you_continue">Do you still want to upload this picture?</string>
|
||||||
|
|
||||||
<string name="upload_connection_error_alert_title">Connection Error</string>
|
<string name="upload_connection_error_alert_title">Connection Error</string>
|
||||||
<string name="upload_connection_error_alert_detail">The upload process requires active internet
|
<string name="upload_connection_error_alert_detail">The upload process requires active internet access. Please check your network connection.</string>
|
||||||
access. Please check your network connection.</string>
|
|
||||||
|
|
||||||
<string name="upload_problem_image">Problems found in image</string>
|
<string name="upload_problem_image">Problems found in image</string>
|
||||||
<string name="internet_downloaded">Please only upload pictures that you have taken by yourself. Don\'t upload pictures that you have downloaded from the Internet.</string>
|
<string name="internet_downloaded">Please only upload pictures that you have taken by yourself. Don\'t upload pictures that you have downloaded from the Internet.</string>
|
||||||
|
|
@ -514,6 +513,13 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="category_edit_helper_edit_message_else">Could not add categories.</string>
|
<string name="category_edit_helper_edit_message_else">Could not add categories.</string>
|
||||||
<string name="category_edit_button_text">Update categories</string>
|
<string name="category_edit_button_text">Update categories</string>
|
||||||
|
|
||||||
|
<string name="coordinates_edit_helper_make_edit_toast">Trying to update coordinates.</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title">Coordinates update</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_title_success">Success</string>
|
||||||
|
<string name="coordinates_edit_helper_show_edit_message">Coordinates %1$s are added.</string>
|
||||||
|
<string name="coordinates_edit_helper_edit_message_else">Could not add coordinates.</string>
|
||||||
|
<string name="coordinates_picking_unsuccessful">Unable to get coordinates.</string>
|
||||||
|
|
||||||
<string name="share_image_via">Share image via</string>
|
<string name="share_image_via">Share image via</string>
|
||||||
<string name="no_achievements_yet">You haven\'t made any contributions yet</string>
|
<string name="no_achievements_yet">You haven\'t made any contributions yet</string>
|
||||||
<string name="account_created">Account created!</string>
|
<string name="account_created">Account created!</string>
|
||||||
|
|
@ -616,6 +622,12 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="app_ui_language">App user interface language</string>
|
<string name="app_ui_language">App user interface language</string>
|
||||||
<string name="remove">Removes a caption and description</string>
|
<string name="remove">Removes a caption and description</string>
|
||||||
<string name="read_help_link">Read more</string>
|
<string name="read_help_link">Read more</string>
|
||||||
|
<string name="choose_a_location">Choose a location</string>
|
||||||
|
<string name="pan_and_zoom_to_adjust">Pan and zoom to adjust</string>
|
||||||
|
<string name="exit_location_picker">Exit location picker</string>
|
||||||
|
<string name="select_location_location_picker">Select location</string>
|
||||||
|
<string name="location_picker_image_view">Location picker image view</string>
|
||||||
|
<string name="location_picker_image_view_shadow">Location picker_image_view_shadow</string>
|
||||||
<string name="custom_selector_title">Custom Selector</string>
|
<string name="custom_selector_title">Custom Selector</string>
|
||||||
<string name="custom_selector_empty_text">No Images</string>
|
<string name="custom_selector_empty_text">No Images</string>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ SELECT
|
||||||
(SAMPLE(?location) as ?location)
|
(SAMPLE(?location) as ?location)
|
||||||
?item
|
?item
|
||||||
(SAMPLE(COALESCE(?itemLabelPreferredLanguage, ?itemLabelAnyLanguage)) as ?label)
|
(SAMPLE(COALESCE(?itemLabelPreferredLanguage, ?itemLabelAnyLanguage)) as ?label)
|
||||||
|
(SAMPLE(COALESCE(?itemDescriptionPreferredLanguage, ?itemDescriptionAnyLanguage, "?")) as ?description)
|
||||||
(SAMPLE(?classId) as ?class)
|
(SAMPLE(?classId) as ?class)
|
||||||
(SAMPLE(COALESCE(?classLabelPreferredLanguage, ?classLabelAnyLanguage, "?")) as ?classLabel)
|
(SAMPLE(COALESCE(?classLabelPreferredLanguage, ?classLabelAnyLanguage, "?")) as ?classLabel)
|
||||||
(SAMPLE(COALESCE(?icon0, ?icon1)) as ?icon)
|
(SAMPLE(COALESCE(?icon0, ?icon1)) as ?icon)
|
||||||
|
|
@ -23,6 +24,10 @@ SELECT
|
||||||
OPTIONAL {?item rdfs:label ?itemLabelPreferredLanguage. FILTER (lang(?itemLabelPreferredLanguage) = "${LANG}")}
|
OPTIONAL {?item rdfs:label ?itemLabelPreferredLanguage. FILTER (lang(?itemLabelPreferredLanguage) = "${LANG}")}
|
||||||
OPTIONAL {?item rdfs:label ?itemLabelAnyLanguage}
|
OPTIONAL {?item rdfs:label ?itemLabelAnyLanguage}
|
||||||
|
|
||||||
|
# Get the description in the preferred language of the user, or any other language if no description is available in that language.
|
||||||
|
OPTIONAL {?item schema:description ?itemDescriptionPreferredLanguage. FILTER (lang(?itemDescriptionPreferredLanguage) = "${LANG}")}
|
||||||
|
OPTIONAL {?item schema:description ?itemDescriptionAnyLanguage }
|
||||||
|
|
||||||
# Get Commons category (P373)
|
# Get Commons category (P373)
|
||||||
OPTIONAL { ?item wdt:P373 ?commonsCategory. }
|
OPTIONAL { ?item wdt:P373 ?commonsCategory. }
|
||||||
|
|
||||||
|
|
|
||||||