Merge branch 'master' of https://github.com/commons-app/apps-android-commons into category-alignment

This commit is contained in:
Suchit Kar 2018-02-27 19:58:33 +05:30
commit ad9740154f
117 changed files with 1997 additions and 628 deletions

7
.gitignore vendored
View file

@ -27,3 +27,10 @@ app/gradle/wrapper/gradle-wrapper.jar
app/gradlew app/gradlew
app/gradlew.bat app/gradlew.bat
app/gradle/wrapper/gradle-wrapper.properties app/gradle/wrapper/gradle-wrapper.properties
#related to OpenCV
/libraries/opencv/build
app/src/main/jniLibs
#Below removes all the HTML files related to OpenCV documentation. The documentation can be otherwise found at:
#https://docs.opencv.org/3.3.0/
/libraries/opencv/javadoc/

9
PULL_REQUEST_TEMPLATE.md Normal file
View file

@ -0,0 +1,9 @@
## Description
Fixes #{GitHub issue number}
{Describe the changes made and why they were made.}
## Screenshots showing what changed
{Only for user interface changes, otherwise remove this section. See [how to take a screenshot](https://android.stackexchange.com/questions/1759/how-to-take-a-screenshot-with-an-android-device)}

View file

@ -18,7 +18,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.1' implementation 'com.google.code.gson:gson:2.8.1'
implementation 'com.jakewharton.timber:timber:4.5.1' implementation 'com.jakewharton.timber:timber:4.5.1'
implementation 'info.debatty:java-string-similarity:0.24' implementation 'info.debatty:java-string-similarity:0.24'
implementation ('com.mapbox.mapboxsdk:mapbox-android-sdk:5.2.1@aar'){ implementation ('com.mapbox.mapboxsdk:mapbox-android-sdk:5.4.1@aar'){
transitive=true transitive=true
} }
@ -26,6 +26,7 @@ dependencies {
implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION" implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION"
implementation "com.android.support:appcompat-v7:$SUPPORT_LIB_VERSION" implementation "com.android.support:appcompat-v7:$SUPPORT_LIB_VERSION"
implementation "com.android.support:design:$SUPPORT_LIB_VERSION" implementation "com.android.support:design:$SUPPORT_LIB_VERSION"
implementation "com.android.support:customtabs:$SUPPORT_LIB_VERSION"
implementation "com.android.support:cardview-v7:$SUPPORT_LIB_VERSION" implementation "com.android.support:cardview-v7:$SUPPORT_LIB_VERSION"
@ -38,6 +39,26 @@ dependencies {
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Because RxAndroid releases are few and far between, it is recommended you also // Because RxAndroid releases are few and far between, it is recommended you also
// explicitly depend on RxJava's latest version for bug fixes and new features. // explicitly depend on RxJava's latest version for bug fixes and new features.
compile 'io.reactivex.rxjava2:rxjava:2.1.2'
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0'
compile 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0'
compile 'com.facebook.fresco:fresco:1.3.0'
compile 'com.facebook.stetho:stetho:1.5.0'
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.7.1'
testCompile 'com.squareup.okhttp3:mockwebserver:3.8.1'
androidTestCompile 'com.squareup.okhttp3:mockwebserver:3.8.1'
androidTestCompile "com.android.support:support-annotations:${project.SUPPORT_LIB_VERSION}"
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.1'
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
implementation 'io.reactivex.rxjava2:rxjava:2.1.2' implementation 'io.reactivex.rxjava2:rxjava:2.1.2'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0' implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0' implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0'
@ -57,7 +78,7 @@ dependencies {
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.4' testImplementation 'org.robolectric:robolectric:3.7.1'
testImplementation 'org.mockito:mockito-all:1.10.19' testImplementation 'org.mockito:mockito-all:1.10.19'
testImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1' testImplementation 'com.squareup.okhttp3:mockwebserver:3.8.1'
@ -91,6 +112,8 @@ android {
targetSdkVersion project.targetSdkVersion targetSdkVersion project.targetSdkVersion
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
multiDexEnabled true
} }
sourceSets { sourceSets {

View file

@ -3,6 +3,8 @@ package fr.free.nrw.commons;
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.support.customtabs.CustomTabsIntent;
import android.support.v4.content.ContextCompat;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
@ -31,7 +33,7 @@ public class AboutActivity extends NavigationBaseActivity {
ButterKnife.bind(this); ButterKnife.bind(this);
String aboutText = getString(R.string.about_license, getString(R.string.trademarked_name)); String aboutText = getString(R.string.about_license);
aboutLicenseText.setHtmlText(aboutText); aboutLicenseText.setHtmlText(aboutText);
versionText.setText(BuildConfig.VERSION_NAME); versionText.setText(BuildConfig.VERSION_NAME);
@ -47,22 +49,29 @@ public class AboutActivity extends NavigationBaseActivity {
intent.setPackage("com.facebook.katana"); intent.setPackage("com.facebook.katana");
startActivity(intent); startActivity(intent);
} catch (Exception e) { } catch (Exception e) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.facebook.com/" + "1921335171459985"))); Utils.handleWebUrl(this,Uri.parse("https://www.facebook.com/" + "1921335171459985"));
} }
} }
@OnClick(R.id.github_launch_icon) @OnClick(R.id.github_launch_icon)
public void launchGithub(View view) { public void launchGithub(View view) {
Utils.handleWebUrl(this,Uri.parse("https://commons-app.github.io/\\"));
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/commons-app/apps-android-commons\\"));
startActivity(browserIntent);
} }
@OnClick(R.id.website_launch_icon) @OnClick(R.id.website_launch_icon)
public void launchWebsite(View view) { public void launchWebsite(View view) {
Utils.handleWebUrl(this,Uri.parse("https://commons-app.github.io/\\"));
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://commons-app.github.io/\\"));
startActivity(browserIntent);
} }
@OnClick(R.id.about_credits)
public void launchCredits(View view) {
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/blob/master/CREDITS/\\"));
}
@OnClick(R.id.about_privacy_policy)
public void launchPrivacyPolicy(View view) {
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\\"));
}
} }

View file

@ -283,7 +283,7 @@ public class MediaDataExtractor {
/** /**
* Take our metadata and inject it into a live Media object. * Take our metadata and inject it into a live Media object.
* Media object might contain stale or cached data, or emptiness. * Media object might contain stale or cached data, or emptiness.
* @param media * @param media Media object to inject into
*/ */
public void fill(Media media) { public void fill(Media media) {
if (!fetched) { if (!fetched) {

View file

@ -1,8 +1,12 @@
package fr.free.nrw.commons; package fr.free.nrw.commons;
import android.content.Context; import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.customtabs.CustomTabsIntent;
import android.support.v4.content.ContextCompat;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
@ -11,6 +15,7 @@ import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.util.Locale; import java.util.Locale;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -65,7 +70,7 @@ public class Utils {
/** /**
* Capitalizes the first character of a string. * Capitalizes the first character of a string.
* *
* @param string * @param string String to alter
* @return string with capitalized first character * @return string with capitalized first character
*/ */
public static String capitalize(String string) { public static String capitalize(String string) {
@ -159,4 +164,15 @@ public class Utils {
return stringBuilder.toString(); return stringBuilder.toString();
} }
public static void handleWebUrl(Context context,Uri url){
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
builder.setToolbarColor(ContextCompat.getColor(context, R.color.primaryColor));
builder.setSecondaryToolbarColor(ContextCompat.getColor(context, R.color.primaryDarkColor));
builder.setExitAnimations(context, android.R.anim.slide_in_left, android.R.anim.slide_out_right);
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
customTabsIntent.launchUrl(context, url);
}
} }

View file

@ -4,6 +4,7 @@ import android.accounts.Account;
import android.accounts.AccountAuthenticatorActivity; import android.accounts.AccountAuthenticatorActivity;
import android.accounts.AccountAuthenticatorResponse; import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager; import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog; import android.app.ProgressDialog;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -17,10 +18,12 @@ import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatDelegate; import android.support.v7.app.AppCompatDelegate;
import android.text.Editable; import android.text.Editable;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.TextView; import android.widget.TextView;
@ -32,7 +35,6 @@ import javax.inject.Named;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import dagger.android.AndroidInjection;
import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.PageTitle; import fr.free.nrw.commons.PageTitle;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
@ -70,6 +72,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
@BindView(R.id.loginTwoFactor) EditText twoFactorEdit; @BindView(R.id.loginTwoFactor) EditText twoFactorEdit;
@BindView(R.id.error_message_container) ViewGroup errorMessageContainer; @BindView(R.id.error_message_container) ViewGroup errorMessageContainer;
@BindView(R.id.error_message) TextView errorMessage; @BindView(R.id.error_message) TextView errorMessage;
@BindView(R.id.login_credentials) TextView loginCredentials;
@BindView(R.id.two_factor_container)TextInputLayout twoFactorContainer; @BindView(R.id.two_factor_container)TextInputLayout twoFactorContainer;
ProgressDialog progressDialog; ProgressDialog progressDialog;
private AppCompatDelegate delegate; private AppCompatDelegate delegate;
@ -92,14 +95,39 @@ public class LoginActivity extends AccountAuthenticatorActivity {
ButterKnife.bind(this); ButterKnife.bind(this);
usernameEdit.addTextChangedListener(textWatcher); usernameEdit.addTextChangedListener(textWatcher);
usernameEdit.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
passwordEdit.addTextChangedListener(textWatcher); passwordEdit.addTextChangedListener(textWatcher);
passwordEdit.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
twoFactorEdit.addTextChangedListener(textWatcher); twoFactorEdit.addTextChangedListener(textWatcher);
passwordEdit.setOnEditorActionListener(newLoginInputActionListener()); passwordEdit.setOnEditorActionListener(newLoginInputActionListener());
loginButton.setOnClickListener(view -> performLogin()); loginButton.setOnClickListener(view -> performLogin());
signupButton.setOnClickListener(view -> signUp()); signupButton.setOnClickListener(view -> signUp());
if(BuildConfig.FLAVOR == "beta"){
loginCredentials.setText(getString(R.string.login_credential));
} else {
loginCredentials.setVisibility(View.GONE);
}
} }
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)this.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override @Override
protected void onPostCreate(Bundle savedInstanceState) { protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState); super.onPostCreate(savedInstanceState);

View file

@ -1,128 +0,0 @@
package fr.free.nrw.commons.auth;
import android.accounts.AccountAuthenticatorResponse;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import java.io.IOException;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import timber.log.Timber;
import static android.accounts.AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE;
import static android.accounts.AccountManager.KEY_ACCOUNT_NAME;
import static android.accounts.AccountManager.KEY_ACCOUNT_TYPE;
import static fr.free.nrw.commons.auth.AccountUtil.ACCOUNT_TYPE;
class LoginTask extends AsyncTask<String, String, String> {
private LoginActivity loginActivity;
private String username;
private String password;
private String twoFactorCode = "";
private AccountUtil accountUtil;
private MediaWikiApi mwApi;
public LoginTask(LoginActivity loginActivity, String username, String password,
String twoFactorCode, AccountUtil accountUtil,
MediaWikiApi mwApi, SharedPreferences prefs) {
this.loginActivity = loginActivity;
this.username = username;
this.password = password;
this.twoFactorCode = twoFactorCode;
this.accountUtil = accountUtil;
this.mwApi = mwApi;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
loginActivity.progressDialog = new ProgressDialog(loginActivity);
loginActivity.progressDialog.setIndeterminate(true);
loginActivity.progressDialog.setTitle(loginActivity.getString(R.string.logging_in_title));
loginActivity.progressDialog.setMessage(loginActivity.getString(R.string.logging_in_message));
loginActivity.progressDialog.setCanceledOnTouchOutside(false);
loginActivity.progressDialog.show();
}
@Override
protected String doInBackground(String... params) {
try {
if (twoFactorCode.isEmpty()) {
return mwApi.login(username, password);
} else {
return mwApi.login(username, password, twoFactorCode);
}
} catch (IOException e) {
// Do something better!
return "NetworkFailure";
}
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Timber.d("Login done!");
if (result.equals("PASS")) {
handlePassResult();
} else {
handleOtherResults(result);
}
}
private void handlePassResult() {
loginActivity.showSuccessAndDismissDialog();
AccountAuthenticatorResponse response = null;
Bundle extras = loginActivity.getIntent().getExtras();
if (extras != null) {
Timber.d("Bundle of extras: %s", extras);
response = extras.getParcelable(KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
if (response != null) {
Bundle authResult = new Bundle();
authResult.putString(KEY_ACCOUNT_NAME, username);
authResult.putString(KEY_ACCOUNT_TYPE, ACCOUNT_TYPE);
response.onResult(authResult);
}
}
accountUtil.createAccount(response, username, password);
loginActivity.startMainActivity();
}
/**
* Match known failure message codes and provide messages.
* @param result String
*/
private void handleOtherResults(String result) {
if (result.equals("NetworkFailure")) {
// Matches NetworkFailure which is created by the doInBackground method
loginActivity.showMessageAndCancelDialog(R.string.login_failed_network);
} else if (result.toLowerCase().contains("nosuchuser".toLowerCase()) || result.toLowerCase().contains("noname".toLowerCase())) {
// Matches nosuchuser, nosuchusershort, noname
loginActivity.showMessageAndCancelDialog(R.string.login_failed_username);
loginActivity.emptySensitiveEditFields();
} else if (result.toLowerCase().contains("wrongpassword".toLowerCase())) {
// Matches wrongpassword, wrongpasswordempty
loginActivity.showMessageAndCancelDialog(R.string.login_failed_password);
loginActivity.emptySensitiveEditFields();
} else if (result.toLowerCase().contains("throttle".toLowerCase())) {
// Matches unknown throttle error codes
loginActivity.showMessageAndCancelDialog(R.string.login_failed_throttled);
} else if (result.toLowerCase().contains("userblocked".toLowerCase())) {
// Matches login-userblocked
loginActivity.showMessageAndCancelDialog(R.string.login_failed_blocked);
} else if (result.equals("2FA")) {
loginActivity.askUserForTwoFactorAuth();
} else {
// Occurs with unhandled login failure codes
Timber.d("Login failed with reason: %s", result);
loginActivity.showMessageAndCancelDialog(R.string.login_failed_generic);
}
}
}

View file

@ -1,18 +1,22 @@
package fr.free.nrw.commons.category; package fr.free.nrw.commons.category;
import android.content.Context; import android.app.Activity;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
@ -38,6 +42,7 @@ import fr.free.nrw.commons.R;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.upload.MwVolleyApi; import fr.free.nrw.commons.upload.MwVolleyApi;
import fr.free.nrw.commons.upload.SingleUploadFragment;
import fr.free.nrw.commons.utils.StringSortingUtils; import fr.free.nrw.commons.utils.StringSortingUtils;
import io.reactivex.Observable; import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
@ -73,6 +78,7 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
private OnCategoriesSaveHandler onCategoriesSaveHandler; private OnCategoriesSaveHandler onCategoriesSaveHandler;
private HashMap<String, ArrayList<String>> categoriesCache; private HashMap<String, ArrayList<String>> categoriesCache;
private List<CategoryItem> selectedCategories = new ArrayList<>(); private List<CategoryItem> selectedCategories = new ArrayList<>();
private TitleTextWatcher textWatcher = new TitleTextWatcher();
private final CategoriesAdapterFactory adapterFactory = new CategoriesAdapterFactory(item -> { private final CategoriesAdapterFactory adapterFactory = new CategoriesAdapterFactory(item -> {
if (item.isSelected()) { if (item.isSelected()) {
@ -103,6 +109,15 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
categoriesAdapter = adapterFactory.create(items); categoriesAdapter = adapterFactory.create(items);
categoriesList.setAdapter(categoriesAdapter); categoriesList.setAdapter(categoriesAdapter);
categoriesFilter.addTextChangedListener(textWatcher);
categoriesFilter.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
RxTextView.textChanges(categoriesFilter) RxTextView.textChanges(categoriesFilter)
.takeUntil(RxView.detaches(categoriesFilter)) .takeUntil(RxView.detaches(categoriesFilter))
.debounce(500, TimeUnit.MILLISECONDS) .debounce(500, TimeUnit.MILLISECONDS)
@ -111,6 +126,18 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
return rootView; return rootView;
} }
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override
public void onDestroyView() {
categoriesFilter.removeTextChangedListener(textWatcher);
super.onDestroyView();
}
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear(); menu.clear();
@ -352,4 +379,21 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
.create() .create()
.show(); .show();
} }
private class TitleTextWatcher implements TextWatcher {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i2, int i3) {
}
@Override
public void afterTextChanged(Editable editable) {
if (getActivity() != null) {
getActivity().invalidateOptionsMenu();
}
}
}
} }

View file

@ -197,6 +197,10 @@ public class Contribution extends Media {
this.localUri = localUri; this.localUri = localUri;
} }
public void setDecimalCoords(String decimalCoords) {
this.decimalCoords = decimalCoords;
}
@NonNull @NonNull
private String licenseTemplateFor(String license) { private String licenseTemplateFor(String license) {
switch (license) { switch (license) {
@ -215,6 +219,7 @@ public class Contribution extends Media {
case Prefs.Licenses.CC_BY_SA: case Prefs.Licenses.CC_BY_SA:
return "{{self|cc-by-sa-3.0}}"; return "{{self|cc-by-sa-3.0}}";
} }
throw new RuntimeException("Unrecognized license value: " + license); throw new RuntimeException("Unrecognized license value: " + license);
} }
} }

View file

@ -93,10 +93,15 @@ class ContributionController {
shareIntent.putExtra(EXTRA_SOURCE, SOURCE_GALLERY); shareIntent.putExtra(EXTRA_SOURCE, SOURCE_GALLERY);
break; break;
case SELECT_FROM_CAMERA: case SELECT_FROM_CAMERA:
shareIntent.setType("image/jpeg"); //FIXME: Find out appropriate mime type //FIXME: Find out appropriate mime type
// AFAIK this is the right type for a JPEG image
// https://developer.android.com/training/sharing/send.html#send-binary-content
shareIntent.setType("image/jpeg");
shareIntent.putExtra(EXTRA_STREAM, lastGeneratedCaptureUri); shareIntent.putExtra(EXTRA_STREAM, lastGeneratedCaptureUri);
shareIntent.putExtra(EXTRA_SOURCE, SOURCE_CAMERA); shareIntent.putExtra(EXTRA_SOURCE, SOURCE_CAMERA);
break; break;
default:
break;
} }
Timber.i("Image selected"); Timber.i("Image selected");
try { try {

View file

@ -86,7 +86,7 @@ public class ContributionsContentProvider extends CommonsDaggerContentProvider {
public Uri insert(@NonNull Uri uri, ContentValues contentValues) { public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
long id = 0; long id;
switch (uriType) { switch (uriType) {
case CONTRIBUTIONS: case CONTRIBUTIONS:
id = sqlDB.insert(TABLE_NAME, null, contentValues); id = sqlDB.insert(TABLE_NAME, null, contentValues);
@ -158,7 +158,7 @@ public class ContributionsContentProvider extends CommonsDaggerContentProvider {
*/ */
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
int rowsUpdated = 0; int rowsUpdated;
switch (uriType) { switch (uriType) {
case CONTRIBUTIONS: case CONTRIBUTIONS:
rowsUpdated = sqlDB.update(TABLE_NAME, contentValues, selection, selectionArgs); rowsUpdated = sqlDB.update(TABLE_NAME, contentValues, selection, selectionArgs);

View file

@ -20,6 +20,8 @@ import android.widget.ListAdapter;
import android.widget.ProgressBar; import android.widget.ProgressBar;
import android.widget.TextView; import android.widget.TextView;
import java.util.Arrays;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
@ -45,8 +47,12 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
@BindView(R.id.loadingContributionsProgressBar) @BindView(R.id.loadingContributionsProgressBar)
ProgressBar progressBar; ProgressBar progressBar;
@Inject @Named("prefs") SharedPreferences prefs; @Inject
@Inject @Named("default_preferences") SharedPreferences defaultPrefs; @Named("prefs")
SharedPreferences prefs;
@Inject
@Named("default_preferences")
SharedPreferences defaultPrefs;
private ContributionController controller; private ContributionController controller;
@ -208,7 +214,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) { @NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult: req code = " + " perm = " Timber.d("onRequestPermissionsResult: req code = " + " perm = "
+ permissions + " grant =" + grantResults); + Arrays.toString(permissions) + " grant =" + Arrays.toString(grantResults));
switch (requestCode) { switch (requestCode) {
// 1 = Storage allowed when gallery selected // 1 = Storage allowed when gallery selected

View file

@ -23,7 +23,6 @@ import java.util.TimeZone;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.di.ApplicationlessInjection; import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.mwapi.LogEventResult; import fr.free.nrw.commons.mwapi.LogEventResult;

View file

@ -1,7 +1,5 @@
package fr.free.nrw.commons.di; package fr.free.nrw.commons.di;
import android.content.Context;
import javax.inject.Singleton; import javax.inject.Singleton;
import dagger.Component; import dagger.Component;
@ -11,10 +9,7 @@ import dagger.android.support.AndroidSupportInjectionModule;
import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.MediaWikiImageView; import fr.free.nrw.commons.MediaWikiImageView;
import fr.free.nrw.commons.auth.LoginActivity; import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.category.CategoryContentProvider;
import fr.free.nrw.commons.contributions.ContributionsContentProvider;
import fr.free.nrw.commons.contributions.ContributionsSyncAdapter; import fr.free.nrw.commons.contributions.ContributionsSyncAdapter;
import fr.free.nrw.commons.modifications.ModificationsContentProvider;
import fr.free.nrw.commons.modifications.ModificationsSyncAdapter; import fr.free.nrw.commons.modifications.ModificationsSyncAdapter;
import fr.free.nrw.commons.settings.SettingsFragment; import fr.free.nrw.commons.settings.SettingsFragment;

View file

@ -14,9 +14,6 @@ import android.support.v4.content.ContextCompat;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import javax.inject.Inject;
import javax.inject.Singleton;
import timber.log.Timber; import timber.log.Timber;
public class LocationServiceManager implements LocationListener { public class LocationServiceManager implements LocationListener {
@ -33,6 +30,7 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Constructs a new instance of LocationServiceManager. * Constructs a new instance of LocationServiceManager.
*
* @param context the context * @param context the context
*/ */
public LocationServiceManager(Context context) { public LocationServiceManager(Context context) {
@ -42,6 +40,7 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Returns the current status of the GPS provider. * Returns the current status of the GPS provider.
*
* @return true if the GPS provider is enabled * @return true if the GPS provider is enabled
*/ */
public boolean isProviderEnabled() { public boolean isProviderEnabled() {
@ -50,6 +49,7 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Returns whether the location permission is granted. * Returns whether the location permission is granted.
*
* @return true if the location permission is granted * @return true if the location permission is granted
*/ */
public boolean isLocationPermissionGranted() { public boolean isLocationPermissionGranted() {
@ -59,6 +59,7 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Requests the location permission to be granted. * Requests the location permission to be granted.
*
* @param activity the activity * @param activity the activity
*/ */
public void requestPermissions(Activity activity) { public void requestPermissions(Activity activity) {
@ -71,11 +72,9 @@ public class LocationServiceManager implements LocationListener {
} }
public boolean isPermissionExplanationRequired(Activity activity) { public boolean isPermissionExplanationRequired(Activity activity) {
if (activity.isFinishing()) { return !activity.isFinishing() &&
return false; ActivityCompat.shouldShowRequestPermissionRationale(activity,
} Manifest.permission.ACCESS_FINE_LOCATION);
return ActivityCompat.shouldShowRequestPermissionRationale(activity,
Manifest.permission.ACCESS_FINE_LOCATION);
} }
public LatLng getLastLocation() { public LatLng getLastLocation() {
@ -85,7 +84,8 @@ public class LocationServiceManager implements LocationListener {
return LatLng.from(lastLocation); return LatLng.from(lastLocation);
} }
/** Registers a LocationManager to listen for current location. /**
* Registers a LocationManager to listen for current location.
*/ */
public void registerLocationManager() { public void registerLocationManager() {
if (!isLocationManagerRegistered) if (!isLocationManagerRegistered)
@ -95,6 +95,7 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Requests location updates from the specified provider. * Requests location updates from the specified provider.
*
* @param locationProvider the location provider * @param locationProvider the location provider
* @return true if successful * @return true if successful
*/ */
@ -116,7 +117,8 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Returns whether a given location is better than the current best location. * Returns whether a given location is better than the current best location.
* @param location the location to be tested *
* @param location the location to be tested
* @param currentBestLocation the current best location * @param currentBestLocation the current best location
* @return true if the given location is better * @return true if the given location is better
*/ */
@ -172,7 +174,8 @@ public class LocationServiceManager implements LocationListener {
return provider1.equals(provider2); return provider1.equals(provider2);
} }
/** Unregisters location manager. /**
* Unregisters location manager.
*/ */
public void unregisterLocationManager() { public void unregisterLocationManager() {
isLocationManagerRegistered = false; isLocationManagerRegistered = false;
@ -185,6 +188,7 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Adds a new listener to the list of location listeners. * Adds a new listener to the list of location listeners.
*
* @param listener the new listener * @param listener the new listener
*/ */
public void addLocationListener(LocationUpdateListener listener) { public void addLocationListener(LocationUpdateListener listener) {
@ -195,6 +199,7 @@ public class LocationServiceManager implements LocationListener {
/** /**
* Removes a listener from the list of location listeners. * Removes a listener from the list of location listeners.
*
* @param listener the listener to be removed * @param listener the listener to be removed
*/ */
public void removeLocationListener(LocationUpdateListener listener) { public void removeLocationListener(LocationUpdateListener listener) {

View file

@ -14,6 +14,7 @@ import android.view.ViewTreeObserver;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -76,7 +77,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
private ViewTreeObserver.OnGlobalLayoutListener layoutListener; // for layout stuff, only used once! private ViewTreeObserver.OnGlobalLayoutListener layoutListener; // for layout stuff, only used once!
private ViewTreeObserver.OnScrollChangedListener scrollListener; private ViewTreeObserver.OnScrollChangedListener scrollListener;
private DataSetObserver dataObserver; private DataSetObserver dataObserver;
private AsyncTask<Void,Void,Boolean> detailFetchTask; private AsyncTask<Void, Void, Boolean> detailFetchTask;
private LicenseList licenseList; private LicenseList licenseList;
@Override @Override
@ -95,7 +96,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
detailProvider = (MediaDetailPagerFragment.MediaDetailProvider)getActivity(); detailProvider = (MediaDetailPagerFragment.MediaDetailProvider) getActivity();
if (savedInstanceState != null) { if (savedInstanceState != null) {
editable = savedInstanceState.getBoolean("editable"); editable = savedInstanceState.getBoolean("editable");
@ -156,7 +157,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
return view; return view;
} }
@Override public void onResume() { @Override
public void onResume() {
super.onResume(); super.onResume();
Media media = detailProvider.getMediaAtPosition(index); Media media = detailProvider.getMediaAtPosition(index);
if (media == null) { if (media == null) {
@ -238,13 +240,13 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
detailFetchTask.cancel(true); detailFetchTask.cancel(true);
detailFetchTask = null; detailFetchTask = null;
} }
if (layoutListener != null) { if (layoutListener != null && getView() != null) {
getView().getViewTreeObserver().removeGlobalOnLayoutListener(layoutListener); // old Android was on crack. CRACK IS WHACK getView().getViewTreeObserver().removeGlobalOnLayoutListener(layoutListener); // old Android was on crack. CRACK IS WHACK
layoutListener = null; layoutListener = null;
} }
if (scrollListener != null) { if (scrollListener != null && getView() != null) {
getView().getViewTreeObserver().removeOnScrollChangedListener(scrollListener); getView().getViewTreeObserver().removeOnScrollChangedListener(scrollListener);
scrollListener = null; scrollListener = null;
} }
if (dataObserver != null) { if (dataObserver != null) {
detailProvider.unregisterDataSetObserver(dataObserver); detailProvider.unregisterDataSetObserver(dataObserver);
@ -272,7 +274,12 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
} }
private void setOnClickListeners(final Media media) { private void setOnClickListeners(final Media media) {
license.setOnClickListener(v -> openWebBrowser(licenseLink(media))); if (licenseLink(media) != null) {
license.setOnClickListener(v -> openWebBrowser(licenseLink(media)));
} else {
Toast toast = Toast.makeText(getContext(), getString(R.string.null_url), Toast.LENGTH_SHORT);
toast.show();
}
if (media.getCoordinates() != null) { if (media.getCoordinates() != null) {
coordinates.setOnClickListener(v -> openMap(media.getCoordinates())); coordinates.setOnClickListener(v -> openMap(media.getCoordinates()));
} }
@ -289,7 +296,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
private View buildCatLabel(final String catName, ViewGroup categoryContainer) { private View buildCatLabel(final String catName, ViewGroup categoryContainer) {
final View item = LayoutInflater.from(getContext()).inflate(R.layout.detail_category_item, categoryContainer, false); final View item = LayoutInflater.from(getContext()).inflate(R.layout.detail_category_item, categoryContainer, false);
final CompatTextView textView = (CompatTextView)item.findViewById(R.id.mediaDetailCategoryItemText); final CompatTextView textView = (CompatTextView) item.findViewById(R.id.mediaDetailCategoryItemText);
textView.setText(catName); textView.setText(catName);
if (categoriesLoaded && categoriesPresent) { if (categoriesLoaded && categoriesPresent) {
@ -308,7 +315,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
// You must face the darkness alone // You must face the darkness alone
int scrollY = scrollView.getScrollY(); int scrollY = scrollView.getScrollY();
int scrollMax = getView().getHeight(); int scrollMax = getView().getHeight();
float scrollPercentage = (float)scrollY / (float)scrollMax; float scrollPercentage = (float) scrollY / (float) scrollMax;
final float transparencyMax = 0.75f; final float transparencyMax = 0.75f;
if (scrollPercentage > transparencyMax) { if (scrollPercentage > transparencyMax) {
scrollPercentage = transparencyMax; scrollPercentage = transparencyMax;
@ -362,7 +369,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
} }
private @Nullable String licenseLink(Media media) { private @Nullable
String licenseLink(Media media) {
String licenseKey = media.getLicense(); String licenseKey = media.getLicense();
if (licenseKey == null || licenseKey.equals("")) { if (licenseKey == null || licenseKey.equals("")) {
return null; return null;

View file

@ -43,9 +43,13 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener { public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment implements ViewPager.OnPageChangeListener {
@Inject MediaWikiApi mwApi; @Inject
@Inject SessionManager sessionManager; MediaWikiApi mwApi;
@Inject @Named("default_preferences") SharedPreferences prefs; @Inject
SessionManager sessionManager;
@Inject
@Named("default_preferences")
SharedPreferences prefs;
private ViewPager pager; private ViewPager pager;
private Boolean editable; private Boolean editable;
@ -164,13 +168,19 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
req.allowScanningByMediaScanner(); req.allowScanningByMediaScanner();
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !(ContextCompat.checkSelfPermission(getContext(), READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ContextCompat.checkSelfPermission(getContext(), READ_EXTERNAL_STORAGE)
!= PERMISSION_GRANTED
&& getView() != null) {
Snackbar.make(getView(), R.string.read_storage_permission_rationale, Snackbar.make(getView(), R.string.read_storage_permission_rationale,
Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok, Snackbar.LENGTH_INDEFINITE).setAction(R.string.ok,
view -> ActivityCompat.requestPermissions(getActivity(), view -> ActivityCompat.requestPermissions(getActivity(),
new String[]{READ_EXTERNAL_STORAGE}, 1)).show(); new String[]{READ_EXTERNAL_STORAGE}, 1)).show();
} else { } else {
((DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE)).enqueue(req); DownloadManager systemService = (DownloadManager) getActivity().getSystemService(DOWNLOAD_SERVICE);
if (systemService != null) {
systemService.enqueue(req);
}
} }
} }

View file

@ -70,7 +70,7 @@ public class ModificationsContentProvider extends CommonsDaggerContentProvider {
public Uri insert(@NonNull Uri uri, ContentValues contentValues) { public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
long id = 0; long id;
switch (uriType) { switch (uriType) {
case MODIFICATIONS: case MODIFICATIONS:
id = sqlDB.insert(TABLE_NAME, null, contentValues); id = sqlDB.insert(TABLE_NAME, null, contentValues);
@ -132,7 +132,7 @@ public class ModificationsContentProvider extends CommonsDaggerContentProvider {
*/ */
int uriType = uriMatcher.match(uri); int uriType = uriMatcher.match(uri);
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase(); SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
int rowsUpdated = 0; int rowsUpdated;
switch (uriType) { switch (uriType) {
case MODIFICATIONS: case MODIFICATIONS:
rowsUpdated = sqlDB.update(TABLE_NAME, rowsUpdated = sqlDB.update(TABLE_NAME,

View file

@ -52,7 +52,7 @@ public class ModifierSequenceDao {
ModifierSequence fromCursor(Cursor cursor) { ModifierSequence fromCursor(Cursor cursor) {
// Hardcoding column positions! // Hardcoding column positions!
ModifierSequence ms = null; ModifierSequence ms;
try { try {
ms = new ModifierSequence(Uri.parse(cursor.getString(1)), ms = new ModifierSequence(Uri.parse(cursor.getString(1)),
new JSONObject(cursor.getString(2))); new JSONObject(cursor.getString(2)));

View file

@ -1,6 +1,5 @@
package fr.free.nrw.commons.nearby; package fr.free.nrw.commons.nearby;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -11,6 +10,7 @@ import android.preference.PreferenceManager;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AlertDialog; import android.support.v7.app.AlertDialog;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -41,8 +41,6 @@ import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers; import io.reactivex.schedulers.Schedulers;
import timber.log.Timber; import timber.log.Timber;
import static fr.free.nrw.commons.location.LocationServiceManager.LOCATION_REQUEST;
public class NearbyActivity extends NavigationBaseActivity implements LocationUpdateListener { public class NearbyActivity extends NavigationBaseActivity implements LocationUpdateListener {
@ -63,7 +61,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
private NearbyActivityMode viewMode; private NearbyActivityMode viewMode;
private Disposable placesDisposable; private Disposable placesDisposable;
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
@BindView(R.id.swipe_container) SwipeRefreshLayout swipeLayout;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -73,6 +71,13 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
bundle = new Bundle(); bundle = new Bundle();
initDrawer(); initDrawer();
initViewState(); initViewState();
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
lockNearbyView(false);
refreshView(true);
}
});
} }
private void initViewState() { private void initViewState() {
@ -259,7 +264,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
/** /**
* This method should be the single point to load/refresh nearby places * This method should be the single point to load/refresh nearby places
* *
* @param isHardRefresh * @param isHardRefresh Should display a toast if the location hasn't changed
*/ */
private void refreshView(boolean isHardRefresh) { private void refreshView(boolean isHardRefresh) {
if (lockNearbyView) { if (lockNearbyView) {
@ -312,7 +317,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
} else { } else {
setListFragment(); setListFragment();
} }
swipeLayout.setRefreshing(false);
hideProgressBar(); hideProgressBar();
} }

View file

@ -39,8 +39,9 @@ public class NearbyController {
/** /**
* Prepares Place list to make their distance information update later. * Prepares Place list to make their distance information update later.
*
* @param curLatLng current location for user * @param curLatLng current location for user
* @param context context * @param context context
* @return Place list without distance information * @return Place list without distance information
*/ */
public List<Place> loadAttractionsFromLocation(LatLng curLatLng, Context context) { public List<Place> loadAttractionsFromLocation(LatLng curLatLng, Context context) {
@ -51,25 +52,24 @@ public class NearbyController {
List<Place> places = prefs.getBoolean("useWikidata", true) List<Place> places = prefs.getBoolean("useWikidata", true)
? nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage()) ? nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage())
: nearbyPlaces.getFromWikiNeedsPictures(); : nearbyPlaces.getFromWikiNeedsPictures();
if (curLatLng != null) { Timber.d("Sorting places by distance...");
Timber.d("Sorting places by distance..."); final Map<Place, Double> distances = new HashMap<>();
final Map<Place, Double> distances = new HashMap<>(); for (Place place : places) {
for (Place place: places) { distances.put(place, computeDistanceBetween(place.location, curLatLng));
distances.put(place, computeDistanceBetween(place.location, curLatLng));
}
Collections.sort(places,
(lhs, rhs) -> {
double lhsDistance = distances.get(lhs);
double rhsDistance = distances.get(rhs);
return (int) (lhsDistance - rhsDistance);
}
);
} }
Collections.sort(places,
(lhs, rhs) -> {
double lhsDistance = distances.get(lhs);
double rhsDistance = distances.get(rhs);
return (int) (lhsDistance - rhsDistance);
}
);
return places; return places;
} }
/** /**
* Loads attractions from location for list view, we need to return Place data type. * Loads attractions from location for list view, we need to return Place data type.
*
* @param curLatLng users current location * @param curLatLng users current location
* @param placeList list of nearby places in Place data type * @param placeList list of nearby places in Place data type
* @return Place list that holds nearby places * @return Place list that holds nearby places
@ -78,7 +78,7 @@ public class NearbyController {
LatLng curLatLng, LatLng curLatLng,
List<Place> placeList) { List<Place> placeList) {
placeList = placeList.subList(0, Math.min(placeList.size(), MAX_RESULTS)); placeList = placeList.subList(0, Math.min(placeList.size(), MAX_RESULTS));
for (Place place: placeList) { for (Place place : placeList) {
String distance = formatDistanceBetween(curLatLng, place.location); String distance = formatDistanceBetween(curLatLng, place.location);
place.setDistance(distance); place.setDistance(distance);
} }
@ -86,7 +86,8 @@ public class NearbyController {
} }
/** /**
*Loads attractions from location for map view, we need to return BaseMarkerOption data type. * Loads attractions from location for map view, we need to return BaseMarkerOption data type.
*
* @param curLatLng users current location * @param curLatLng users current location
* @param placeList list of nearby places in Place data type * @param placeList list of nearby places in Place data type
* @return BaseMarkerOptions list that holds nearby places * @return BaseMarkerOptions list that holds nearby places
@ -103,26 +104,28 @@ public class NearbyController {
placeList = placeList.subList(0, Math.min(placeList.size(), MAX_RESULTS)); placeList = placeList.subList(0, Math.min(placeList.size(), MAX_RESULTS));
Bitmap icon = UiUtils.getBitmap( VectorDrawableCompat vectorDrawable = VectorDrawableCompat.create(
VectorDrawableCompat.create( context.getResources(), R.drawable.ic_custom_map_marker, context.getTheme()
context.getResources(), R.drawable.ic_custom_map_marker, context.getTheme() );
)); if (vectorDrawable != null) {
Bitmap icon = UiUtils.getBitmap(vectorDrawable);
for (Place place: placeList) { for (Place place : placeList) {
String distance = formatDistanceBetween(curLatLng, place.location); String distance = formatDistanceBetween(curLatLng, place.location);
place.setDistance(distance); place.setDistance(distance);
NearbyBaseMarker nearbyBaseMarker = new NearbyBaseMarker(); NearbyBaseMarker nearbyBaseMarker = new NearbyBaseMarker();
nearbyBaseMarker.title(place.name); nearbyBaseMarker.title(place.name);
nearbyBaseMarker.position( nearbyBaseMarker.position(
new com.mapbox.mapboxsdk.geometry.LatLng( new com.mapbox.mapboxsdk.geometry.LatLng(
place.location.getLatitude(), place.location.getLatitude(),
place.location.getLongitude())); place.location.getLongitude()));
nearbyBaseMarker.place(place); nearbyBaseMarker.place(place);
nearbyBaseMarker.icon(IconFactory.getInstance(context) nearbyBaseMarker.icon(IconFactory.getInstance(context)
.fromBitmap(icon)); .fromBitmap(icon));
baseMarkerOptions.add(nearbyBaseMarker); baseMarkerOptions.add(nearbyBaseMarker);
}
} }
return baseMarkerOptions; return baseMarkerOptions;
} }

View file

@ -3,7 +3,9 @@ package fr.free.nrw.commons.nearby;
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.support.customtabs.CustomTabsIntent;
import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.PopupMenu; import android.support.v7.widget.PopupMenu;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MenuItem; import android.view.MenuItem;
@ -17,6 +19,7 @@ import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.Unbinder; import butterknife.Unbinder;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.ui.widget.OverlayDialog; import fr.free.nrw.commons.ui.widget.OverlayDialog;
import fr.free.nrw.commons.utils.DialogUtil; import fr.free.nrw.commons.utils.DialogUtil;
@ -141,8 +144,7 @@ public class NearbyInfoDialog extends OverlayDialog {
} }
private void openWebView(Uri link) { private void openWebView(Uri link) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, link); Utils.handleWebUrl(getContext(),link);
startActivity(browserIntent);
} }
@OnClick(R.id.emptyLayout) @OnClick(R.id.emptyLayout)

View file

@ -19,7 +19,6 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import dagger.android.support.AndroidSupportInjection; import dagger.android.support.AndroidSupportInjection;
import dagger.android.support.DaggerFragment;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.utils.UriDeserializer; import fr.free.nrw.commons.utils.UriDeserializer;

View file

@ -9,7 +9,6 @@ import android.view.ViewGroup;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import dagger.android.support.AndroidSupportInjection; import dagger.android.support.AndroidSupportInjection;
import dagger.android.support.DaggerFragment;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import timber.log.Timber; import timber.log.Timber;

View file

@ -5,11 +5,13 @@ import android.content.Context;
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.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import com.pedrogomez.renderers.RVRendererAdapter; import com.pedrogomez.renderers.RVRendererAdapter;
import java.util.Collections;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
@ -45,8 +47,9 @@ public class NotificationActivity extends NavigationBaseActivity {
} }
private void initListView() { private void initListView() {
recyclerView = findViewById(R.id.listView);
recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setLayoutManager(new LinearLayoutManager(this));
DividerItemDecoration itemDecor = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
recyclerView.addItemDecoration(itemDecor);
addNotifications(); addNotifications();
} }
@ -58,11 +61,10 @@ public class NotificationActivity extends NavigationBaseActivity {
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe(notificationList -> { .subscribe(notificationList -> {
Collections.reverse(notificationList);
Timber.d("Number of notifications is %d", notificationList.size()); Timber.d("Number of notifications is %d", notificationList.size());
setAdapter(notificationList); setAdapter(notificationList);
}, throwable -> { }, throwable -> Timber.e(throwable, "Error occurred while loading notifications"));
Timber.e(throwable, "Error occurred while loading notifications");
});
} }
private void handleUrl(String url) { private void handleUrl(String url) {

View file

@ -8,13 +8,9 @@ import android.widget.TextView;
import com.pedrogomez.renderers.Renderer; import com.pedrogomez.renderers.Renderer;
import java.util.Calendar;
import java.util.Date;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.utils.DateUtils;
/** /**
* Created by root on 19.12.2017. * Created by root on 19.12.2017.

View file

@ -25,7 +25,6 @@ import java.io.File;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import dagger.android.AndroidInjection;
import fr.free.nrw.commons.BuildConfig; import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;

View file

@ -5,6 +5,7 @@ import android.accounts.AccountManager;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView; import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
@ -119,8 +120,9 @@ public abstract class NavigationBaseActivity extends BaseActivity
return true; return true;
case R.id.action_feedback: case R.id.action_feedback:
drawerLayout.closeDrawer(navigationView); drawerLayout.closeDrawer(navigationView);
Intent feedbackIntent = new Intent(Intent.ACTION_SEND); Intent feedbackIntent = new Intent(Intent.ACTION_SENDTO);
feedbackIntent.setType("message/rfc822"); feedbackIntent.setType("message/rfc822");
feedbackIntent.setData(Uri.parse("mailto:"));
feedbackIntent.putExtra(Intent.EXTRA_EMAIL, feedbackIntent.putExtra(Intent.EXTRA_EMAIL,
new String[]{CommonsApplication.FEEDBACK_EMAIL}); new String[]{CommonsApplication.FEEDBACK_EMAIL});
feedbackIntent.putExtra(Intent.EXTRA_SUBJECT, feedbackIntent.putExtra(Intent.EXTRA_SUBJECT,

View file

@ -1,7 +1,7 @@
package fr.free.nrw.commons.ui.widget; package fr.free.nrw.commons.ui.widget;
/** /*
* Created by mikel on 07/08/2017. *Created by mikel on 07/08/2017.
*/ */
import android.content.Context; import android.content.Context;
@ -20,20 +20,22 @@ import fr.free.nrw.commons.utils.UiUtils;
* a text view compatible with older versions of the platform * a text view compatible with older versions of the platform
*/ */
public class CompatTextView extends AppCompatTextView { public class CompatTextView extends AppCompatTextView {
/** /**
* Constructs a new instance of CompatTextView * Constructs a new instance of CompatTextView
*
* @param context the view context * @param context the view context
*/ */
public CompatTextView(Context context) { public CompatTextView(Context context) {
super(context); super(context);
init(null); init(null);
} }
/** /**
* Constructs a new instance of CompatTextView * Constructs a new instance of CompatTextView
*
* @param context the view context * @param context the view context
* @param attrs the set of attributes for the view * @param attrs the set of attributes for the view
*/ */
public CompatTextView(Context context, AttributeSet attrs) { public CompatTextView(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
@ -42,6 +44,7 @@ public class CompatTextView extends AppCompatTextView {
/** /**
* Constructs a new instance of CompatTextView * Constructs a new instance of CompatTextView
*
* @param context * @param context
* @param attrs * @param attrs
* @param defStyleAttr * @param defStyleAttr
@ -53,6 +56,7 @@ public class CompatTextView extends AppCompatTextView {
/** /**
* initializes the view * initializes the view
*
* @param attrs the attribute set of the view, which can be null * @param attrs the attribute set of the view, which can be null
*/ */
private void init(@Nullable AttributeSet attrs) { private void init(@Nullable AttributeSet attrs) {

View file

@ -19,7 +19,7 @@ public abstract class OverlayDialog extends DialogFragment {
/** /**
* creates a DialogFragment with the correct style and theme * creates a DialogFragment with the correct style and theme
* @param savedInstanceState * @param savedInstanceState bundle re-constructed from a previous saved state
*/ */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {

View file

@ -0,0 +1,59 @@
package fr.free.nrw.commons.upload;
import android.content.Context;
import android.graphics.BitmapRegionDecoder;
import android.net.Uri;
import android.os.AsyncTask;
import java.io.IOException;
import fr.free.nrw.commons.utils.ImageUtils;
import timber.log.Timber;
/**
* Created by bluesir9 on 16/9/17.
*
* <p>Responsible for checking if the picture that the user is trying to upload is useful or not. Will attempt to filter
* away completely black,fuzzy/blurry pictures(for now).
*
* <p>todo: Detect selfies?
*/
public class DetectUnwantedPicturesAsync extends AsyncTask<Void, Void, ImageUtils.Result> {
interface Callback {
void onResult(ImageUtils.Result result);
}
private final Callback callback;
private final String imageMediaFilePath;
DetectUnwantedPicturesAsync(String imageMediaFilePath, Callback callback) {
this.callback = callback;
this.imageMediaFilePath = imageMediaFilePath;
}
@Override
protected ImageUtils.Result doInBackground(Void... voids) {
try {
Timber.d("FilePath: " + imageMediaFilePath);
if (imageMediaFilePath == null) {
return ImageUtils.Result.IMAGE_OK;
}
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(imageMediaFilePath,false);
return ImageUtils.checkIfImageIsTooDark(decoder);
} catch (IOException ioe) {
Timber.e(ioe, "IO Exception");
return ImageUtils.Result.IMAGE_OK;
}
}
@Override
protected void onPostExecute(ImageUtils.Result result) {
super.onPostExecute(result);
//callback to UI so that it can take necessary decision based on the result obtained
callback.onResult(result);
}
}

View file

@ -3,20 +3,25 @@ package fr.free.nrw.commons.upload;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.ContentUris; import android.content.ContentUris;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Environment; import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import java.io.File;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.nio.channels.FileChannel; import java.nio.channels.FileChannel;
import java.util.Date;
import timber.log.Timber; import timber.log.Timber;
@ -28,7 +33,7 @@ public class FileUtils {
* other file-based ContentProviders. * other file-based ContentProviders.
* *
* @param context The context. * @param context The context.
* @param uri The Uri to query. * @param uri The Uri to query.
* @author paulburke * @author paulburke
*/ */
// Can be safely suppressed, checks for isKitKat before running isDocumentUri // Can be safely suppressed, checks for isKitKat before running isDocumentUri
@ -36,6 +41,7 @@ public class FileUtils {
@Nullable @Nullable
public static String getPath(Context context, Uri uri) { public static String getPath(Context context, Uri uri) {
String returnPath = null;
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider // DocumentProvider
@ -47,7 +53,7 @@ public class FileUtils {
final String type = split[0]; final String type = split[0];
if ("primary".equalsIgnoreCase(type)) { if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1]; returnPath = Environment.getExternalStorageDirectory() + "/" + split[1];
} }
} else if (isDownloadsDocument(uri)) { // DownloadsProvider } else if (isDownloadsDocument(uri)) { // DownloadsProvider
@ -55,19 +61,26 @@ public class FileUtils {
final Uri contentUri = ContentUris.withAppendedId( final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null); returnPath = getDataColumn(context, contentUri, null, null);
} else if (isMediaDocument(uri)) { // MediaProvider } else if (isMediaDocument(uri)) { // MediaProvider
final String docId = DocumentsContract.getDocumentId(uri); final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":"); final String[] split = docId.split(":");
final String type = split[0]; final String type = split[0];
Uri contentUri = null; Uri contentUri = null;
if ("image".equals(type)) { switch (type) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; case "image":
} else if ("video".equals(type)) { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; break;
} else if ("audio".equals(type)) { case "video":
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
break;
case "audio":
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
break;
default:
break;
} }
final String selection = "_id=?"; final String selection = "_id=?";
@ -75,16 +88,55 @@ public class FileUtils {
split[1] split[1]
}; };
return getDataColumn(context, contentUri, selection, selectionArgs); returnPath = getDataColumn(context, contentUri, selection, selectionArgs);
} }
} }
// MediaStore (and general) // MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) { else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null); returnPath = getDataColumn(context, uri, null, null);
} }
// File // File
else if ("file".equalsIgnoreCase(uri.getScheme())) { else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath(); returnPath = uri.getPath();
}
if(returnPath == null) {
//fetching path may fail depending on the source URI and all hope is lost
//so we will create and use a copy of the file, which seems to work
String copyPath = null;
try {
ParcelFileDescriptor descriptor
= context.getContentResolver().openFileDescriptor(uri, "r");
if (descriptor != null) {
SharedPreferences sharedPref = PreferenceManager
.getDefaultSharedPreferences(context);
boolean useExtStorage = sharedPref.getBoolean("useExternalStorage", true);
if (useExtStorage) {
copyPath = Environment.getExternalStorageDirectory().toString()
+ "/CommonsApp/" + new Date().getTime() + ".jpg";
File newFile = new File(Environment.getExternalStorageDirectory().toString() + "/CommonsApp");
newFile.mkdir();
FileUtils.copy(
descriptor.getFileDescriptor(),
copyPath);
Timber.d("Filepath (copied): %s", copyPath);
return copyPath;
}
copyPath = context.getCacheDir().getAbsolutePath()
+ "/" + new Date().getTime() + ".jpg";
FileUtils.copy(
descriptor.getFileDescriptor(),
copyPath);
Timber.d("Filepath (copied): %s", copyPath);
return copyPath;
}
} catch (IOException e) {
Timber.w(e, "Error in file " + copyPath);
return null;
}
} else {
return returnPath;
} }
return null; return null;
@ -105,7 +157,7 @@ public class FileUtils {
String[] selectionArgs) { String[] selectionArgs) {
Cursor cursor = null; Cursor cursor = null;
final String column = "_data"; final String column = MediaStore.Images.ImageColumns.DATA;
final String[] projection = { final String[] projection = {
column column
}; };
@ -159,7 +211,8 @@ public class FileUtils {
/** /**
* Copy content from source file to destination file. * Copy content from source file to destination file.
* @param source stream copied from *
* @param source stream copied from
* @param destination stream copied to * @param destination stream copied to
* @throws IOException thrown when failing to read source or opening destination file * @throws IOException thrown when failing to read source or opening destination file
*/ */
@ -172,7 +225,8 @@ public class FileUtils {
/** /**
* Copy content from source file to destination file. * Copy content from source file to destination file.
* @param source file descriptor copied from *
* @param source file descriptor copied from
* @param destination file path copied to * @param destination file path copied to
* @throws IOException thrown when failing to read source or opening destination file * @throws IOException thrown when failing to read source or opening destination file
*/ */

View file

@ -113,11 +113,11 @@ public class GPSExtractor {
*/ */
@Nullable @Nullable
public String getCoords(boolean useGPS) { public String getCoords(boolean useGPS) {
String latitude = ""; String latitude;
String longitude = ""; String longitude;
String latitude_ref = ""; String latitudeRef;
String longitude_ref = ""; String longitudeRef;
String decimalCoords = ""; String decimalCoords;
//If image has no EXIF data and user has enabled GPS setting, get user's location //If image has no EXIF data and user has enabled GPS setting, get user's location
if (exif == null || exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) == null) { if (exif == null || exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) == null) {
@ -150,15 +150,15 @@ public class GPSExtractor {
Timber.d("EXIF data has location info"); Timber.d("EXIF data has location info");
latitude = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE); latitude = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
latitude_ref = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF); latitudeRef = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
longitude = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE); longitude = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
longitude_ref = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF); longitudeRef = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
if (latitude!=null && latitude_ref!=null && longitude!=null && longitude_ref!=null) { if (latitude!=null && latitudeRef!=null && longitude!=null && longitudeRef!=null) {
Timber.d("Latitude: %s %s", latitude, latitude_ref); Timber.d("Latitude: %s %s", latitude, latitudeRef);
Timber.d("Longitude: %s %s", longitude, longitude_ref); Timber.d("Longitude: %s %s", longitude, longitudeRef);
decimalCoords = getDecimalCoords(latitude, latitude_ref, longitude, longitude_ref); decimalCoords = getDecimalCoords(latitude, latitudeRef, longitude, longitudeRef);
return decimalCoords; return decimalCoords;
} else { } else {
return null; return null;

View file

@ -11,7 +11,9 @@ import android.database.DataSetObserver;
import android.net.Uri; import android.net.Uri;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
@ -21,6 +23,7 @@ import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.Toast; import android.widget.Toast;
import java.io.FileNotFoundException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -51,11 +54,17 @@ public class MultipleShareActivity extends AuthenticatedActivity
MultipleUploadListFragment.OnMultipleUploadInitiatedHandler, MultipleUploadListFragment.OnMultipleUploadInitiatedHandler,
OnCategoriesSaveHandler { OnCategoriesSaveHandler {
@Inject MediaWikiApi mwApi; @Inject
@Inject SessionManager sessionManager; MediaWikiApi mwApi;
@Inject UploadController uploadController; @Inject
@Inject ModifierSequenceDao modifierSequenceDao; SessionManager sessionManager;
@Inject @Named("default_preferences") SharedPreferences prefs; @Inject
UploadController uploadController;
@Inject
ModifierSequenceDao modifierSequenceDao;
@Inject
@Named("default_preferences")
SharedPreferences prefs;
private ArrayList<Contribution> photosList = null; private ArrayList<Contribution> photosList = null;
@ -63,6 +72,8 @@ public class MultipleShareActivity extends AuthenticatedActivity
private MediaDetailPagerFragment mediaDetails; private MediaDetailPagerFragment mediaDetails;
private CategorizationFragment categorizationFragment; private CategorizationFragment categorizationFragment;
private boolean locationPermitted = false;
@Override @Override
public Media getMediaAtPosition(int i) { public Media getMediaAtPosition(int i) {
return photosList.get(i); return photosList.get(i);
@ -207,6 +218,14 @@ public class MultipleShareActivity extends AuthenticatedActivity
getSupportFragmentManager().addOnBackStackChangedListener(this); getSupportFragmentManager().addOnBackStackChangedListener(this);
requestAuthToken(); requestAuthToken();
//TODO: 15/10/17 should location permission be explicitly requested if not provided?
//check if location permission is enabled
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationPermitted = true;
}
}
} }
@Override @Override
@ -240,7 +259,7 @@ public class MultipleShareActivity extends AuthenticatedActivity
mwApi.setAuthCookie(authCookie); mwApi.setAuthCookie(authCookie);
Intent intent = getIntent(); Intent intent = getIntent();
if (intent.getAction().equals(Intent.ACTION_SEND_MULTIPLE)) { if (Intent.ACTION_SEND_MULTIPLE.equals(intent.getAction())) {
if (photosList == null) { if (photosList == null) {
photosList = new ArrayList<>(); photosList = new ArrayList<>();
ArrayList<Uri> urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); ArrayList<Uri> urisList = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
@ -252,6 +271,11 @@ public class MultipleShareActivity extends AuthenticatedActivity
up.setTag("sequence", i); up.setTag("sequence", i);
up.setSource(Contribution.SOURCE_EXTERNAL); up.setSource(Contribution.SOURCE_EXTERNAL);
up.setMultiple(true); up.setMultiple(true);
String imageGpsCoordinates = extractImageGpsData(uri);
if (imageGpsCoordinates != null) {
Timber.d("GPS data for image found!");
up.setDecimalCoords(imageGpsCoordinates);
}
photosList.add(up); photosList.add(up);
} }
} }
@ -278,7 +302,49 @@ public class MultipleShareActivity extends AuthenticatedActivity
@Override @Override
public void onBackStackChanged() { public void onBackStackChanged() {
getSupportActionBar().setDisplayHomeAsUpEnabled(mediaDetails != null && mediaDetails.isVisible()) ; getSupportActionBar().setDisplayHomeAsUpEnabled(mediaDetails != null && mediaDetails.isVisible());
} }
/**
* Will attempt to extract the gps coordinates using exif data or by using the current
* location if available for the image who's imageUri has been provided.
* @param imageUri The uri of the image who's GPS coordinates data we wish to extract
* @return GPS coordinates as a String as is returned by {@link GPSExtractor}
*/
@Nullable
private String extractImageGpsData(Uri imageUri) {
Timber.d("Entering extractImagesGpsData");
if (imageUri == null) {
//now why would you do that???
return null;
}
GPSExtractor gpsExtractor = null;
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(imageUri,"r");
if (fd != null) {
gpsExtractor = new GPSExtractor(fd.getFileDescriptor(),this,prefs);
}
} else {
String filePath = FileUtils.getPath(this,imageUri);
if (filePath != null) {
gpsExtractor = new GPSExtractor(filePath,this,prefs);
}
}
if (gpsExtractor != null) {
//get image coordinates from exif data or user location
return gpsExtractor.getCoords(locationPermitted);
}
} catch (FileNotFoundException fnfe) {
Timber.w(fnfe);
return null;
}
return null;
}
} }

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.upload; package fr.free.nrw.commons.upload;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.graphics.Point; import android.graphics.Point;
import android.net.Uri; import android.net.Uri;
@ -10,6 +11,7 @@ import android.text.Editable;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -177,9 +179,21 @@ public class MultipleUploadListFragment extends Fragment {
photosGrid.setColumnWidth(photoSize.x); photosGrid.setColumnWidth(photoSize.x);
baseTitle.addTextChangedListener(textWatcher); baseTitle.addTextChangedListener(textWatcher);
baseTitle.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
hideKeyboard(v);
}
});
return view; return view;
} }
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
@Override @Override
public void onDestroyView() { public void onDestroyView() {
baseTitle.removeTextChangedListener(textWatcher); baseTitle.removeTextChangedListener(textWatcher);

View file

@ -2,6 +2,7 @@ package fr.free.nrw.commons.upload;
import android.Manifest; import android.Manifest;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -16,7 +17,9 @@ import android.support.annotation.RequiresApi;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.graphics.drawable.VectorDrawableCompat; import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat; import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
@ -46,11 +49,14 @@ import fr.free.nrw.commons.caching.CacheController;
import fr.free.nrw.commons.category.CategorizationFragment; import fr.free.nrw.commons.category.CategorizationFragment;
import fr.free.nrw.commons.category.OnCategoriesSaveHandler; import fr.free.nrw.commons.category.OnCategoriesSaveHandler;
import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.contributions.ContributionsActivity;
import fr.free.nrw.commons.modifications.CategoryModifier; import fr.free.nrw.commons.modifications.CategoryModifier;
import fr.free.nrw.commons.modifications.ModificationsContentProvider; import fr.free.nrw.commons.modifications.ModificationsContentProvider;
import fr.free.nrw.commons.modifications.ModifierSequence; import fr.free.nrw.commons.modifications.ModifierSequence;
import fr.free.nrw.commons.modifications.ModifierSequenceDao; import fr.free.nrw.commons.modifications.ModifierSequenceDao;
import fr.free.nrw.commons.modifications.TemplateRemoveModifier; import fr.free.nrw.commons.modifications.TemplateRemoveModifier;
import fr.free.nrw.commons.mwapi.EventLog;
import fr.free.nrw.commons.utils.ImageUtils;
import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi;
import timber.log.Timber; import timber.log.Timber;
@ -61,10 +67,10 @@ import static fr.free.nrw.commons.upload.ExistingFileAsync.Result.NO_DUPLICATE;
* Activity for the title/desc screen after image is selected. Also starts processing image * Activity for the title/desc screen after image is selected. Also starts processing image
* GPS coordinates or user location (if enabled in Settings) for category suggestions. * GPS coordinates or user location (if enabled in Settings) for category suggestions.
*/ */
public class ShareActivity public class ShareActivity
extends AuthenticatedActivity extends AuthenticatedActivity
implements SingleUploadFragment.OnUploadActionInitiated, implements SingleUploadFragment.OnUploadActionInitiated,
OnCategoriesSaveHandler { OnCategoriesSaveHandler,SimilarImageDialogFragment.onResponse {
private static final int REQUEST_PERM_ON_CREATE_STORAGE = 1; private static final int REQUEST_PERM_ON_CREATE_STORAGE = 1;
private static final int REQUEST_PERM_ON_CREATE_LOCATION = 2; private static final int REQUEST_PERM_ON_CREATE_LOCATION = 2;
@ -72,12 +78,19 @@ public class ShareActivity
private static final int REQUEST_PERM_ON_SUBMIT_STORAGE = 4; private static final int REQUEST_PERM_ON_SUBMIT_STORAGE = 4;
private CategorizationFragment categorizationFragment; private CategorizationFragment categorizationFragment;
@Inject MediaWikiApi mwApi; @Inject
@Inject CacheController cacheController; MediaWikiApi mwApi;
@Inject SessionManager sessionManager; @Inject
@Inject UploadController uploadController; CacheController cacheController;
@Inject ModifierSequenceDao modifierSequenceDao; @Inject
@Inject @Named("default_preferences") SharedPreferences prefs; SessionManager sessionManager;
@Inject
UploadController uploadController;
@Inject
ModifierSequenceDao modifierSequenceDao;
@Inject
@Named("default_preferences")
SharedPreferences prefs;
private String source; private String source;
private String mimeType; private String mimeType;
@ -89,6 +102,7 @@ public class ShareActivity
private boolean cacheFound; private boolean cacheFound;
private GPSExtractor imageObj; private GPSExtractor imageObj;
private GPSExtractor tempImageObj;
private String decimalCoords; private String decimalCoords;
private boolean useNewPermissions = false; private boolean useNewPermissions = false;
@ -99,7 +113,7 @@ public class ShareActivity
private String description; private String description;
private Snackbar snackbar; private Snackbar snackbar;
private boolean duplicateCheckPassed = false; private boolean duplicateCheckPassed = false;
private boolean haveCheckedForOtherImages = false;
/** /**
* Called when user taps the submit button. * Called when user taps the submit button.
*/ */
@ -216,7 +230,7 @@ public class ShareActivity
//Receive intent from ContributionController.java when user selects picture to upload //Receive intent from ContributionController.java when user selects picture to upload
Intent intent = getIntent(); Intent intent = getIntent();
if (intent.getAction().equals(Intent.ACTION_SEND)) { if (Intent.ACTION_SEND.equals(intent.getAction())) {
mediaUri = intent.getParcelableExtra(Intent.EXTRA_STREAM); mediaUri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (intent.hasExtra(UploadService.EXTRA_SOURCE)) { if (intent.hasExtra(UploadService.EXTRA_SOURCE)) {
source = intent.getStringExtra(UploadService.EXTRA_SOURCE); source = intent.getStringExtra(UploadService.EXTRA_SOURCE);
@ -278,7 +292,7 @@ public class ShareActivity
REQUEST_PERM_ON_CREATE_LOCATION); REQUEST_PERM_ON_CREATE_LOCATION);
} }
} }
performPreuploadProcessingOfFile(); performPreUploadProcessingOfFile();
SingleUploadFragment shareView = (SingleUploadFragment) getSupportFragmentManager().findFragmentByTag("shareView"); SingleUploadFragment shareView = (SingleUploadFragment) getSupportFragmentManager().findFragmentByTag("shareView");
@ -302,7 +316,7 @@ public class ShareActivity
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
backgroundImageView.setImageURI(mediaUri); backgroundImageView.setImageURI(mediaUri);
storagePermitted = true; storagePermitted = true;
performPreuploadProcessingOfFile(); performPreUploadProcessingOfFile();
} }
return; return;
} }
@ -310,7 +324,7 @@ public class ShareActivity
if (grantResults.length >= 1 if (grantResults.length >= 1
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationPermitted = true; locationPermitted = true;
performPreuploadProcessingOfFile(); performPreUploadProcessingOfFile();
} }
return; return;
} }
@ -319,12 +333,12 @@ public class ShareActivity
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
backgroundImageView.setImageURI(mediaUri); backgroundImageView.setImageURI(mediaUri);
storagePermitted = true; storagePermitted = true;
performPreuploadProcessingOfFile(); performPreUploadProcessingOfFile();
} }
if (grantResults.length >= 2 if (grantResults.length >= 2
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) { && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
locationPermitted = true; locationPermitted = true;
performPreuploadProcessingOfFile(); performPreUploadProcessingOfFile();
} }
return; return;
} }
@ -335,7 +349,7 @@ public class ShareActivity
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) { && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//It is OK to call this at both (1) and (4) because if perm had been granted at //It is OK to call this at both (1) and (4) because if perm had been granted at
//snackbar, user should not be prompted at submit button //snackbar, user should not be prompted at submit button
performPreuploadProcessingOfFile(); performPreUploadProcessingOfFile();
//Uploading only begins if storage permission granted from arrow icon //Uploading only begins if storage permission granted from arrow icon
uploadBegins(); uploadBegins();
@ -346,7 +360,7 @@ public class ShareActivity
} }
} }
private void performPreuploadProcessingOfFile() { private void performPreUploadProcessingOfFile() {
if (!useNewPermissions || storagePermitted) { if (!useNewPermissions || storagePermitted) {
if (!duplicateCheckPassed) { if (!duplicateCheckPassed) {
//Test SHA1 of image to see if it matches SHA1 of a file on Commons //Test SHA1 of image to see if it matches SHA1 of a file on Commons
@ -361,7 +375,17 @@ public class ShareActivity
Timber.d("%s duplicate check: %s", mediaUri.toString(), result); Timber.d("%s duplicate check: %s", mediaUri.toString(), result);
duplicateCheckPassed = (result == DUPLICATE_PROCEED duplicateCheckPassed = (result == DUPLICATE_PROCEED
|| result == NO_DUPLICATE); || result == NO_DUPLICATE);
}, mwApi); /*
TODO: 16/9/17 should we run DetectUnwantedPicturesAsync if DUPLICATE_PROCEED is returned? Since that means
we are processing images that are already on server???...
*/
if (duplicateCheckPassed) {
//image can be uploaded, so now check if its a useless picture or not
performUnwantedPictureDetectionProcess();
}
},mwApi);
fileAsyncTask.execute(); fileAsyncTask.execute();
} catch (IOException e) { } catch (IOException e) {
Timber.d(e, "IO Exception: "); Timber.d(e, "IO Exception: ");
@ -375,6 +399,37 @@ public class ShareActivity
} }
} }
private void performUnwantedPictureDetectionProcess() {
String imageMediaFilePath = FileUtils.getPath(this,mediaUri);
DetectUnwantedPicturesAsync detectUnwantedPicturesAsync = new DetectUnwantedPicturesAsync(imageMediaFilePath, result -> {
if (result != ImageUtils.Result.IMAGE_OK) {
//show appropriate error message
String errorMessage = result == ImageUtils.Result.IMAGE_DARK ? getString(R.string.upload_image_too_dark) : getString(R.string.upload_image_blurry);
AlertDialog.Builder errorDialogBuilder = new AlertDialog.Builder(this);
errorDialogBuilder.setMessage(errorMessage);
errorDialogBuilder.setTitle(getString(R.string.warning));
errorDialogBuilder.setPositiveButton(getString(R.string.no), (dialogInterface, i) -> {
//user does not wish to upload the picture, take them back to ContributionsActivity
Intent intent = new Intent(ShareActivity.this, ContributionsActivity.class);
dialogInterface.dismiss();
startActivity(intent);
});
errorDialogBuilder.setNegativeButton(getString(R.string.yes), (dialogInterface, i) -> {
//user wishes to go ahead with the upload of this picture, just dismiss this dialog
dialogInterface.dismiss();
});
AlertDialog errorDialog = errorDialogBuilder.create();
if (!isFinishing()) {
errorDialog.show();
}
}
});
detectUnwantedPicturesAsync.execute();
}
private Snackbar requestPermissionUsingSnackBar(String rationale, private Snackbar requestPermissionUsingSnackBar(String rationale,
final String[] perms, final String[] perms,
final int code) { final int code) {
@ -452,13 +507,93 @@ public class ShareActivity
if (imageObj != null) { if (imageObj != null) {
// Gets image coords from exif data or user location // Gets image coords from exif data or user location
decimalCoords = imageObj.getCoords(gpsEnabled); decimalCoords = imageObj.getCoords(gpsEnabled);
useImageCoords(); if(decimalCoords==null || !imageObj.imageCoordsExists){
// Check if the location is from GPS or EXIF
// Find other photos taken around the same time which has gps coordinates
Timber.d("EXIF:false");
Timber.d("EXIF call"+(imageObj==tempImageObj));
if(!haveCheckedForOtherImages)
findOtherImages(gpsEnabled);// Do not do repeat the process
}
else {
// As the selected image has GPS data in EXIF go ahead with the same.
useImageCoords();
}
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Timber.w("File not found: " + mediaUri, e); Timber.w("File not found: " + mediaUri, e);
} }
} }
private void findOtherImages(boolean gpsEnabled) {
Timber.d("filePath"+getPathOfMediaOrCopy());
String filePath = getPathOfMediaOrCopy();
long timeOfCreation = new File(filePath).lastModified();//Time when the original image was created
File folder = new File(filePath.substring(0,filePath.lastIndexOf('/')));
File[] files = folder.listFiles();
Timber.d("folderTime Number:"+files.length);
for(File file : files){
if(file.lastModified()-timeOfCreation<=(120*1000) && file.lastModified()-timeOfCreation>=-(120*1000)){
//Make sure the photos were taken within 20seconds
Timber.d("fild date:"+file.lastModified()+ " time of creation"+timeOfCreation);
tempImageObj = null;//Temporary GPSExtractor to extract coords from these photos
ParcelFileDescriptor descriptor
= null;
try {
descriptor = getContentResolver().openFileDescriptor(Uri.parse(file.getAbsolutePath()), "r");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
if (descriptor != null) {
tempImageObj = new GPSExtractor(descriptor.getFileDescriptor(),this, prefs);
}
} else {
if (filePath != null) {
tempImageObj = new GPSExtractor(file.getAbsolutePath(), this, prefs);
}
}
if(tempImageObj!=null){
Timber.d("not null fild EXIF"+tempImageObj.imageCoordsExists +" coords"+tempImageObj.getCoords(gpsEnabled));
if(tempImageObj.getCoords(gpsEnabled)!=null && tempImageObj.imageCoordsExists){
// Current image has gps coordinates and it's not current gps locaiton
Timber.d("This fild has image coords:"+ file.getAbsolutePath());
// Create a dialog fragment for the suggestion
FragmentManager fragmentManager = getSupportFragmentManager();
SimilarImageDialogFragment newFragment = new SimilarImageDialogFragment();
Bundle args = new Bundle();
args.putString("originalImagePath",filePath);
args.putString("possibleImagePath",file.getAbsolutePath());
newFragment.setArguments(args);
newFragment.show(fragmentManager, "dialog");
break;
}
}
}
}
haveCheckedForOtherImages = true; //Finished checking for other images
return;
}
@Override
public void onPostiveResponse() {
imageObj = tempImageObj;
decimalCoords = imageObj.getCoords(false);// Not necessary to use gps as image already ha EXIF data
Timber.d("EXIF from tempImageObj");
useImageCoords();
}
@Override
public void onNegativeResponse() {
Timber.d("EXIF from imageObj");
useImageCoords();
}
/** /**
* Initiates retrieval of image coordinates or user coordinates, and caching of coordinates. * Initiates retrieval of image coordinates or user coordinates, and caching of coordinates.
* Then initiates the calls to MediaWiki API through an instance of MwVolleyApi. * Then initiates the calls to MediaWiki API through an instance of MwVolleyApi.
@ -466,6 +601,7 @@ public class ShareActivity
public void useImageCoords() { public void useImageCoords() {
if (decimalCoords != null) { if (decimalCoords != null) {
Timber.d("Decimal coords of image: %s", decimalCoords); Timber.d("Decimal coords of image: %s", decimalCoords);
Timber.d("is EXIF data present:"+imageObj.imageCoordsExists+" from findOther image:"+(imageObj==tempImageObj));
// Only set cache for this point if image has coords // Only set cache for this point if image has coords
if (imageObj.imageCoordsExists) { if (imageObj.imageCoordsExists) {
@ -489,7 +625,10 @@ public class ShareActivity
Timber.d("Cache found, setting categoryList in MwVolleyApi to %s", displayCatList); Timber.d("Cache found, setting categoryList in MwVolleyApi to %s", displayCatList);
MwVolleyApi.setGpsCat(displayCatList); MwVolleyApi.setGpsCat(displayCatList);
} }
}else{
Timber.d("EXIF: no coords");
} }
} }
@Override @Override

View file

@ -0,0 +1,112 @@
package fr.free.nrw.commons.upload;
import android.app.Dialog;
import android.content.DialogInterface;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.imagepipeline.listener.RequestListener;
import com.facebook.imagepipeline.listener.RequestLoggingListener;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import fr.free.nrw.commons.R;
/**
* Created by harisanker on 14/2/18.
*/
public class SimilarImageDialogFragment extends DialogFragment {
SimpleDraweeView originalImage;
SimpleDraweeView possibleImage;
Button positiveButton;
Button negativeButton;
onResponse mOnResponse;//Implemented interface from shareActivity
Boolean gotResponse = false;
public SimilarImageDialogFragment() {
}
public interface onResponse{
public void onPostiveResponse();
public void onNegativeResponse();
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_similar_image_dialog, container, false);
Set<RequestListener> requestListeners = new HashSet<>();
requestListeners.add(new RequestLoggingListener());
originalImage =(SimpleDraweeView) view.findViewById(R.id.orginalImage);
possibleImage =(SimpleDraweeView) view.findViewById(R.id.possibleImage);
positiveButton = (Button) view.findViewById(R.id.postive_button);
negativeButton = (Button) view.findViewById(R.id.negative_button);
originalImage.setHierarchy(GenericDraweeHierarchyBuilder
.newInstance(getResources())
.setPlaceholderImage(VectorDrawableCompat.create(getResources(),
R.drawable.ic_image_black_24dp,getContext().getTheme()))
.setFailureImage(VectorDrawableCompat.create(getResources(),
R.drawable.ic_error_outline_black_24dp, getContext().getTheme()))
.build());
possibleImage.setHierarchy(GenericDraweeHierarchyBuilder
.newInstance(getResources())
.setPlaceholderImage(VectorDrawableCompat.create(getResources(),
R.drawable.ic_image_black_24dp,getContext().getTheme()))
.setFailureImage(VectorDrawableCompat.create(getResources(),
R.drawable.ic_error_outline_black_24dp, getContext().getTheme()))
.build());
originalImage.setImageURI(Uri.fromFile(new File(getArguments().getString("originalImagePath"))));
possibleImage.setImageURI(Uri.fromFile(new File(getArguments().getString("possibleImagePath"))));
negativeButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnResponse.onNegativeResponse();
gotResponse = true;
dismiss();
}
});
positiveButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mOnResponse.onPostiveResponse();
gotResponse = true;
dismiss();
}
});
return view;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mOnResponse = (onResponse) getActivity();//Interface Implementation
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = super.onCreateDialog(savedInstanceState);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
return dialog;
}
@Override
public void onDismiss(DialogInterface dialog) {
// I user dismisses dialog by pressing outside the dialog.
if(!gotResponse)
mOnResponse.onNegativeResponse();
super.onDismiss(dialog);
}
}

View file

@ -6,6 +6,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor; import android.database.Cursor;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -49,7 +50,7 @@ public class UploadController {
private ServiceConnection uploadServiceConnection = new ServiceConnection() { private ServiceConnection uploadServiceConnection = new ServiceConnection() {
@Override @Override
public void onServiceConnected(ComponentName componentName, IBinder binder) { public void onServiceConnected(ComponentName componentName, IBinder binder) {
uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder)binder).getService(); uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder) binder).getService();
isUploadServiceConnected = true; isUploadServiceConnected = true;
} }
@ -81,13 +82,14 @@ public class UploadController {
/** /**
* Starts a new upload task. * Starts a new upload task.
* @param title the title of the contribution *
* @param mediaUri the media URI of the contribution * @param title the title of the contribution
* @param description the description of the contribution * @param mediaUri the media URI of the contribution
* @param mimeType the MIME type of the contribution * @param description the description of the contribution
* @param source the source of the contribution * @param mimeType the MIME type of the contribution
* @param source the source of the contribution
* @param decimalCoords the coordinates in decimal. (e.g. "37.51136|-77.602615") * @param decimalCoords the coordinates in decimal. (e.g. "37.51136|-77.602615")
* @param onComplete the progress tracker * @param onComplete the progress tracker
*/ */
public void startUpload(String title, Uri mediaUri, String description, String mimeType, String source, String decimalCoords, ContributionUploadProgress onComplete) { public void startUpload(String title, Uri mediaUri, String description, String mimeType, String source, String decimalCoords, ContributionUploadProgress onComplete) {
Contribution contribution; Contribution contribution;
@ -106,8 +108,9 @@ public class UploadController {
/** /**
* Starts a new upload task. * Starts a new upload task.
*
* @param contribution the contribution object * @param contribution the contribution object
* @param onComplete the progress tracker * @param onComplete the progress tracker
*/ */
public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) { public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) {
//Set creator, desc, and license //Set creator, desc, and license
@ -134,15 +137,17 @@ public class UploadController {
ContentResolver contentResolver = context.getContentResolver(); ContentResolver contentResolver = context.getContentResolver();
try { try {
if (contribution.getDataLength() <= 0) { if (contribution.getDataLength() <= 0) {
length = contentResolver AssetFileDescriptor assetFileDescriptor = contentResolver
.openAssetFileDescriptor(contribution.getLocalUri(), "r") .openAssetFileDescriptor(contribution.getLocalUri(), "r");
.getLength(); if (assetFileDescriptor != null) {
if (length == -1) { length = assetFileDescriptor.getLength();
// Let us find out the long way! if (length == -1) {
length = countBytes(contentResolver // Let us find out the long way!
.openInputStream(contribution.getLocalUri())); length = countBytes(contentResolver
.openInputStream(contribution.getLocalUri()));
}
contribution.setDataLength(length);
} }
contribution.setDataLength(length);
} }
} catch (IOException e) { } catch (IOException e) {
Timber.e(e, "IO Exception: "); Timber.e(e, "IO Exception: ");
@ -152,7 +157,7 @@ public class UploadController {
Timber.e(e, "Security Exception: "); Timber.e(e, "Security Exception: ");
} }
String mimeType = (String)contribution.getTag("mimeType"); String mimeType = (String) contribution.getTag("mimeType");
Boolean imagePrefix = false; Boolean imagePrefix = false;
if (mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) { if (mimeType == null || TextUtils.isEmpty(mimeType) || mimeType.endsWith("*")) {
@ -199,6 +204,7 @@ public class UploadController {
/** /**
* Counts the number of bytes in {@code stream}. * Counts the number of bytes in {@code stream}.
*
* @param stream the stream * @param stream the stream
* @return the number of bytes in {@code stream} * @return the number of bytes in {@code stream}
* @throws IOException if an I/O error occurs * @throws IOException if an I/O error occurs

View file

@ -161,7 +161,7 @@ public class UploadService extends HandlerService<Contribution> {
@Override @Override
public int onStartCommand(Intent intent, int flags, int startId) { public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(ACTION_START_SERVICE) && freshStart) { if (ACTION_START_SERVICE.equals(intent.getAction()) && freshStart) {
ContentValues failedValues = new ContentValues(); ContentValues failedValues = new ContentValues();
failedValues.put(ContributionDao.Table.COLUMN_STATE, Contribution.STATE_FAILED); failedValues.put(ContributionDao.Table.COLUMN_STATE, Contribution.STATE_FAILED);

View file

@ -11,7 +11,6 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import fr.free.nrw.commons.CommonsApplication;
import timber.log.Timber; import timber.log.Timber;
public class FileUtils { public class FileUtils {
@ -32,7 +31,7 @@ public class FileUtils {
reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line; String line;
while ((line = reader.readLine()) != null) { while ((line = reader.readLine()) != null) {
buffer.append(line + "\n"); buffer.append(line).append("\n");
} }
} finally { } finally {
if (reader != null) { if (reader != null) {

View file

@ -0,0 +1,135 @@
package fr.free.nrw.commons.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Color;
import android.graphics.Rect;
import timber.log.Timber;
/**
* Created by bluesir9 on 3/10/17.
*/
public class ImageUtils {
//atleast 50% of the image in question should be considered dark for the entire image to be dark
private static final double MINIMUM_DARKNESS_FACTOR = 0.50;
//atleast 50% of the image in question should be considered blurry for the entire image to be blurry
private static final double MINIMUM_BLURRYNESS_FACTOR = 0.50;
private static final int LAPLACIAN_VARIANCE_THRESHOLD = 70;
public enum Result {
IMAGE_DARK,
IMAGE_OK
}
/**
* BitmapRegionDecoder allows us to process a large bitmap by breaking it down into smaller rectangles. The rectangles
* are obtained by setting an initial width, height and start position of the rectangle as a factor of the width and
* height of the original bitmap and then manipulating the width, height and position to loop over the entire original
* bitmap. Each individual rectangle is independently processed to check if its too dark. Based on
* the factor of "bright enough" individual rectangles amongst the total rectangles into which the image
* was divided, we will declare the image as wanted/unwanted
*
* @param bitmapRegionDecoder BitmapRegionDecoder for the image we wish to process
* @return Result.IMAGE_OK if image is neither dark nor blurry or if the input bitmapRegionDecoder provided is null
* Result.IMAGE_DARK if image is too dark
*/
public static Result checkIfImageIsTooDark(BitmapRegionDecoder bitmapRegionDecoder) {
if (bitmapRegionDecoder == null) {
Timber.e("Expected bitmapRegionDecoder was null");
return Result.IMAGE_OK;
}
int loadImageHeight = bitmapRegionDecoder.getHeight();
int loadImageWidth = bitmapRegionDecoder.getWidth();
int checkImageTopPosition = 0;
int checkImageBottomPosition = loadImageHeight / 10;
int checkImageLeftPosition = 0;
int checkImageRightPosition = loadImageWidth / 10;
int totalDividedRectangles = 0;
int numberOfDarkRectangles = 0;
while ((checkImageRightPosition <= loadImageWidth) && (checkImageLeftPosition < checkImageRightPosition)) {
while ((checkImageBottomPosition <= loadImageHeight) && (checkImageTopPosition < checkImageBottomPosition)) {
Timber.d("left: " + checkImageLeftPosition + " right: " + checkImageRightPosition + " top: " + checkImageTopPosition + " bottom: " + checkImageBottomPosition);
Rect rect = new Rect(checkImageLeftPosition,checkImageTopPosition,checkImageRightPosition,checkImageBottomPosition);
totalDividedRectangles++;
Bitmap processBitmap = bitmapRegionDecoder.decodeRegion(rect,null);
if (checkIfImageIsDark(processBitmap)) {
numberOfDarkRectangles++;
}
checkImageTopPosition = checkImageBottomPosition;
checkImageBottomPosition += (checkImageBottomPosition < (loadImageHeight - checkImageBottomPosition)) ? checkImageBottomPosition : (loadImageHeight - checkImageBottomPosition);
}
checkImageTopPosition = 0; //reset to start
checkImageBottomPosition = loadImageHeight / 10; //reset to start
checkImageLeftPosition = checkImageRightPosition;
checkImageRightPosition += (checkImageRightPosition < (loadImageWidth - checkImageRightPosition)) ? checkImageRightPosition : (loadImageWidth - checkImageRightPosition);
}
Timber.d("dark rectangles count = " + numberOfDarkRectangles + ", total rectangles count = " + totalDividedRectangles);
if (numberOfDarkRectangles > totalDividedRectangles * MINIMUM_DARKNESS_FACTOR) {
return Result.IMAGE_DARK;
}
return Result.IMAGE_OK;
}
/**
* Pulls the pixels into an array and then runs through it while checking the brightness of each pixel.
* The calculation of brightness of each pixel is done by extracting the RGB constituents of the pixel
* and then applying the formula to calculate its "Luminance". If this brightness value is less than
* 50 then the pixel is considered to be dark. Based on the MINIMUM_DARKNESS_FACTOR if enough pixels
* are dark then the entire bitmap is considered to be dark.
*
* <p>For more information on this brightness/darkness calculation technique refer the accepted answer
* on this -> https://stackoverflow.com/questions/35914461/how-to-detect-dark-photos-in-android/35914745
* SO question and follow the trail.
*
* @param bitmap The bitmap that needs to be checked.
* @return true if bitmap is dark or null, false if bitmap is bright
*/
private static boolean checkIfImageIsDark(Bitmap bitmap) {
if (bitmap == null) {
Timber.e("Expected bitmap was null");
return true;
}
int bitmapWidth = bitmap.getWidth();
int bitmapHeight = bitmap.getHeight();
int allPixelsCount = bitmapWidth * bitmapHeight;
int[] bitmapPixels = new int[allPixelsCount];
bitmap.getPixels(bitmapPixels,0,bitmapWidth,0,0,bitmapWidth,bitmapHeight);
boolean isImageDark = false;
int darkPixelsCount = 0;
for (int pixel : bitmapPixels) {
int r = Color.red(pixel);
int g = Color.green(pixel);
int b = Color.blue(pixel);
int brightness = (int) (0.2126 * r + 0.7152 * g + 0.0722 * b);
if (brightness < 50) {
//pixel is dark
darkPixelsCount++;
if (darkPixelsCount > allPixelsCount * MINIMUM_DARKNESS_FACTOR) {
isImageDark = true;
break;
}
}
}
return isImageDark;
}
}

View file

@ -7,11 +7,6 @@ import android.widget.Toast;
public class ViewUtil { public class ViewUtil {
public static void showLongToast(final Context context, @StringRes final int stringResId) { public static void showLongToast(final Context context, @StringRes final int stringResId) {
ExecutorUtils.uiExecutor().execute(new Runnable() { ExecutorUtils.uiExecutor().execute(() -> Toast.makeText(context, context.getString(stringResId), Toast.LENGTH_LONG).show());
@Override
public void run() {
Toast.makeText(context, context.getString(stringResId), Toast.LENGTH_LONG).show();
}
});
} }
} }

View file

@ -13,12 +13,12 @@
<android.support.v7.widget.CardView <android.support.v7.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_gap"
android:layout_marginBottom="@dimen/standard_gap" android:layout_marginBottom="@dimen/standard_gap"
android:layout_marginEnd="@dimen/standard_gap" android:layout_marginEnd="@dimen/standard_gap"
android:layout_marginLeft="@dimen/standard_gap" android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap" android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap" android:layout_marginStart="@dimen/standard_gap"
android:layout_marginTop="@dimen/large_gap"
app:cardCornerRadius="4dp" app:cardCornerRadius="4dp"
app:cardElevation="4dp"> app:cardElevation="4dp">
@ -40,11 +40,26 @@
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="@dimen/heading_text_size" /> android:textSize="@dimen/heading_text_size" />
<TextView
android:id="@+id/login_credentials"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginEnd="@dimen/standard_gap"
android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap"
android:paddingBottom="@dimen/standard_gap"
android:paddingTop="@dimen/small_gap"
android:textAlignment="center"
android:textColor="@color/secondaryDarkColor"
tools:text="@string/login_credential" />
<FrameLayout <FrameLayout
android:id="@+id/error_message_container" android:id="@+id/error_message_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/title" android:layout_below="@id/login_credentials"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
@ -56,6 +71,7 @@
android:layout_marginLeft="@dimen/standard_gap" android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap" android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap" android:layout_marginStart="@dimen/standard_gap"
android:gravity="center"
android:paddingBottom="@dimen/small_gap" android:paddingBottom="@dimen/small_gap"
android:paddingTop="@dimen/small_gap" android:paddingTop="@dimen/small_gap"
android:textColor="@color/secondaryDarkColor" android:textColor="@color/secondaryDarkColor"
@ -149,8 +165,8 @@
<Button <Button
android:id="@+id/signupButton" android:id="@+id/signupButton"
android:layout_width="0dp"
style="@style/Widget.AppCompat.Button.Borderless.Colored" style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginEnd="@dimen/small_gap" android:layout_marginEnd="@dimen/small_gap"
@ -160,8 +176,8 @@
<Button <Button
android:id="@+id/loginButton" android:id="@+id/loginButton"
android:layout_width="0dp"
style="@style/Widget.AppCompat.Button.Colored" style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/small_gap" android:layout_marginLeft="@dimen/small_gap"
android:layout_marginStart="@dimen/small_gap" android:layout_marginStart="@dimen/small_gap"
@ -174,13 +190,13 @@
<fr.free.nrw.commons.ui.widget.HtmlTextView <fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_privacy_policy" android:id="@+id/about_privacy_policy"
style="?android:textAppearanceSmall" style="?android:textAppearanceSmall"
android:layout_below="@id/buttonFrame"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/standard_gap" android:layout_below="@id/buttonFrame"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:text="@string/about_privacy_policy" android:layout_marginBottom="@dimen/standard_gap"
android:layout_centerHorizontal="true"/> android:text="@string/about_privacy_policy" />
</RelativeLayout> </RelativeLayout>
</android.support.v7.widget.CardView> </android.support.v7.widget.CardView>
@ -188,19 +204,19 @@
<android.support.v7.widget.AppCompatImageView <android.support.v7.widget.AppCompatImageView
android:layout_width="64dp" android:layout_width="64dp"
android:layout_height="64dp" android:layout_height="64dp"
android:elevation="8dp"
tools:ignore="UnusedAttribute"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
app:srcCompat="@drawable/blue_rinse_circle" /> android:elevation="8dp"
app:srcCompat="@drawable/blue_rinse_circle"
tools:ignore="UnusedAttribute" />
<android.support.v7.widget.AppCompatImageView <android.support.v7.widget.AppCompatImageView
android:layout_width="42dp" android:layout_width="42dp"
tools:ignore="UnusedAttribute"
android:layout_height="42dp" android:layout_height="42dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:elevation="8dp" android:elevation="8dp"
app:srcCompat="@drawable/commons_logo_large" /> app:srcCompat="@drawable/commons_logo_large"
tools:ignore="UnusedAttribute" />
</FrameLayout> </FrameLayout>

View file

@ -73,16 +73,91 @@
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:textColor="@android:color/white"/> android:textColor="@android:color/white"/>
<TextView <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:paddingTop="@dimen/standard_gap"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxWidth="240dp" android:maxWidth="240dp"
android:text="@string/tutorial_2_subtext" android:text="@string/tutorial_2_subtext_1"
android:layout_gravity="center" android:layout_gravity="center"
android:textAlignment="textStart" android:textAlignment="textStart"
android:paddingTop="@dimen/standard_gap" android:paddingTop="@dimen/standard_gap"
android:gravity="start" android:gravity="start"
android:textColor="@android:color/white" android:textColor="@android:color/white"
/> />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_2_subtext_2"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:layout_gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_2_subtext_3"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -55,16 +55,90 @@
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:textColor="@android:color/white"/> android:textColor="@android:color/white"/>
<TextView <LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:paddingTop="@dimen/standard_gap"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_3_subtext_1"
android:layout_gravity="center"
android:textAlignment="textStart"
android:paddingTop="@dimen/standard_gap"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxWidth="240dp" android:maxWidth="240dp"
android:text="@string/tutorial_3_subtext"
android:layout_gravity="center" android:layout_gravity="center"
android:textAlignment="textStart" android:orientation="horizontal">
android:paddingTop="@dimen/standard_gap"
android:gravity="start" <TextView
android:textColor="@android:color/white" android:layout_width="wrap_content"
/> android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_3_subtext_2"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_3_subtext_3"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -38,16 +38,89 @@
android:gravity="center_horizontal" android:gravity="center_horizontal"
android:textColor="@android:color/white"/> android:textColor="@android:color/white"/>
<TextView <LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxWidth="240dp" android:maxWidth="240dp"
android:text="@string/tutorial_4_subtext" android:orientation="horizontal">
android:layout_gravity="center"
android:textAlignment="textStart" <TextView
android:paddingTop="@dimen/standard_gap" android:layout_width="wrap_content"
android:gravity="start" android:layout_height="wrap_content"
android:textColor="@android:color/white" android:text="@string/bullet"
/> android:paddingRight="4dp"
android:textSize="16sp"
android:paddingTop="@dimen/standard_gap"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_4_subtext_1"
android:layout_gravity="center"
android:textAlignment="textStart"
android:paddingTop="@dimen/standard_gap"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_4_subtext_2"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_4_subtext_3"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -13,12 +13,12 @@
<android.support.v7.widget.CardView <android.support.v7.widget.CardView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_gap"
android:layout_marginBottom="@dimen/standard_gap" android:layout_marginBottom="@dimen/standard_gap"
android:layout_marginEnd="@dimen/standard_gap" android:layout_marginEnd="@dimen/standard_gap"
android:layout_marginLeft="@dimen/standard_gap" android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap" android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap" android:layout_marginStart="@dimen/standard_gap"
android:layout_marginTop="@dimen/large_gap"
app:cardCornerRadius="4dp" app:cardCornerRadius="4dp"
app:cardElevation="4dp"> app:cardElevation="4dp">
@ -40,6 +40,21 @@
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="@dimen/heading_text_size" /> android:textSize="@dimen/heading_text_size" />
<TextView
android:id="@+id/login_credentials"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginEnd="@dimen/standard_gap"
android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap"
android:paddingBottom="@dimen/small_gap"
android:paddingTop="@dimen/small_gap"
android:textAlignment="center"
android:textColor="@color/secondaryDarkColor"
tools:text="@string/login_credential" />
<FrameLayout <FrameLayout
android:id="@+id/error_message_container" android:id="@+id/error_message_container"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -56,6 +71,7 @@
android:layout_marginLeft="@dimen/standard_gap" android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap" android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap" android:layout_marginStart="@dimen/standard_gap"
android:gravity="center"
android:paddingBottom="@dimen/small_gap" android:paddingBottom="@dimen/small_gap"
android:paddingTop="@dimen/small_gap" android:paddingTop="@dimen/small_gap"
android:textColor="@color/secondaryDarkColor" android:textColor="@color/secondaryDarkColor"
@ -149,8 +165,8 @@
<Button <Button
android:id="@+id/signupButton" android:id="@+id/signupButton"
android:layout_width="0dp"
style="@style/Widget.AppCompat.Button.Borderless.Colored" style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginEnd="@dimen/small_gap" android:layout_marginEnd="@dimen/small_gap"
@ -160,8 +176,8 @@
<Button <Button
android:id="@+id/loginButton" android:id="@+id/loginButton"
android:layout_width="0dp"
style="@style/Widget.AppCompat.Button.Colored" style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/small_gap" android:layout_marginLeft="@dimen/small_gap"
android:layout_marginStart="@dimen/small_gap" android:layout_marginStart="@dimen/small_gap"
@ -174,13 +190,13 @@
<fr.free.nrw.commons.ui.widget.HtmlTextView <fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_privacy_policy" android:id="@+id/about_privacy_policy"
style="?android:textAppearanceSmall" style="?android:textAppearanceSmall"
android:layout_below="@id/buttonFrame"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/standard_gap" android:layout_below="@id/buttonFrame"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:text="@string/about_privacy_policy" android:layout_marginBottom="@dimen/standard_gap"
android:layout_centerHorizontal="true"/> android:text="@string/about_privacy_policy" />
</RelativeLayout> </RelativeLayout>
</android.support.v7.widget.CardView> </android.support.v7.widget.CardView>
@ -188,8 +204,8 @@
<android.support.v7.widget.AppCompatImageView <android.support.v7.widget.AppCompatImageView
android:layout_width="64dp" android:layout_width="64dp"
android:layout_height="64dp" android:layout_height="64dp"
android:elevation="8dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:elevation="8dp"
app:srcCompat="@drawable/blue_rinse_circle" app:srcCompat="@drawable/blue_rinse_circle"
tools:ignore="UnusedAttribute" /> tools:ignore="UnusedAttribute" />
@ -198,9 +214,9 @@
android:layout_height="42dp" android:layout_height="42dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
tools:ignore="UnusedAttribute"
android:elevation="8dp" android:elevation="8dp"
app:srcCompat="@drawable/commons_logo_large" /> app:srcCompat="@drawable/commons_logo_large"
tools:ignore="UnusedAttribute" />
</FrameLayout> </FrameLayout>

View file

@ -5,134 +5,135 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<RelativeLayout <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content">
<include <RelativeLayout
android:id="@+id/toolbar"
layout="@layout/toolbar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content">
<LinearLayout <include
android:layout_width="match_parent" android:id="@+id/toolbar"
android:layout_height="match_parent" layout="@layout/toolbar"
android:layout_below="@id/toolbar" android:layout_width="match_parent"
android:layout_marginLeft="@dimen/activity_margin_horizontal"
android:layout_marginStart="@dimen/activity_margin_horizontal"
android:layout_marginRight="@dimen/activity_margin_horizontal"
android:layout_marginEnd="@dimen/activity_margin_horizontal"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"
android:contentDescription= "@string/commons_logo"
/>
<TextView
style="?android:textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name" />
<TextView
android:id="@+id/about_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_license"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/standard_gap"
android:gravity="center"
android:text="@string/about_license" />
<fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_improve"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/small_gap"
android:gravity="center"
android:text="@string/about_improve" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:gravity="center" android:layout_below="@id/toolbar"
android:orientation="horizontal"
android:layout_marginLeft="@dimen/activity_margin_horizontal"
android:layout_marginStart="@dimen/activity_margin_horizontal"
android:layout_marginRight="@dimen/activity_margin_horizontal"
android:layout_marginTop="@dimen/activity_margin_horizontal"
android:layout_marginEnd="@dimen/activity_margin_horizontal" android:layout_marginEnd="@dimen/activity_margin_horizontal"
> android:layout_marginLeft="@dimen/activity_margin_horizontal"
android:layout_marginRight="@dimen/activity_margin_horizontal"
android:layout_marginStart="@dimen/activity_margin_horizontal"
android:layout_marginTop="@dimen/activity_margin_vertical"
android:gravity="center"
android:orientation="vertical">
<ImageView <ImageView
android:id="@+id/website_launch_icon" android:layout_width="wrap_content"
android:layout_width="@dimen/overflow_icon_dimen" android:layout_height="wrap_content"
android:layout_height="@dimen/overflow_icon_dimen" android:contentDescription="@string/commons_logo"
app:srcCompat="@drawable/ic_action_website" android:src="@drawable/ic_launcher" />
android:contentDescription= "@string/commons_website"
android:layout_margin="@dimen/activity_margin_horizontal"
/>
<ImageView <TextView
android:id="@+id/facebook_launch_icon" style="?android:textAppearanceLarge"
android:layout_width="@dimen/overflow_icon_dimen" android:layout_width="wrap_content"
android:layout_height="@dimen/overflow_icon_dimen" android:layout_height="wrap_content"
app:srcCompat="@drawable/ic_action_facebook" android:text="@string/app_name" />
android:contentDescription= "@string/commons_facebook"
android:layout_margin="@dimen/activity_margin_horizontal"
/>
<ImageView <TextView
android:id="@+id/github_launch_icon" android:id="@+id/about_version"
android:layout_width="@dimen/overflow_icon_dimen" android:layout_width="wrap_content"
android:layout_height="@dimen/overflow_icon_dimen" android:layout_height="wrap_content" />
app:srcCompat="@drawable/ic_action_github"
android:contentDescription= "@string/commons_github" <fr.free.nrw.commons.ui.widget.HtmlTextView
android:layout_margin="@dimen/activity_margin_horizontal" android:id="@+id/about_license"
/> style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/standard_gap"
android:gravity="center"
android:text="@string/about_license" />
<fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_improve"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/small_gap"
android:gravity="center"
android:text="@string/about_improve" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/activity_margin_horizontal"
android:layout_marginLeft="@dimen/activity_margin_horizontal"
android:layout_marginRight="@dimen/activity_margin_horizontal"
android:layout_marginStart="@dimen/activity_margin_horizontal"
android:layout_marginTop="@dimen/activity_margin_horizontal"
android:gravity="center"
android:orientation="horizontal">
<ImageView
android:id="@+id/website_launch_icon"
android:layout_width="@dimen/overflow_icon_dimen"
android:layout_height="@dimen/overflow_icon_dimen"
android:layout_margin="@dimen/activity_margin_horizontal"
android:contentDescription="@string/commons_website"
app:srcCompat="@drawable/ic_action_website" />
<ImageView
android:id="@+id/facebook_launch_icon"
android:layout_width="@dimen/overflow_icon_dimen"
android:layout_height="@dimen/overflow_icon_dimen"
android:layout_margin="@dimen/activity_margin_horizontal"
android:contentDescription="@string/commons_facebook"
app:srcCompat="@drawable/ic_action_facebook" />
<ImageView
android:id="@+id/github_launch_icon"
android:layout_width="@dimen/overflow_icon_dimen"
android:layout_height="@dimen/overflow_icon_dimen"
android:layout_margin="@dimen/activity_margin_horizontal"
android:contentDescription="@string/commons_github"
app:srcCompat="@drawable/ic_action_github" />
</LinearLayout>
<fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_privacy_policy"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/standard_gap"
android:gravity="center"
android:text="@string/about_privacy_policy" />
<fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_credits"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/standard_gap"
android:gravity="center"
android:text="@string/about_credits" />
<TextView
android:id="@+id/about_uploads_to"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_gap"
android:alpha="0.2"
android:gravity="center" />
</LinearLayout> </LinearLayout>
</RelativeLayout>
<fr.free.nrw.commons.ui.widget.HtmlTextView </ScrollView>
android:id="@+id/about_privacy_policy"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/standard_gap"
android:gravity="center"
android:text="@string/about_privacy_policy" />
<fr.free.nrw.commons.ui.widget.HtmlTextView
android:id="@+id/about_credits"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/standard_gap"
android:gravity="center"
android:text="@string/about_credits" />
<TextView
android:id="@+id/about_uploads_to"
style="?android:textAppearanceSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/large_gap"
android:alpha="0.2"
android:gravity="center" />
</LinearLayout>
</RelativeLayout>
<android.support.design.widget.NavigationView <android.support.design.widget.NavigationView
android:id="@+id/navigation_view" android:id="@+id/navigation_view"
@ -140,6 +141,6 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_gravity="start" android:layout_gravity="start"
app:headerLayout="@layout/drawer_header" app:headerLayout="@layout/drawer_header"
app:menu="@menu/drawer"/> app:menu="@menu/drawer" />
</android.support.v4.widget.DrawerLayout> </android.support.v4.widget.DrawerLayout>

View file

@ -19,12 +19,16 @@
android:layout_marginRight="@dimen/standard_gap" android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap" android:layout_marginStart="@dimen/standard_gap"
android:layout_marginTop="@dimen/large_gap" android:layout_marginTop="@dimen/large_gap"
android:clickable="true"
android:focusableInTouchMode="true"
app:cardCornerRadius="4dp" app:cardCornerRadius="4dp"
app:cardElevation="4dp"> app:cardElevation="4dp">
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="true"
android:focusableInTouchMode="true"
android:gravity="center" android:gravity="center"
android:orientation="vertical"> android:orientation="vertical">
@ -40,11 +44,27 @@
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="@dimen/heading_text_size" /> android:textSize="@dimen/heading_text_size" />
<TextView
android:id="@+id/login_credentials"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/title"
android:layout_marginEnd="@dimen/standard_gap"
android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap"
android:paddingBottom="@dimen/small_gap"
android:paddingTop="@dimen/small_gap"
android:textAlignment="center"
android:textColor="@color/secondaryDarkColor"
tools:text="@string/login_credential" />
<FrameLayout <FrameLayout
android:id="@+id/error_message_container" android:id="@+id/error_message_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@id/title" android:layout_below="@id/login_credentials"
android:visibility="gone" android:visibility="gone"
tools:visibility="visible"> tools:visibility="visible">
@ -56,6 +76,7 @@
android:layout_marginLeft="@dimen/standard_gap" android:layout_marginLeft="@dimen/standard_gap"
android:layout_marginRight="@dimen/standard_gap" android:layout_marginRight="@dimen/standard_gap"
android:layout_marginStart="@dimen/standard_gap" android:layout_marginStart="@dimen/standard_gap"
android:gravity="center"
android:paddingBottom="@dimen/small_gap" android:paddingBottom="@dimen/small_gap"
android:paddingTop="@dimen/small_gap" android:paddingTop="@dimen/small_gap"
android:textColor="@color/secondaryDarkColor" android:textColor="@color/secondaryDarkColor"
@ -149,8 +170,8 @@
<Button <Button
android:id="@+id/signupButton" android:id="@+id/signupButton"
android:layout_width="0dp"
style="@style/Widget.AppCompat.Button.Borderless.Colored" style="@style/Widget.AppCompat.Button.Borderless.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginEnd="@dimen/small_gap" android:layout_marginEnd="@dimen/small_gap"
@ -160,8 +181,8 @@
<Button <Button
android:id="@+id/loginButton" android:id="@+id/loginButton"
android:layout_width="0dp"
style="@style/Widget.AppCompat.Button.Colored" style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/small_gap" android:layout_marginLeft="@dimen/small_gap"
android:layout_marginStart="@dimen/small_gap" android:layout_marginStart="@dimen/small_gap"
@ -188,19 +209,19 @@
<android.support.v7.widget.AppCompatImageView <android.support.v7.widget.AppCompatImageView
android:layout_width="64dp" android:layout_width="64dp"
android:layout_height="64dp" android:layout_height="64dp"
android:elevation="8dp"
tools:ignore="UnusedAttribute"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
app:srcCompat="@drawable/blue_rinse_circle" /> android:elevation="8dp"
app:srcCompat="@drawable/blue_rinse_circle"
tools:ignore="UnusedAttribute" />
<android.support.v7.widget.AppCompatImageView <android.support.v7.widget.AppCompatImageView
android:layout_width="42dp" android:layout_width="42dp"
android:layout_height="42dp" android:layout_height="42dp"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
tools:ignore="UnusedAttribute"
android:elevation="8dp" android:elevation="8dp"
app:srcCompat="@drawable/commons_logo_large" /> app:srcCompat="@drawable/commons_logo_large"
tools:ignore="UnusedAttribute" />
</FrameLayout> </FrameLayout>

View file

@ -21,17 +21,19 @@
android:orientation="horizontal" android:orientation="horizontal"
android:gravity="center_vertical" android:gravity="center_vertical"
android:layout_below="@id/toolbar"> android:layout_below="@id/toolbar">
<ProgressBar <ProgressBar
android:id="@+id/progressBar" android:id="@+id/progressBar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipe_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout <FrameLayout
android:id="@+id/container" android:id="@+id/container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout> </LinearLayout>
</RelativeLayout> </RelativeLayout>

View file

@ -1,33 +1,34 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/fragmentCategorisationBackground" android:background="?attr/fragmentCategorisationBackground"
android:clickable="true"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:paddingBottom="@dimen/small_gap" android:paddingBottom="@dimen/small_gap"
android:paddingLeft="@dimen/standard_gap"
android:paddingStart="@dimen/standard_gap"
android:paddingRight="@dimen/standard_gap"
android:paddingEnd="@dimen/standard_gap" android:paddingEnd="@dimen/standard_gap"
android:paddingLeft="@dimen/standard_gap"
android:paddingRight="@dimen/standard_gap"
android:paddingStart="@dimen/standard_gap"
android:paddingTop="@dimen/small_gap" android:paddingTop="@dimen/small_gap"
android:theme="@style/DarkAppTheme" android:theme="@style/DarkAppTheme">
>
<FrameLayout <FrameLayout
android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
> android:layout_height="wrap_content"
android:clickable="true"
android:focusableInTouchMode="true">
<EditText <EditText
android:id="@+id/categoriesSearchBox" android:id="@+id/categoriesSearchBox"
android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/categories_search_text_hint" android:hint="@string/categories_search_text_hint"
android:maxLines="1" android:maxLines="1"
android:gravity="left" android:gravity="left"
android:inputType="textCapWords" android:inputType="textCapWords"
android:imeOptions="flagNoExtractUi" android:imeOptions="flagNoExtractUi"/>
/>
<ProgressBar <ProgressBar
android:id="@+id/categoriesSearchInProgress" android:id="@+id/categoriesSearchInProgress"
@ -45,27 +46,24 @@
<TextView <TextView
android:id="@+id/categoriesNotFound" android:id="@+id/categoriesNotFound"
android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:visibility="gone" android:layout_height="wrap_content"
android:gravity="center" android:gravity="center"
/> android:visibility="gone" />
<TextView <TextView
android:id="@+id/categoriesExplanation" android:id="@+id/categoriesExplanation"
android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/huge_gap" android:layout_marginTop="@dimen/huge_gap"
android:gravity="center"
android:focusable="true" android:focusable="true"
android:gravity="center"
android:text="@string/categories_skip_explanation" android:text="@string/categories_skip_explanation"
android:visibility="gone" android:visibility="gone" />
/>
<android.support.v7.widget.RecyclerView <android.support.v7.widget.RecyclerView
android:id="@+id/categoriesListBox" android:id="@+id/categoriesListBox"
android:layout_height="wrap_content"
android:layout_width="match_parent" android:layout_width="match_parent"
android:fadingEdge="none" android:layout_height="wrap_content"
/> android:fadingEdge="none" />
</LinearLayout> </LinearLayout>

View file

@ -149,6 +149,10 @@
tools:text="License link" /> tools:text="License link" />
</LinearLayout> </LinearLayout>
<fr.free.nrw.commons.media.MediaDetailSpacer
android:layout_width="match_parent"
android:layout_height="@dimen/small_gap" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View file

@ -3,6 +3,8 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clickable="true"
android:focusableInTouchMode="true"
> >
<EditText <EditText
@ -23,4 +25,5 @@
android:fadingEdge="none" android:fadingEdge="none"
android:fastScrollEnabled="false" android:fastScrollEnabled="false"
/> />
</LinearLayout> </LinearLayout>

View file

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/orginalImage"
android:layout_width="160dp"
android:layout_height="240dp"
android:layout_margin="3dp"
app:actualImageScaleType="centerCrop" />
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/possibleImage"
android:layout_width="160dp"
android:layout_height="240dp"
android:layout_margin="3dp"
app:actualImageScaleType="centerCrop" />
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="6dp"
android:layout_gravity="center"
android:textAlignment="center"
android:text="Did you shoot these two pictures at the same place? Do you want to use the latitude/longitude of the picture on the right?"/>
<LinearLayout
android:layout_width="match_parent"
android:orientation="horizontal"
android:layout_height="match_parent">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_gravity="right"
android:id="@+id/negative_button"
android:layout_marginRight="3dp"
android:layout_height="wrap_content"
android:text="No" />
<Button
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/postive_button"
android:layout_gravity="right"
android:layout_marginLeft="3dp"
android:text="Yes" />
</LinearLayout>
</LinearLayout>

View file

@ -67,15 +67,95 @@
android:textColor="@android:color/white" android:textColor="@android:color/white"
/> />
<TextView <LinearLayout
android:layout_width="295dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxWidth="240dp" android:gravity="center"
android:text="@string/tutorial_2_subtext" android:orientation="horizontal">
android:layout_gravity="center"
android:textAlignment="textStart" <TextView
android:paddingTop="@dimen/standard_gap" android:layout_width="wrap_content"
android:gravity="start" android:layout_height="wrap_content"
android:textColor="@android:color/white" android:text="@string/bullet"
/> android:paddingRight="4dp"
android:textSize="16sp"
android:paddingTop="@dimen/standard_gap"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_2_subtext_1"
android:layout_gravity="center"
android:textAlignment="textStart"
android:paddingTop="@dimen/standard_gap"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_2_subtext_2"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
</LinearLayout>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_2_subtext_3"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -48,15 +48,87 @@
android:textColor="@android:color/white" android:textColor="@android:color/white"
/> />
<TextView <LinearLayout
android:layout_width="295dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxWidth="240dp" android:gravity="center"
android:text="@string/tutorial_3_subtext" android:orientation="horizontal">
android:layout_gravity="center"
android:textAlignment="textStart" <TextView
android:paddingTop="@dimen/standard_gap" android:layout_width="wrap_content"
android:gravity="start" android:layout_height="wrap_content"
android:textColor="@android:color/white" android:text="@string/bullet"
/> android:paddingRight="4dp"
android:textSize="16sp"
android:paddingTop="@dimen/standard_gap"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_3_subtext_1"
android:layout_gravity="center"
android:textAlignment="textStart"
android:paddingTop="@dimen/standard_gap"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_3_subtext_2"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_3_subtext_3"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -32,15 +32,101 @@
android:textColor="@android:color/white" android:textColor="@android:color/white"
/> />
<TextView <LinearLayout
android:layout_width="278dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:maxWidth="240dp" android:gravity="center"
android:text="@string/tutorial_4_subtext" android:orientation="horizontal">
android:layout_gravity="center"
android:textAlignment="textStart" <TextView
android:paddingTop="@dimen/standard_gap" android:layout_width="wrap_content"
android:gravity="start" android:layout_height="wrap_content"
android:textColor="@android:color/white" android:text="@string/bullet"
/> android:paddingRight="4dp"
android:textSize="16sp"
android:paddingTop="@dimen/standard_gap"
android:textColor="@android:color/white"/>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_4_subtext_1"
android:layout_gravity="center"
android:textAlignment="textStart"
android:paddingTop="@dimen/standard_gap"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
</LinearLayout>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_4_subtext_2"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bullet"
android:paddingRight="4dp"
android:textSize="16sp"
android:textColor="@android:color/white"/>
</LinearLayout>
<TextView
android:layout_width="295dp"
android:layout_height="wrap_content"
android:maxWidth="240dp"
android:text="@string/tutorial_4_subtext_3"
android:layout_gravity="center"
android:textAlignment="textStart"
android:gravity="start"
android:textColor="@android:color/white"
/>
</LinearLayout>
</LinearLayout> </LinearLayout>

View file

@ -10,6 +10,11 @@
android:icon="@drawable/ic_location_black_24dp" android:icon="@drawable/ic_location_black_24dp"
android:title="@string/navigation_item_nearby"/> android:title="@string/navigation_item_nearby"/>
<item
android:id="@+id/action_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/navigation_item_notification"/>
<item <item
android:id="@+id/action_about" android:id="@+id/action_about"
android:icon="@drawable/ic_info_outline_black_24dp" android:icon="@drawable/ic_info_outline_black_24dp"
@ -35,9 +40,4 @@
android:icon="@drawable/ic_exit_to_app_black_24dp" android:icon="@drawable/ic_exit_to_app_black_24dp"
android:title="@string/navigation_item_logout"/> android:title="@string/navigation_item_logout"/>
<item
android:id="@+id/action_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/navigation_item_notification"/>
</menu> </menu>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Error al poner les fotos na caché</string> <string name="error_while_cache">Error al poner les fotos na caché</string>
<string name="title_info">Un títulu descriptivu únicu pal ficheru, que sirvirá para da-y nome al ficheru. Se pue usar llinguax normal con espacios. Nun amiestes la estensión del ficheru</string> <string name="title_info">Un títulu descriptivu únicu pal ficheru, que sirvirá para da-y nome al ficheru. Se pue usar llinguax normal con espacios. Nun amiestes la estensión del ficheru</string>
<string name="description_info">Por favor, describi l\'elementu multimedia tantu como sía posible: ¿ónde se tomó?, ¿qué amuesa?, ¿cuál ye\'l contestu? Por favor, describi los oxetos o persones. Revela la información que nun pueda aldovinase de mou cenciellu, por casu el momentu del día si ye un paisaxe. Si\'l mediu amuesa daqué desacostumao, esplica qué lo fai raro.</string> <string name="description_info">Por favor, describi l\'elementu multimedia tantu como sía posible: ¿ónde se tomó?, ¿qué amuesa?, ¿cuál ye\'l contestu? Por favor, describi los oxetos o persones. Revela la información que nun pueda aldovinase de mou cenciellu, por casu el momentu del día si ye un paisaxe. Si\'l mediu amuesa daqué desacostumao, esplica qué lo fai raro.</string>
<string name="upload_image_too_dark">Esta imaxe ye escura enforma, ¿tas seguru de que quies xubila? Wikimedia Commons ye sólo pa imáxenes con valor enciclopédicu.</string>
<string name="upload_image_blurry">Esta imaxe ta borrosa, ¿tas seguru de que quies xubila? Wikimedia Commons ye sólo pa imáxenes con valor enciclopédicu.</string>
<string name="give_permission">Dar permisu</string> <string name="give_permission">Dar permisu</string>
<string name="use_external_storage">Usar almacenamientu esternu</string> <string name="use_external_storage">Usar almacenamientu esternu</string>
<string name="use_external_storage_summary">Guardar nel preséu les imaxes tomaes cola cámara de la app</string> <string name="use_external_storage_summary">Guardar nel preséu les imaxes tomaes cola cámara de la app</string>
<string name="login_to_your_account">Anicia sesión na to cuenta</string>
<string name="send_log_file">Unviar ficheru de rexistru</string> <string name="send_log_file">Unviar ficheru de rexistru</string>
<string name="send_log_file_description">Unviar ficheru de rexistru a los desendolcadores per corréu electrónicu</string> <string name="send_log_file_description">Unviar ficheru de rexistru a los desendolcadores per corréu electrónicu</string>
<string name="login_to_your_account">Anicia sesión na to cuenta</string>
<string name="nearby_location_has_not_changed">L\'allugamientu nun camudó.</string> <string name="nearby_location_has_not_changed">L\'allugamientu nun camudó.</string>
<string name="nearby_location_not_available">L\'allugamientu nun ta disponible.</string> <string name="nearby_location_not_available">L\'allugamientu nun ta disponible.</string>
<string name="location_permission_rationale_nearby">Ríquese permisu p\'amosar una llista de llugares cercanos</string> <string name="location_permission_rationale_nearby">Ríquese permisu p\'amosar una llista de llugares cercanos</string>

View file

@ -199,9 +199,9 @@
<string name="give_permission">Davanje dozvole</string> <string name="give_permission">Davanje dozvole</string>
<string name="use_external_storage">Upotreba spoljašnjeg skladišta</string> <string name="use_external_storage">Upotreba spoljašnjeg skladišta</string>
<string name="use_external_storage_summary">Spremanje slika napravljenih kamerom aplikacije na Vašem uređaju</string> <string name="use_external_storage_summary">Spremanje slika napravljenih kamerom aplikacije na Vašem uređaju</string>
<string name="login_to_your_account">Prijavite se na svoj nalog</string>
<string name="send_log_file">Pošalji dnevničku datoteku</string> <string name="send_log_file">Pošalji dnevničku datoteku</string>
<string name="send_log_file_description">Pošalji dnevničku datoteku developerima preko imejla</string> <string name="send_log_file_description">Pošalji dnevničku datoteku developerima preko imejla</string>
<string name="login_to_your_account">Prijavite se na svoj nalog</string>
<string name="nearby_location_has_not_changed">Lokacija nije promenjena.</string> <string name="nearby_location_has_not_changed">Lokacija nije promenjena.</string>
<string name="nearby_location_not_available">Lokacija nije dostupna.</string> <string name="nearby_location_not_available">Lokacija nije dostupna.</string>
<string name="location_permission_rationale_nearby">Potrebna je dozvola za prikazivanje liste lokacija u blizini</string> <string name="location_permission_rationale_nearby">Potrebna je dozvola za prikazivanje liste lokacija u blizini</string>

View file

@ -202,9 +202,9 @@
<string name="give_permission">অনুমতি দিন</string> <string name="give_permission">অনুমতি দিন</string>
<string name="use_external_storage">বাহ্যিক সঞ্চয়স্থান ব্যবহার করুন</string> <string name="use_external_storage">বাহ্যিক সঞ্চয়স্থান ব্যবহার করুন</string>
<string name="use_external_storage_summary">অাপনার ডিভাইসের নিজস্ব ক্যামেরায় ধারণকৃত ছবি সংরক্ষণ করুন</string> <string name="use_external_storage_summary">অাপনার ডিভাইসের নিজস্ব ক্যামেরায় ধারণকৃত ছবি সংরক্ষণ করুন</string>
<string name="login_to_your_account">আপনার অ্যাকাউন্টে প্রবেশ করুন</string>
<string name="send_log_file">লগ ফাইল পাঠান</string> <string name="send_log_file">লগ ফাইল পাঠান</string>
<string name="send_log_file_description">ইমেইলের মাধ্যমে উন্নয়নকারীর কাছে লগ ফাইল পাঠান</string> <string name="send_log_file_description">ইমেইলের মাধ্যমে উন্নয়নকারীর কাছে লগ ফাইল পাঠান</string>
<string name="login_to_your_account">আপনার অ্যাকাউন্টে প্রবেশ করুন</string>
<string name="nearby_location_has_not_changed">অবস্থান পরিবর্তন হয়নি।</string> <string name="nearby_location_has_not_changed">অবস্থান পরিবর্তন হয়নি।</string>
<string name="nearby_location_not_available">অবস্থান উপলব্ধ নয়।</string> <string name="nearby_location_not_available">অবস্থান উপলব্ধ নয়।</string>
<string name="location_permission_rationale_nearby">কাছাকাছি স্থানসমূহের একটি তালিকা প্রদর্শন করতে অনুমতি প্রয়োজন</string> <string name="location_permission_rationale_nearby">কাছাকাছি স্থানসমূহের একটি তালিকা প্রদর্শন করতে অনুমতি প্রয়োজন</string>

View file

@ -170,9 +170,9 @@
<string name="error_while_cache">Error mentre es carregaven les fotografies</string> <string name="error_while_cache">Error mentre es carregaven les fotografies</string>
<string name="give_permission">Dóna permís</string> <string name="give_permission">Dóna permís</string>
<string name="use_external_storage">Utilitza lemmagatzematge extern</string> <string name="use_external_storage">Utilitza lemmagatzematge extern</string>
<string name="login_to_your_account">Entreu en el vostre compte</string>
<string name="send_log_file">Envia el fitxer de registre</string> <string name="send_log_file">Envia el fitxer de registre</string>
<string name="send_log_file_description">Envia el registre als desenvolupadors per correu</string> <string name="send_log_file_description">Envia el registre als desenvolupadors per correu</string>
<string name="login_to_your_account">Entreu en el vostre compte</string>
<string name="nearby_location_has_not_changed">La ubicació no ha canviat.</string> <string name="nearby_location_has_not_changed">La ubicació no ha canviat.</string>
<string name="nearby_location_not_available">La ubicació no és disponible.</string> <string name="nearby_location_not_available">La ubicació no és disponible.</string>
<string name="get_directions">COM ANAR-HI</string> <string name="get_directions">COM ANAR-HI</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Chyba při meziukládání obrázků</string> <string name="error_while_cache">Chyba při meziukládání obrázků</string>
<string name="title_info">Unikátní a popisný název pro daný soubor, který bude sloužit jako název souboru. Můžete použít běžný psaný jazyk s mezerami; nezahrnujte koncovku souboru.</string> <string name="title_info">Unikátní a popisný název pro daný soubor, který bude sloužit jako název souboru. Můžete použít běžný psaný jazyk s mezerami; nezahrnujte koncovku souboru.</string>
<string name="description_info">Popište prosím obrázek, jak jen to je možné: Kde byl pořízen? Co znázorňuje? Jaký je kontext obrázku? Popisujte prosím významné předměty nebo osoby na obrázku a nezapomeňte na informace, které není možné snadno odhadnout ze samotného obrázku, jako je například denní doba, pokud jde o krajinu. Pokud je na obrázku něco neobvyklého, popište, co to dělá neobvyklým.</string> <string name="description_info">Popište prosím obrázek, jak jen to je možné: Kde byl pořízen? Co znázorňuje? Jaký je kontext obrázku? Popisujte prosím významné předměty nebo osoby na obrázku a nezapomeňte na informace, které není možné snadno odhadnout ze samotného obrázku, jako je například denní doba, pokud jde o krajinu. Pokud je na obrázku něco neobvyklého, popište, co to dělá neobvyklým.</string>
<string name="upload_image_too_dark">Tento obrázek je příliš tmavý, jste si jist/a, že ho chcete nahrát? Wikimedia Commons slouží jenom pro obrázky s encyklopedickou hodnotou.</string>
<string name="upload_image_blurry">Tento obrázek je rozmazaný, jste si jist/a, že ho chcete nahrát? Wikimedia Commons slouží jenom pro obrázky s encyklopedickou hodnotou.</string>
<string name="give_permission">Dát povolení</string> <string name="give_permission">Dát povolení</string>
<string name="use_external_storage">Použít externí úložiště</string> <string name="use_external_storage">Použít externí úložiště</string>
<string name="use_external_storage_summary">Uložit obrázky pořízené fotoaparátem, jenž je součástí této aplikace</string> <string name="use_external_storage_summary">Uložit obrázky pořízené fotoaparátem, jenž je součástí této aplikace</string>
<string name="login_to_your_account">Přihlásit se k účtu</string>
<string name="send_log_file">Odeslat log</string> <string name="send_log_file">Odeslat log</string>
<string name="send_log_file_description">Odeslat log vývojářům e-mailem</string> <string name="send_log_file_description">Odeslat log vývojářům e-mailem</string>
<string name="login_to_your_account">Přihlásit se k účtu</string>
<string name="nearby_location_has_not_changed">Vaše umístění se nezměnilo.</string> <string name="nearby_location_has_not_changed">Vaše umístění se nezměnilo.</string>
<string name="nearby_location_not_available">Umístění není dostupné.</string> <string name="nearby_location_not_available">Umístění není dostupné.</string>
<string name="location_permission_rationale_nearby">Vyžadováno povolení k zobrazení seznamu blízkých míst</string> <string name="location_permission_rationale_nearby">Vyžadováno povolení k zobrazení seznamu blízkých míst</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Fejl under mellemlagring af billeder</string> <string name="error_while_cache">Fejl under mellemlagring af billeder</string>
<string name="title_info">En unik beskrivelse for filen, som vil fungere som et filnavn. Du kan bruge normalt sprog med mellemrum. Udelad filendelsen.</string> <string name="title_info">En unik beskrivelse for filen, som vil fungere som et filnavn. Du kan bruge normalt sprog med mellemrum. Udelad filendelsen.</string>
<string name="description_info">Beskriv mediet så godt som muligt: Hvor blev det taget? Hvad viser det? Hvad er konteksten? Beskriv objekterne eller personerne. Giv information som ikke nemt kan gættes, for eksempel hvornår på dagen billedet blev taget, om det er et landskabsbillede. Om billedet viser noget usædvanligt, forklar hvad som gør det usædvanlig.</string> <string name="description_info">Beskriv mediet så godt som muligt: Hvor blev det taget? Hvad viser det? Hvad er konteksten? Beskriv objekterne eller personerne. Giv information som ikke nemt kan gættes, for eksempel hvornår på dagen billedet blev taget, om det er et landskabsbillede. Om billedet viser noget usædvanligt, forklar hvad som gør det usædvanlig.</string>
<string name="upload_image_too_dark">Billedet er for mørkt. Er du sikker på, at du ønsker at overføre det? Wikimedia Commons er kun for billeder encyklopædisk værdi.</string>
<string name="upload_image_blurry">Dette billede er sløret. Er du sikker på, at du ønsker at overføre det? Wikimedia Commons er kun for billeder med encyklopædisk værdi.</string>
<string name="give_permission">Giv tilladelse</string> <string name="give_permission">Giv tilladelse</string>
<string name="use_external_storage">Brug eksternt lager</string> <string name="use_external_storage">Brug eksternt lager</string>
<string name="use_external_storage_summary">Gem billeder taget med din enheds program på kameraet</string> <string name="use_external_storage_summary">Gem billeder taget med din enheds program på kameraet</string>
<string name="login_to_your_account">Log ind på din konto</string>
<string name="send_log_file">Send logfil</string> <string name="send_log_file">Send logfil</string>
<string name="send_log_file_description">Send logfil til udviklerne via e-post</string> <string name="send_log_file_description">Send logfil til udviklerne via e-post</string>
<string name="login_to_your_account">Log ind på din konto</string>
<string name="nearby_location_has_not_changed">Sted er ikke ændret.</string> <string name="nearby_location_has_not_changed">Sted er ikke ændret.</string>
<string name="nearby_location_not_available">Sted ikke tilgængeligt.</string> <string name="nearby_location_not_available">Sted ikke tilgængeligt.</string>
<string name="location_permission_rationale_nearby">Tilladelse kræves for at vise en liste over steder i nærheden</string> <string name="location_permission_rationale_nearby">Tilladelse kræves for at vise en liste over steder i nærheden</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Fehler beim Zwischenspeichern der Bilder</string> <string name="error_while_cache">Fehler beim Zwischenspeichern der Bilder</string>
<string name="title_info">Ein eindeutiger beschreibender Titel für die Datei, der als Dateiname dient. Du kannst Klartext mit Leerzeichen verwenden. Gib nicht die Dateierweiterung mit an.</string> <string name="title_info">Ein eindeutiger beschreibender Titel für die Datei, der als Dateiname dient. Du kannst Klartext mit Leerzeichen verwenden. Gib nicht die Dateierweiterung mit an.</string>
<string name="description_info">Bitte beschreibe das Medium so gut wie möglich: Wo wurde es aufgenommen? Was zeigt es? Was ist der Kontext? Bitte beschreibe die Objekte oder Personen. Zeige Informationen auf, die nicht einfach erraten werden können, zum Beispiel die Tageszeit, falls es eine Landschaft ist. Falls das Medium etwas Ungewöhnliches zeigt, erkläre bitte, was es ungewöhnlich macht.</string> <string name="description_info">Bitte beschreibe das Medium so gut wie möglich: Wo wurde es aufgenommen? Was zeigt es? Was ist der Kontext? Bitte beschreibe die Objekte oder Personen. Zeige Informationen auf, die nicht einfach erraten werden können, zum Beispiel die Tageszeit, falls es eine Landschaft ist. Falls das Medium etwas Ungewöhnliches zeigt, erkläre bitte, was es ungewöhnlich macht.</string>
<string name="upload_image_too_dark">Dieses Bild ist zu dunkel. Bist du sicher, dass du es hochladen möchtest? Wikimedia Commons ist nur für Bilder mit enzyklopädischem Wert gedacht.</string>
<string name="upload_image_blurry">Dieses Bild ist verschwommen. Bist du sicher, dass du es hochladen möchtest? Wikimedia Commons ist nur für Bilder mit enzyklopädischem Wert gedacht.</string>
<string name="give_permission">Berechtigung geben</string> <string name="give_permission">Berechtigung geben</string>
<string name="use_external_storage">Externen Speicher verwenden</string> <string name="use_external_storage">Externen Speicher verwenden</string>
<string name="use_external_storage_summary">Mit der In-App-Kamera aufgenommene Bilder auf deinem Gerät speichern</string> <string name="use_external_storage_summary">Mit der In-App-Kamera aufgenommene Bilder auf deinem Gerät speichern</string>
<string name="login_to_your_account">Bei deinem Benutzerkonto anmelden</string>
<string name="send_log_file">Logdatei senden</string> <string name="send_log_file">Logdatei senden</string>
<string name="send_log_file_description">Logdatei an die Entwickler per E-Mail senden</string> <string name="send_log_file_description">Logdatei an die Entwickler per E-Mail senden</string>
<string name="login_to_your_account">Bei deinem Benutzerkonto anmelden</string>
<string name="nearby_location_has_not_changed">Der Standort hat sich nicht geändert.</string> <string name="nearby_location_has_not_changed">Der Standort hat sich nicht geändert.</string>
<string name="nearby_location_not_available">Der Standort ist nicht verfügbar.</string> <string name="nearby_location_not_available">Der Standort ist nicht verfügbar.</string>
<string name="location_permission_rationale_nearby">Berechtigung zur Anzeige einer Liste mit Orten in der Nähe erforderlich</string> <string name="location_permission_rationale_nearby">Berechtigung zur Anzeige einer Liste mit Orten in der Nähe erforderlich</string>

View file

@ -7,7 +7,7 @@
<string name="login">Cı kewe</string> <string name="login">Cı kewe</string>
<string name="signup">Qeyd be</string> <string name="signup">Qeyd be</string>
<string name="logging_in_title">Cıkewtış</string> <string name="logging_in_title">Cıkewtış</string>
<string name="logging_in_message" fuzzy="true">Tay bıpawe</string> <string name="logging_in_message">Kerem kerên, bıpawên...</string>
<string name="login_success">Cıkewtış hewl bi.</string> <string name="login_success">Cıkewtış hewl bi.</string>
<string name="login_failed">Nidekeweya de</string> <string name="login_failed">Nidekeweya de</string>
<string name="upload_failed">Dosya nêvineya. Dosyê da bine bıcerebnê.</string> <string name="upload_failed">Dosya nêvineya. Dosyê da bine bıcerebnê.</string>
@ -20,9 +20,9 @@
<string name="upload_progress_notification_title_finishing">Barkerdışe %1$s qedya</string> <string name="upload_progress_notification_title_finishing">Barkerdışe %1$s qedya</string>
<string name="upload_failed_notification_title">%1$s bar nêbeno.</string> <string name="upload_failed_notification_title">%1$s bar nêbeno.</string>
<string name="upload_failed_notification_subtitle">pıpawane xo bıvin</string> <string name="upload_failed_notification_subtitle">pıpawane xo bıvin</string>
<plurals name="uploads_pending_notification_indicator" fuzzy="true"> <plurals name="uploads_pending_notification_indicator">
<item quantity="one">1 dosye selagnayış</item> <item quantity="one">1 dosya bar bena</item>
<item quantity="other">%1$d dosye Selagnayışi</item> <item quantity="other">%1$d dosyeyi bar benê</item>
</plurals> </plurals>
<string name="title_activity_contributions">Barkerdışê mınê peyêni</string> <string name="title_activity_contributions">Barkerdışê mınê peyêni</string>
<string name="contribution_state_queued">Ratneya</string> <string name="contribution_state_queued">Ratneya</string>
@ -49,18 +49,18 @@
<string name="menu_upload_single">Bar ke</string> <string name="menu_upload_single">Bar ke</string>
<string name="categories_search_text_hint">Kategoriyan dı cı geyr</string> <string name="categories_search_text_hint">Kategoriyan dı cı geyr</string>
<string name="menu_save_categories">Star ke</string> <string name="menu_save_categories">Star ke</string>
<plurals name="contributions_subtitle" fuzzy="true"> <plurals name="contributions_subtitle">
<item quantity="zero">Theba bar nêbı</item> <item quantity="zero">\@string/contributions_subtitle_zero</item>
<item quantity="one">1 bar kerdış</item> <item quantity="one">Yew barbiyayış</item>
<item quantity="other">%1$d bar kerdışi</item> <item quantity="other">%1$d barbiyayışi</item>
</plurals> </plurals>
<plurals name="starting_multiple_uploads" fuzzy="true"> <plurals name="starting_multiple_uploads" fuzzy="true">
<item quantity="one">Sergendış 1 bar kerdış</item> <item quantity="one">Sergendış 1 bar kerdış</item>
<item quantity="other">Sergendış %1$d bar kerdışi </item> <item quantity="other">Sergendış %1$d bar kerdışi </item>
</plurals> </plurals>
<plurals name="multiple_uploads_title" fuzzy="true"> <plurals name="multiple_uploads_title">
<item quantity="one">1 bar kerdış</item> <item quantity="one">%1$d barkerdış</item>
<item quantity="other">%1$d bar kerdışi </item> <item quantity="other">%1$d barkerdışi</item>
</plurals> </plurals>
<string name="categories_not_found">Kategoriyan de %1$s deye theba çıniyo</string> <string name="categories_not_found">Kategoriyan de %1$s deye theba çıniyo</string>
<string name="categories_skip_explanation" fuzzy="true">Kategori cı kerdışi rê nusnayış bıkeré. Ena gamer ravêrdışi rê mesaci bıpıloğnê yana peyd şırê.</string> <string name="categories_skip_explanation" fuzzy="true">Kategori cı kerdışi rê nusnayış bıkeré. Ena gamer ravêrdışi rê mesaci bıpıloğnê yana peyd şırê.</string>
@ -69,7 +69,7 @@
<string name="title_activity_signup">Qeyd be</string> <string name="title_activity_signup">Qeyd be</string>
<string name="menu_about">Heq te cı</string> <string name="menu_about">Heq te cı</string>
<string name="about_improve" fuzzy="true">&lt;a href=\"https://github.com/commons-app/apps-android-commons\"&gt;Çıme&lt;/a&gt; u &lt;a href=\"https://commons-app.github.io/\"&gt;website&lt;/a&gt; on GitHub&lt;/a&gt;. Newe vıraz &lt;a href=\"https://github.com/commons-app/apps-android-commons/issues\"&gt;GitHub mewzu &lt;/a&gt; U rapor bıweseynê</string> <string name="about_improve" fuzzy="true">&lt;a href=\"https://github.com/commons-app/apps-android-commons\"&gt;Çıme&lt;/a&gt; u &lt;a href=\"https://commons-app.github.io/\"&gt;website&lt;/a&gt; on GitHub&lt;/a&gt;. Newe vıraz &lt;a href=\"https://github.com/commons-app/apps-android-commons/issues\"&gt;GitHub mewzu &lt;/a&gt; U rapor bıweseynê</string>
<string name="about_privacy_policy" fuzzy="true">/</string> <string name="about_privacy_policy">&lt;a href=\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\"&gt;Politikay nımıtışi&lt;/a&gt;</string>
<string name="title_activity_about">Heq te cı</string> <string name="title_activity_about">Heq te cı</string>
<string name="menu_feedback">Peyd rışten bırış (E-posta ra)</string> <string name="menu_feedback">Peyd rışten bırış (E-posta ra)</string>
<string name="no_email_client">E-posta eyar nêbi</string> <string name="no_email_client">E-posta eyar nêbi</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Υπήρξε σφάλμα κατά την σκίαση εικόνων</string> <string name="error_while_cache">Υπήρξε σφάλμα κατά την σκίαση εικόνων</string>
<string name="title_info">Ένας μοναδικός τίτλος περιγραφής του φακέλλου, που θα χρησιμεύσει ως όνομα φακέλλου. Μπορείτε να χρησιμοποιήσετε τις ήδη υπάρχουσες γλώσσες με διαστήματα. Μην συμπεριλάβετε την επέκταση φακέλλου</string> <string name="title_info">Ένας μοναδικός τίτλος περιγραφής του φακέλλου, που θα χρησιμεύσει ως όνομα φακέλλου. Μπορείτε να χρησιμοποιήσετε τις ήδη υπάρχουσες γλώσσες με διαστήματα. Μην συμπεριλάβετε την επέκταση φακέλλου</string>
<string name="description_info">\nΠαρακαλώ περιγράψετε τα μέσα το δυνατό περισσότερο : Πού οδηγήθηκε αυτό; Τι δείχνει; Ποιο είναι το περιεχόμενο του; Παρακαλώ περιγράψετε τα αντικείμενα ή τα πρόσωπα. Αποκαλύψετε πληροφορίες που δεν μπορούν εύκολο να μαντέψει κανείς, για παράδειγμα την ώρα εντός της ημέρας αν πρόκειται για τοπίο. Αν τα μέσα δείξουν κάτι ασύνηθες, παρακαλώ εξηγήστε τι το καθιστά μη συνηθισμένα.</string> <string name="description_info">\nΠαρακαλώ περιγράψετε τα μέσα το δυνατό περισσότερο : Πού οδηγήθηκε αυτό; Τι δείχνει; Ποιο είναι το περιεχόμενο του; Παρακαλώ περιγράψετε τα αντικείμενα ή τα πρόσωπα. Αποκαλύψετε πληροφορίες που δεν μπορούν εύκολο να μαντέψει κανείς, για παράδειγμα την ώρα εντός της ημέρας αν πρόκειται για τοπίο. Αν τα μέσα δείξουν κάτι ασύνηθες, παρακαλώ εξηγήστε τι το καθιστά μη συνηθισμένα.</string>
<string name="upload_image_too_dark">Αυτή η εικόνα είναι πολύ σκοτεινή, είστε βέβαιοι ότι θέλετε να την ανεβάσετε; Το Wikimedia Commons είναι μόνο για εικόνες με εγκυκλοπαιδική αξία.</string>
<string name="upload_image_blurry">Αυτή η εικόνα είναι θολή, είστε βέβαιοι ότι θέλετε να την ανεβάσετε; Το Wikimedia Commons είναι μόνο για εικόνες με εγκυκλοπαιδική αξία.</string>
<string name="give_permission">Χορηγήστε άδεια</string> <string name="give_permission">Χορηγήστε άδεια</string>
<string name="use_external_storage">Χρησιμοποιήσετε την εξωτερική αποθήκευση</string> <string name="use_external_storage">Χρησιμοποιήσετε την εξωτερική αποθήκευση</string>
<string name="use_external_storage_summary">Αποθηκεύσετε εικόνες που παίρνονται στην κάμερα εφαρμογής στην συσκευή σας</string> <string name="use_external_storage_summary">Αποθηκεύσετε εικόνες που παίρνονται στην κάμερα εφαρμογής στην συσκευή σας</string>
<string name="login_to_your_account">Συνδεθείτε στο λογαριασμό σας.</string>
<string name="send_log_file">Αποστείλατε τον φάκελλο σύνδεσης</string> <string name="send_log_file">Αποστείλατε τον φάκελλο σύνδεσης</string>
<string name="send_log_file_description">Στείλατε τον φάκελλο σύνδεσης στους δημιουργούς μέσω email</string> <string name="send_log_file_description">Στείλατε τον φάκελλο σύνδεσης στους δημιουργούς μέσω email</string>
<string name="login_to_your_account">Συνδεθείτε στο λογαριασμό σας.</string>
<string name="nearby_location_has_not_changed">Ο εντοπισμός δεν έχει αλλάξει.</string> <string name="nearby_location_has_not_changed">Ο εντοπισμός δεν έχει αλλάξει.</string>
<string name="nearby_location_not_available">Ο τόπος δεν είναι διαθέσιμος.</string> <string name="nearby_location_not_available">Ο τόπος δεν είναι διαθέσιμος.</string>
<string name="location_permission_rationale_nearby">Απαιτείται άδεια για την εμφάνιση λίστας κοντινών σημείων</string> <string name="location_permission_rationale_nearby">Απαιτείται άδεια για την εμφάνιση λίστας κοντινών σημείων</string>

View file

@ -198,13 +198,15 @@
<string name="nearby_info_menu_wikidata_article">Elemento de Wikidata</string> <string name="nearby_info_menu_wikidata_article">Elemento de Wikidata</string>
<string name="error_while_cache">Error al almacenar imágenes en la antememoria</string> <string name="error_while_cache">Error al almacenar imágenes en la antememoria</string>
<string name="title_info">Un título único descriptivo para el archivo, que servirá como un nombre de archivo. Puede usar un lenguaje claro con espacios. No incluya la extensión del archivo.</string> <string name="title_info">Un título único descriptivo para el archivo, que servirá como un nombre de archivo. Puede usar un lenguaje claro con espacios. No incluya la extensión del archivo.</string>
<string name="description_info">Por favor, describa el elemento multimedia tanto como sea posible: ¿dónde fue tomado?, ¿qué muestra?, ¿cuál es el contexto? Por favor, describa los objetos o personas. Ofrezca la información que no puede ser inferida tan facilmente, por ejemplo el momento del día si es un paisaje. Si el medio muestra algo inusual, explique qué lo hace insual.</string> <string name="description_info">Por favor, describa el elemento multimedia tanto como sea posible: ¿dónde fue tomado?, ¿qué muestra?, ¿cuál es el contexto? Por favor, describa los objetos o personas. Ofrezca la información que no puede ser inferida tan fácilmente, por ejemplo el momento del día si es un paisaje. Si el medio muestra algo inusual, explique qué lo hace insual.</string>
<string name="upload_image_too_dark">Esta imagen es demasiado oscura. ¿Confirmas que quieres cargarla? Wikimedia Commons solo acepta imágenes con valor enciclopédico.</string>
<string name="upload_image_blurry">Esta imagen se ve borrosa. ¿Confirmas que quieres cargarla? Wikimedia Commons solo acepta imágenes con valor enciclopédico.</string>
<string name="give_permission">Otorgar permiso</string> <string name="give_permission">Otorgar permiso</string>
<string name="use_external_storage">Utilizar almacenamiento externo</string> <string name="use_external_storage">Utilizar almacenamiento externo</string>
<string name="use_external_storage_summary">Guardar en el dispositivo imágenes capturadas con la cámara de la aplicación</string> <string name="use_external_storage_summary">Guardar en el dispositivo imágenes capturadas con la cámara de la aplicación</string>
<string name="login_to_your_account">Accede a tu cuenta</string>
<string name="send_log_file">Enviar archivo de registro</string> <string name="send_log_file">Enviar archivo de registro</string>
<string name="send_log_file_description">Enviar archivo de registro a los desarrolladores por correo electrónico</string> <string name="send_log_file_description">Enviar archivo de registro a los desarrolladores por correo electrónico</string>
<string name="login_to_your_account">Accede a tu cuenta</string>
<string name="nearby_location_has_not_changed">La ubicación no ha cambiado.</string> <string name="nearby_location_has_not_changed">La ubicación no ha cambiado.</string>
<string name="nearby_location_not_available">La ubicación no está disponible.</string> <string name="nearby_location_not_available">La ubicación no está disponible.</string>
<string name="location_permission_rationale_nearby">Se necesita permiso para mostrar una lista de lugares cercanos</string> <string name="location_permission_rationale_nearby">Se necesita permiso para mostrar una lista de lugares cercanos</string>

View file

@ -198,9 +198,9 @@
<string name="give_permission">اجازه بده</string> <string name="give_permission">اجازه بده</string>
<string name="use_external_storage">استفاده از حافظهٔ خارجی</string> <string name="use_external_storage">استفاده از حافظهٔ خارجی</string>
<string name="use_external_storage_summary">ذخیرهٔ تصویرهای گرفته شده توسط دوربین درونکار اپلیکیشن بر روی دستگاه شما</string> <string name="use_external_storage_summary">ذخیرهٔ تصویرهای گرفته شده توسط دوربین درونکار اپلیکیشن بر روی دستگاه شما</string>
<string name="login_to_your_account">ورود به حساب کاربریتان</string>
<string name="send_log_file">ارسال فایل سیاهه</string> <string name="send_log_file">ارسال فایل سیاهه</string>
<string name="send_log_file_description">ارسال فایل سیاهه به‌وسیلهٔ ایمیل برای توسعه‌دهندگان</string> <string name="send_log_file_description">ارسال فایل سیاهه به‌وسیلهٔ ایمیل برای توسعه‌دهندگان</string>
<string name="login_to_your_account">ورود به حساب کاربریتان</string>
<string name="nearby_location_has_not_changed">مکان تغییر نکرده‌است.</string> <string name="nearby_location_has_not_changed">مکان تغییر نکرده‌است.</string>
<string name="nearby_location_not_available">مکان موجود نیست.</string> <string name="nearby_location_not_available">مکان موجود نیست.</string>
<string name="location_permission_rationale_nearby">برای نمایش مکان‌ّای اطراف نیاز به اجازه است.</string> <string name="location_permission_rationale_nearby">برای نمایش مکان‌ّای اطراف نیاز به اجازه است.</string>

View file

@ -192,9 +192,9 @@
<string name="title_info">Tiedoston yksilöllinen ja kuvaava otsikko, jota käytetään tiedostonimenä. Voit käyttää tavallista kieltä välilyönnein. Älä sisällytä tiedoston päätettä.</string> <string name="title_info">Tiedoston yksilöllinen ja kuvaava otsikko, jota käytetään tiedostonimenä. Voit käyttää tavallista kieltä välilyönnein. Älä sisällytä tiedoston päätettä.</string>
<string name="give_permission">Anna lupa</string> <string name="give_permission">Anna lupa</string>
<string name="use_external_storage">Käytä ulkoista tallennustilaa</string> <string name="use_external_storage">Käytä ulkoista tallennustilaa</string>
<string name="login_to_your_account">Kirjaudu tilillesi</string>
<string name="send_log_file">Lähetä lokitiedosto</string> <string name="send_log_file">Lähetä lokitiedosto</string>
<string name="send_log_file_description">Lähetä logitiedosto kehittäjille sähköpostin kautta</string> <string name="send_log_file_description">Lähetä logitiedosto kehittäjille sähköpostin kautta</string>
<string name="login_to_your_account">Kirjaudu tilillesi</string>
<string name="nearby_location_has_not_changed">Sijainti ei ole muuttunut.</string> <string name="nearby_location_has_not_changed">Sijainti ei ole muuttunut.</string>
<string name="nearby_location_not_available">Sijainti ei käytettävissä.</string> <string name="nearby_location_not_available">Sijainti ei käytettävissä.</string>
<string name="read_article">LUE ARTIKKELI</string> <string name="read_article">LUE ARTIKKELI</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Erreur en mettant les images en cache</string> <string name="error_while_cache">Erreur en mettant les images en cache</string>
<string name="title_info">Un titre descriptif unique pour le fichier, qui servira de nom de fichier. Vous pouvez utiliser un langage simple avec des espaces. Nincluez pas lextension du fichier</string> <string name="title_info">Un titre descriptif unique pour le fichier, qui servira de nom de fichier. Vous pouvez utiliser un langage simple avec des espaces. Nincluez pas lextension du fichier</string>
<string name="description_info">Veuillez décrire le média autant que possible : Où a-t-il été enregistré? Que montre-t-il? Quel est le contexte? Veuillez décrire les objets ou les personnes. Révélez les informations qui ne peuvent pas être devinées facilement, par exemple lheure de la journée si cest un paysage. Si le média montre quelque chose dinhabituel, veuillez expliquer ce qui le rend exceptionnel.</string> <string name="description_info">Veuillez décrire le média autant que possible : Où a-t-il été enregistré? Que montre-t-il? Quel est le contexte? Veuillez décrire les objets ou les personnes. Révélez les informations qui ne peuvent pas être devinées facilement, par exemple lheure de la journée si cest un paysage. Si le média montre quelque chose dinhabituel, veuillez expliquer ce qui le rend exceptionnel.</string>
<string name="upload_image_too_dark">Cette image est trop sombre, êtes-vous sûr de vouloir la télécharger? Wikimédia Communs nest que pour les images avec une valeur encyclopédique.</string>
<string name="upload_image_blurry">Cette image est floue, êtes-vous sûr de vouloir la télécharger? Wikimédia Communs nest que pour les images ayant une valeur encyclopédique.</string>
<string name="give_permission">Accorder le droit</string> <string name="give_permission">Accorder le droit</string>
<string name="use_external_storage">Utiliser le stockage externe</string> <string name="use_external_storage">Utiliser le stockage externe</string>
<string name="use_external_storage_summary">Enregistrer les images prises avec lappareil photo de votre appareil</string> <string name="use_external_storage_summary">Enregistrer les images prises avec lappareil photo de votre appareil</string>
<string name="login_to_your_account">Connectez-vous à votre compte</string>
<string name="send_log_file">Envoyer le journal</string> <string name="send_log_file">Envoyer le journal</string>
<string name="send_log_file_description">Envoyer le journal aux développeurs par courriel</string> <string name="send_log_file_description">Envoyer le journal aux développeurs par courriel</string>
<string name="login_to_your_account">Connectez-vous à votre compte</string>
<string name="nearby_location_has_not_changed">L\'emplacement n\'a pas changé.</string> <string name="nearby_location_has_not_changed">L\'emplacement n\'a pas changé.</string>
<string name="nearby_location_not_available">Emplacement non disponible.</string> <string name="nearby_location_not_available">Emplacement non disponible.</string>
<string name="location_permission_rationale_nearby">Une permission est requise pour afficher une liste de lieux relatifs</string> <string name="location_permission_rationale_nearby">Une permission est requise pour afficher une liste de lieux relatifs</string>

View file

@ -202,9 +202,9 @@
<string name="give_permission">Outorgar permiso</string> <string name="give_permission">Outorgar permiso</string>
<string name="use_external_storage">Usar o almacenamento externo</string> <string name="use_external_storage">Usar o almacenamento externo</string>
<string name="use_external_storage_summary">Gardar as imaxes capturadas coa cámara do seu dispositivo</string> <string name="use_external_storage_summary">Gardar as imaxes capturadas coa cámara do seu dispositivo</string>
<string name="login_to_your_account">Comezar sesión na súa conta</string>
<string name="send_log_file">Enviar ficheiro de rexistro</string> <string name="send_log_file">Enviar ficheiro de rexistro</string>
<string name="send_log_file_description">Enviar ficheiro de rexistro ós desenvolvedores por correo electrónico</string> <string name="send_log_file_description">Enviar ficheiro de rexistro ós desenvolvedores por correo electrónico</string>
<string name="login_to_your_account">Comezar sesión na súa conta</string>
<string name="nearby_location_has_not_changed">A localización non cambiou.</string> <string name="nearby_location_has_not_changed">A localización non cambiou.</string>
<string name="nearby_location_not_available">A localización non está dispoñible.</string> <string name="nearby_location_not_available">A localización non está dispoñible.</string>
<string name="location_permission_rationale_nearby">Precísase permiso para amosar unha lista de lugares preto de aquí</string> <string name="location_permission_rationale_nearby">Precísase permiso para amosar unha lista de lugares preto de aquí</string>

View file

@ -198,12 +198,13 @@
<string name="error_while_cache">चित्र कैशिंग करते समय त्रुटि</string> <string name="error_while_cache">चित्र कैशिंग करते समय त्रुटि</string>
<string name="title_info">फ़ाइल के लिए एक अद्वितीय वर्णनात्मक शीर्षक, जो एक फ़ाइल नाम के रूप में काम करेगा। आप रिक्त स्थान के साथ सादे भाषा का उपयोग कर सकते हैं। फ़ाइल विस्तार शामिल न करें</string> <string name="title_info">फ़ाइल के लिए एक अद्वितीय वर्णनात्मक शीर्षक, जो एक फ़ाइल नाम के रूप में काम करेगा। आप रिक्त स्थान के साथ सादे भाषा का उपयोग कर सकते हैं। फ़ाइल विस्तार शामिल न करें</string>
<string name="description_info">कृपया मीडिया जितना संभव हो उतना बताएं: यह कहां लिया गया? यह क्या दिखाता है? संदर्भ क्या है? कृपया वस्तुओं या व्यक्तियों का वर्णन करें। ऐसी जानकारी का खुलासा करें जिसे आसानी से अनुमानित नहीं किया जा सकता, उदाहरण के लिए दिन का समय यदि यह परिदृश्य है। अगर मीडिया कुछ असामान्य दिखाता है, तो कृपया बताएं कि इसे क्या असामान्य बनाता है।</string> <string name="description_info">कृपया मीडिया जितना संभव हो उतना बताएं: यह कहां लिया गया? यह क्या दिखाता है? संदर्भ क्या है? कृपया वस्तुओं या व्यक्तियों का वर्णन करें। ऐसी जानकारी का खुलासा करें जिसे आसानी से अनुमानित नहीं किया जा सकता, उदाहरण के लिए दिन का समय यदि यह परिदृश्य है। अगर मीडिया कुछ असामान्य दिखाता है, तो कृपया बताएं कि इसे क्या असामान्य बनाता है।</string>
<string name="upload_image_too_dark">यह चित्र बहुत गहरा है, क्या आप वाकई इसे अपलोड करना चाहते हैं? विकिमीडिया कॉमन्स केवल विश्वकोषीय मूल्य वाले चित्रों के लिए है।</string>
<string name="give_permission">अनुमति दें</string> <string name="give_permission">अनुमति दें</string>
<string name="use_external_storage">बाहरी स्टॉरज का पृयोग करे।</string> <string name="use_external_storage">बाहरी स्टॉरज का पृयोग करे।</string>
<string name="use_external_storage_summary">आप अपने डिवाइस के इन-ऐप कैमरा से ली गई तस्वीरों को सहेजें।</string> <string name="use_external_storage_summary">आप अपने डिवाइस के इन-ऐप कैमरा से ली गई तस्वीरों को सहेजें।</string>
<string name="login_to_your_account">अपने खाते में प्रवेश करें</string>
<string name="send_log_file">लॉग फाइल भेजें</string> <string name="send_log_file">लॉग फाइल भेजें</string>
<string name="send_log_file_description">डेवेलपर्स को लॉग फाइल ई-मेल से भेजें</string> <string name="send_log_file_description">डेवेलपर्स को लॉग फाइल ई-मेल से भेजें</string>
<string name="login_to_your_account">अपने खाते में प्रवेश करें</string>
<string name="nearby_location_has_not_changed">स्थान परिवर्तन नहीं हुआ।</string> <string name="nearby_location_has_not_changed">स्थान परिवर्तन नहीं हुआ।</string>
<string name="nearby_location_not_available">स्थान उपलब्ध नहीं।</string> <string name="nearby_location_not_available">स्थान उपलब्ध नहीं।</string>
<string name="location_permission_rationale_nearby">आसपास के स्थान दिखाने के लिए अनुमति चाहिए</string> <string name="location_permission_rationale_nearby">आसपास के स्थान दिखाने के लिए अनुमति चाहिए</string>

View file

@ -196,9 +196,9 @@
<string name="give_permission">Engedély adása</string> <string name="give_permission">Engedély adása</string>
<string name="use_external_storage">Külső tárhely használata</string> <string name="use_external_storage">Külső tárhely használata</string>
<string name="use_external_storage_summary">Az alkalmazáson belüli kamerával készült képek mentése az eszközre</string> <string name="use_external_storage_summary">Az alkalmazáson belüli kamerával készült képek mentése az eszközre</string>
<string name="login_to_your_account">Bejelentkezés a fiókodba</string>
<string name="send_log_file">Naplófájlok küldése</string> <string name="send_log_file">Naplófájlok küldése</string>
<string name="send_log_file_description">Naplófájlok küldése e-mailben a fejlesztőknek</string> <string name="send_log_file_description">Naplófájlok küldése e-mailben a fejlesztőknek</string>
<string name="login_to_your_account">Bejelentkezés a fiókodba</string>
<string name="nearby_location_has_not_changed">A hely nem változott.</string> <string name="nearby_location_has_not_changed">A hely nem változott.</string>
<string name="nearby_location_not_available">A hely nem érhető el.</string> <string name="nearby_location_not_available">A hely nem érhető el.</string>
</resources> </resources>

View file

@ -54,16 +54,16 @@
<string name="gps_disabled">GPS er óvirkt í tækinu þínu. Viltu virkja það?</string> <string name="gps_disabled">GPS er óvirkt í tækinu þínu. Viltu virkja það?</string>
<string name="enable_gps">Virkja GPS</string> <string name="enable_gps">Virkja GPS</string>
<string name="contributions_subtitle_zero">Engar innsendingar ennþá</string> <string name="contributions_subtitle_zero">Engar innsendingar ennþá</string>
<plurals name="contributions_subtitle" fuzzy="true"> <plurals name="contributions_subtitle">
<item quantity="zero">\@string/contributions_subtitle_zero</item> <item quantity="zero">\@string/contributions_subtitle_zero</item>
<item quantity="one">%1$d innsending</item> <item quantity="one">%1$d innsending</item>
<item quantity="other">%1$d innsendingar</item> <item quantity="other">%1$d innsendingar</item>
</plurals> </plurals>
<plurals name="starting_multiple_uploads" fuzzy="true"> <plurals name="starting_multiple_uploads">
<item quantity="one">Byrja %1$d innsendingu</item> <item quantity="one">Byrja %1$d innsendingu</item>
<item quantity="other">Byrja %1$d innsendingar</item> <item quantity="other">Byrja %1$d innsendingar</item>
</plurals> </plurals>
<plurals name="multiple_uploads_title" fuzzy="true"> <plurals name="multiple_uploads_title">
<item quantity="one">%1$d innsending</item> <item quantity="one">%1$d innsending</item>
<item quantity="other">%1$d innsendingar</item> <item quantity="other">%1$d innsendingar</item>
</plurals> </plurals>
@ -199,19 +199,22 @@
<string name="error_while_cache">Villa kom upp í skyndiminni mynda</string> <string name="error_while_cache">Villa kom upp í skyndiminni mynda</string>
<string name="title_info">Einstakur og lýsandi titill, sem mun verða skráarheiti. Þú mátt nota einfaldan texta með bilum. Ekki hafa með neina skráarendingu</string> <string name="title_info">Einstakur og lýsandi titill, sem mun verða skráarheiti. Þú mátt nota einfaldan texta með bilum. Ekki hafa með neina skráarendingu</string>
<string name="description_info">Lýstu gögnunum eins vel og auðið er: Hvar er myndin tekin? Hvað sýnir hún? Hvert er samhengið? Lýstu fólki og fyrirbærum. Gefðu upp þær upplýsingar sem ekki er auðvelt að giska á, til dæmis á hvaða tíma dags myndin er tekin ef hún sýnir landslag. Ef gögnin sýna eitthvað óvenjulegt, útskýrðu þá hvað það er sem sé sérstakt.</string> <string name="description_info">Lýstu gögnunum eins vel og auðið er: Hvar er myndin tekin? Hvað sýnir hún? Hvert er samhengið? Lýstu fólki og fyrirbærum. Gefðu upp þær upplýsingar sem ekki er auðvelt að giska á, til dæmis á hvaða tíma dags myndin er tekin ef hún sýnir landslag. Ef gögnin sýna eitthvað óvenjulegt, útskýrðu þá hvað það er sem sé sérstakt.</string>
<string name="upload_image_too_dark">Þessi mynd er of dökk, ertu viss um að þú viljir senda hana inn? Wikimedia Commons er aðeins fyrir myndir sem hafa eitthvað fræðslugildi.</string>
<string name="upload_image_blurry">Þessi mynd er ekki skörp, ertu viss um að þú viljir senda hana inn? Wikimedia Commons er aðeins fyrir myndir sem hafa eitthvað fræðslugildi.</string>
<string name="give_permission">Gefa heimild</string> <string name="give_permission">Gefa heimild</string>
<string name="use_external_storage">Nota ytri gagnageymslu</string> <string name="use_external_storage">Nota ytri gagnageymslu</string>
<string name="use_external_storage_summary">Vistaðu myndir sem teknar hafa verið með innbyggðu myndavélinni í tækinu þínu</string> <string name="use_external_storage_summary">Vistaðu myndir sem teknar hafa verið með innbyggðu myndavélinni í tækinu þínu</string>
<string name="login_to_your_account">Skrá inn á aðganginn þinn</string>
<string name="send_log_file">Senda atvikaskrá</string> <string name="send_log_file">Senda atvikaskrá</string>
<string name="send_log_file_description">Senda atvikaskrá til forritaranna með tölvupósti</string> <string name="send_log_file_description">Senda atvikaskrá til forritaranna með tölvupósti</string>
<string name="login_to_your_account">Skrá inn á aðganginn þinn</string>
<string name="nearby_location_has_not_changed">Staðsetning hefur ekki breyst.</string> <string name="nearby_location_has_not_changed">Staðsetning hefur ekki breyst.</string>
<string name="nearby_location_not_available">Staðsetning ekki tiltæk.</string> <string name="nearby_location_not_available">Staðsetning ekki tiltæk.</string>
<string name="location_permission_rationale_nearby">Heimild þarf til að birta lista yfir staði í nágrenninu</string> <string name="location_permission_rationale_nearby">Heimild þarf til að birta lista yfir staði í nágrenninu</string>
<string name="get_directions">FÁ LEIÐSÖGN</string> <string name="get_directions">FÁ LEIÐSÖGN</string>
<string name="read_article">LESA GREIN</string> <string name="read_article">LESA GREIN</string>
<string name="notifications_welcome" fuzzy="true">Velkomin á Wikimedia Commons, %1$s! Við erum ánægð með að þú skulir vera hérna.</string> <string name="notifications_welcome">Velkomin á Wikimedia Commons, %1$s! Við erum ánægð með að þú skulir vera hérna.</string>
<string name="notifications_talk_page_message">%1$s skildi eftir skilaboð á spjallsíðunni þinni</string> <string name="notifications_talk_page_message">%1$s skildi eftir skilaboð á spjallsíðunni þinni</string>
<string name="notifications_thank_you_edit">Takk fyrir að hafa gert breytingar</string> <string name="notifications_thank_you_edit">Takk fyrir að hafa gert breytingar</string>
<string name="notifications_mention" fuzzy="true">%1$s minntist á þig á %2$s.</string> <string name="notifications_mention">%1$s minntist á þig á %2$s.</string>
<string name="toggle_view_button">Víxla sýn</string>
</resources> </resources>

View file

@ -201,9 +201,9 @@
<string name="give_permission">לתת הרשאה</string> <string name="give_permission">לתת הרשאה</string>
<string name="use_external_storage">להשתמש באחסון חיצוני</string> <string name="use_external_storage">להשתמש באחסון חיצוני</string>
<string name="use_external_storage_summary">שמירת תמונות שצולמו באמצעות מצלמה בתוך היישום במכשיר שלך</string> <string name="use_external_storage_summary">שמירת תמונות שצולמו באמצעות מצלמה בתוך היישום במכשיר שלך</string>
<string name="login_to_your_account">כניסה לחשבון שלך</string>
<string name="send_log_file">שליחת קובץ יומן</string> <string name="send_log_file">שליחת קובץ יומן</string>
<string name="send_log_file_description">שליחת קובץ יומן למפתחים בדואר אלקטרוני</string> <string name="send_log_file_description">שליחת קובץ יומן למפתחים בדואר אלקטרוני</string>
<string name="login_to_your_account">כניסה לחשבון שלך</string>
<string name="nearby_location_has_not_changed">המיקום לא השתנה.</string> <string name="nearby_location_has_not_changed">המיקום לא השתנה.</string>
<string name="nearby_location_not_available">המיקום אינו זמין.</string> <string name="nearby_location_not_available">המיקום אינו זמין.</string>
<string name="location_permission_rationale_nearby">נדרשת הרשאה כדי להציג רשימה של מקומות בסביבה</string> <string name="location_permission_rationale_nearby">נדרשת הרשאה כדי להציג רשימה של מקומות בסביבה</string>

View file

@ -41,6 +41,7 @@
<string name="login_failed_password">ログインできません - パスワードを確認してください</string> <string name="login_failed_password">ログインできません - パスワードを確認してください</string>
<string name="login_failed_throttled">失敗した回数が多すぎます。数分でもう一度お試しください。</string> <string name="login_failed_throttled">失敗した回数が多すぎます。数分でもう一度お試しください。</string>
<string name="login_failed_blocked">申し訳ありませんが、この利用者はコモンズでブロックされています。</string> <string name="login_failed_blocked">申し訳ありませんが、この利用者はコモンズでブロックされています。</string>
<string name="login_failed_2fa_needed">2 要素認証コードを提供する必要があります。</string>
<string name="login_failed_generic">ログイン失敗</string> <string name="login_failed_generic">ログイン失敗</string>
<string name="share_upload_button">アップロード</string> <string name="share_upload_button">アップロード</string>
<string name="multiple_share_base_title">このセットに名前をつけてください</string> <string name="multiple_share_base_title">このセットに名前をつけてください</string>
@ -150,8 +151,10 @@
<string name="become_a_tester_description">Google Playのベータ版チャンネルにオプトインして、新機能やバグ修正プログラムに早期にアクセス</string> <string name="become_a_tester_description">Google Playのベータ版チャンネルにオプトインして、新機能やバグ修正プログラムに早期にアクセス</string>
<string name="use_wikidata">ウィキデータを使用してください</string> <string name="use_wikidata">ウィキデータを使用してください</string>
<string name="use_wikidata_summary">(警告:これを無効にすると、モバイルデータを大量に消費する可能性があります)</string> <string name="use_wikidata_summary">(警告:これを無効にすると、モバイルデータを大量に消費する可能性があります)</string>
<string name="_2fa_code">2FA コード</string>
<string name="number_of_uploads">最近のアップロードファイルに表示する最大件数</string> <string name="number_of_uploads">最近のアップロードファイルに表示する最大件数</string>
<string name="maximum_limit">最大限</string> <string name="maximum_limit">最大限</string>
<string name="maximum_limit_alert">500 以上の項目を表示できません</string>
<string name="set_limit">最近のアップロードファイルに表示する最大件数</string> <string name="set_limit">最近のアップロードファイルに表示する最大件数</string>
<string name="login_failed_2fa_not_supported">2段階認証は現在サポートされていません。</string> <string name="login_failed_2fa_not_supported">2段階認証は現在サポートされていません。</string>
<string name="logout_verification">ログアウトしてもよろしいですか?</string> <string name="logout_verification">ログアウトしてもよろしいですか?</string>
@ -186,9 +189,9 @@
<string name="give_permission">権限を取得</string> <string name="give_permission">権限を取得</string>
<string name="use_external_storage">外部ストレージを使用</string> <string name="use_external_storage">外部ストレージを使用</string>
<string name="use_external_storage_summary">アプリ内のカメラで撮影した写真を端末に保存する</string> <string name="use_external_storage_summary">アプリ内のカメラで撮影した写真を端末に保存する</string>
<string name="login_to_your_account">自分のアカウントにログイン</string>
<string name="send_log_file">ログファイルを送信する</string> <string name="send_log_file">ログファイルを送信する</string>
<string name="send_log_file_description">メールで開発者にログファイルを送信する</string> <string name="send_log_file_description">メールで開発者にログファイルを送信する</string>
<string name="login_to_your_account">自分のアカウントにログイン</string>
<string name="nearby_location_has_not_changed">場所は変更されていません。</string> <string name="nearby_location_has_not_changed">場所は変更されていません。</string>
<string name="nearby_location_not_available">位置が無効です。</string> <string name="nearby_location_not_available">位置が無効です。</string>
</resources> </resources>

View file

@ -202,9 +202,9 @@
<string name="give_permission">Mudd tasiregt</string> <string name="give_permission">Mudd tasiregt</string>
<string name="use_external_storage">Seqdec asekles azɣaray</string> <string name="use_external_storage">Seqdec asekles azɣaray</string>
<string name="use_external_storage_summary">Sekles tiwlafin yettwaṭṭfen s tkamirat yellan deg ibenk</string> <string name="use_external_storage_summary">Sekles tiwlafin yettwaṭṭfen s tkamirat yellan deg ibenk</string>
<string name="login_to_your_account">Qqen ar umiḍan-ik</string>
<string name="send_log_file">Azen afaylu n uɣmis</string> <string name="send_log_file">Azen afaylu n uɣmis</string>
<string name="send_log_file_description">Azen afaylu n uɣmis i yinermisen s yimayl</string> <string name="send_log_file_description">Azen afaylu n uɣmis i yinermisen s yimayl</string>
<string name="login_to_your_account">Qqen ar umiḍan-ik</string>
<string name="nearby_location_has_not_changed">Adeg ur ibeddel ara.</string> <string name="nearby_location_has_not_changed">Adeg ur ibeddel ara.</string>
<string name="nearby_location_not_available">Ulac adeg</string> <string name="nearby_location_not_available">Ulac adeg</string>
<string name="location_permission_rationale_nearby">Ilaq usireg i uskan tabdart n wadigen iqerben</string> <string name="location_permission_rationale_nearby">Ilaq usireg i uskan tabdart n wadigen iqerben</string>

View file

@ -197,9 +197,9 @@
<string name="give_permission">권한 부여</string> <string name="give_permission">권한 부여</string>
<string name="use_external_storage">외부 저장소 사용하기</string> <string name="use_external_storage">외부 저장소 사용하기</string>
<string name="use_external_storage_summary">장치의 인앱 카메라로 찍은 사진 저장하기</string> <string name="use_external_storage_summary">장치의 인앱 카메라로 찍은 사진 저장하기</string>
<string name="login_to_your_account">자신의 계정으로 로그인</string>
<string name="send_log_file">로그 파일 보내기</string> <string name="send_log_file">로그 파일 보내기</string>
<string name="send_log_file_description">이메일로 개발자에게 로그 파일 보내기</string> <string name="send_log_file_description">이메일로 개발자에게 로그 파일 보내기</string>
<string name="login_to_your_account">자신의 계정으로 로그인</string>
<string name="nearby_location_has_not_changed">위치가 변경되지 않았습니다.</string> <string name="nearby_location_has_not_changed">위치가 변경되지 않았습니다.</string>
<string name="nearby_location_not_available">위치를 사용할 수 없습니다.</string> <string name="nearby_location_not_available">위치를 사용할 수 없습니다.</string>
<string name="location_permission_rationale_nearby">주변 장소의 목록을 표시하기 위한 권한이 필요합니다.</string> <string name="location_permission_rationale_nearby">주변 장소의 목록을 표시하기 위한 권한이 필요합니다.</string>

View file

@ -189,9 +189,9 @@
<string name="give_permission">Autorisatioun ginn</string> <string name="give_permission">Autorisatioun ginn</string>
<string name="use_external_storage">Externe Späicher benotzen</string> <string name="use_external_storage">Externe Späicher benotzen</string>
<string name="use_external_storage_summary">Biller späicheren déi mat der in-app Kamera vun Ärem Apparat gemaach goufen</string> <string name="use_external_storage_summary">Biller späicheren déi mat der in-app Kamera vun Ärem Apparat gemaach goufen</string>
<string name="login_to_your_account">An Äre Benotzerkont aloggen</string>
<string name="send_log_file">Log-Fichier schécken</string> <string name="send_log_file">Log-Fichier schécken</string>
<string name="send_log_file_description">Log-Fichier per E-Mail un d\'Entwéckler schécken</string> <string name="send_log_file_description">Log-Fichier per E-Mail un d\'Entwéckler schécken</string>
<string name="login_to_your_account">An Äre Benotzerkont aloggen</string>
<string name="nearby_location_has_not_changed">De Plaz huet net geännert.</string> <string name="nearby_location_has_not_changed">De Plaz huet net geännert.</string>
<string name="nearby_location_not_available">Plaz ass net disponibel.</string> <string name="nearby_location_not_available">Plaz ass net disponibel.</string>
<string name="read_article">ARTIKEL LIESEN</string> <string name="read_article">ARTIKEL LIESEN</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Грешка при меѓускладирање на сликите</string> <string name="error_while_cache">Грешка при меѓускладирање на сликите</string>
<string name="title_info">Краток и единствен наслов на податотеката, кој ќе служи како нејзин назив. Можете да користите прост јазик со меѓупростор, но не пишувајте ја податотечната наставка</string> <string name="title_info">Краток и единствен наслов на податотеката, кој ќе служи како нејзин назив. Можете да користите прост јазик со меѓупростор, но не пишувајте ја податотечната наставка</string>
<string name="description_info">Објаснете ја податотеката што подобро можете: Каде е направена? Што е прикажано на неа? Кој е контекстот? Опишете ги предметите, објектите и личностите. Дајте сознанија што не можат лесно да се погодат, како на пр. време од денот ако се работи за природен предел. Ако на неа е претставено нешто необично, објаснете зошто прикажаното е необично.</string> <string name="description_info">Објаснете ја податотеката што подобро можете: Каде е направена? Што е прикажано на неа? Кој е контекстот? Опишете ги предметите, објектите и личностите. Дајте сознанија што не можат лесно да се погодат, како на пр. време од денот ако се работи за природен предел. Ако на неа е претставено нешто необично, објаснете зошто прикажаното е необично.</string>
<string name="upload_image_too_dark">Сликата ви е претемна. Дали сигурно сакате да ја подигнете? Ризницата е посветена само на слики со енциклопедиска вредност.</string>
<string name="upload_image_blurry">Сликата ви е матна. Дали сигурно сакате да ја подигнете? Ризницата е посветена само на слики со енциклопедиска вредност.</string>
<string name="give_permission">Дај дозвола</string> <string name="give_permission">Дај дозвола</string>
<string name="use_external_storage">Користи надворешен склад</string> <string name="use_external_storage">Користи надворешен склад</string>
<string name="use_external_storage_summary">Зачувување на направените слики во прилогот со камерата на вашиот уред</string> <string name="use_external_storage_summary">Зачувување на направените слики во прилогот со камерата на вашиот уред</string>
<string name="login_to_your_account">Најавете се со вашата сметка</string>
<string name="send_log_file">Испрати дневничка податотека</string> <string name="send_log_file">Испрати дневничка податотека</string>
<string name="send_log_file_description">Испрати дневничка податотека на разработувачите по е-пошта</string> <string name="send_log_file_description">Испрати дневничка податотека на разработувачите по е-пошта</string>
<string name="login_to_your_account">Најавете се со вашата сметка</string>
<string name="nearby_location_has_not_changed">Местоположбата не е сменета.</string> <string name="nearby_location_has_not_changed">Местоположбата не е сменета.</string>
<string name="nearby_location_not_available">Местоположбата е недостапна.</string> <string name="nearby_location_not_available">Местоположбата е недостапна.</string>
<string name="location_permission_rationale_nearby">Се бара дозвола за приказ на список на околни места</string> <string name="location_permission_rationale_nearby">Се бара дозвола за приказ на список на околни места</string>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">कॉमन्स</string> <string name="app_name">कॉमन्स</string>
<string name="menu_settings">मांडण्या</string> <string name="menu_settings">सेटिंग्स</string>
<string name="username">सदस्यनाव</string> <string name="username">सदस्यनाव</string>
<string name="password">परवलीचा शब्द(पासवर्ड)</string> <string name="password">परवलीचा शब्द(पासवर्ड)</string>
<string name="login">सनोंद-प्रवेश करा</string> <string name="login">सनोंद-प्रवेश करा</string>
@ -20,12 +20,12 @@
<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>
<string name="upload_failed_notification_subtitle">बघण्यास अलगद टपली मारा</string> <string name="upload_failed_notification_subtitle">बघण्यास अलगद टपली मारा</string>
<plurals name="uploads_pending_notification_indicator" fuzzy="true"> <plurals name="uploads_pending_notification_indicator">
<item quantity="one">१ संचिका अपभारीत आहे</item> <item quantity="one">१ संचिका अपभारीत होत आहे</item>
<item quantity="other">%1$d संचिका अपभारीत आहे</item> <item quantity="other">%1$d संचिका अपभारीत होत आहे</item>
</plurals> </plurals>
<string name="title_activity_contributions">माझी अपभारणे</string> <string name="title_activity_contributions">माझी अपभारणे</string>
<string name="contribution_state_queued">प्रतिक्षावलीत ठेवल</string> <string name="contribution_state_queued">रांगेत आह</string>
<string name="contribution_state_failed">अपयशी</string> <string name="contribution_state_failed">अपयशी</string>
<string name="contribution_state_in_progress">%1$d%% पूर्ण</string> <string name="contribution_state_in_progress">%1$d%% पूर्ण</string>
<string name="contribution_state_starting">अपभारण करीत आहे</string> <string name="contribution_state_starting">अपभारण करीत आहे</string>
@ -41,7 +41,7 @@
<string name="login_failed_username">सनोंद प्रवेश अशक्य - कृपया आपले सदस्यनाव तपासा</string> <string name="login_failed_username">सनोंद प्रवेश अशक्य - कृपया आपले सदस्यनाव तपासा</string>
<string name="login_failed_password">सनोंद प्रवेश अशक्य - कृपया आपला परवलीचा शब्द तपासा</string> <string name="login_failed_password">सनोंद प्रवेश अशक्य - कृपया आपला परवलीचा शब्द तपासा</string>
<string name="login_failed_throttled">अनेक अयशस्वी प्रयत्न.काही मिनीटांनंतर पुन्हा प्रयत्न करा.</string> <string name="login_failed_throttled">अनेक अयशस्वी प्रयत्न.काही मिनीटांनंतर पुन्हा प्रयत्न करा.</string>
<string name="login_failed_blocked">माफ करा,कॉमन्सवर हा सदस्य प्रतिबंधित आहे</string> <string name="login_failed_blocked">माफ करा, कॉमन्सवर हा सदस्य प्रतिबंधित आहे</string>
<string name="login_failed_2fa_needed">आपण आपल्या दोन कारक प्रमाणिकरण कोड प्रदान करणे आवश्यक आहे.</string> <string name="login_failed_2fa_needed">आपण आपल्या दोन कारक प्रमाणिकरण कोड प्रदान करणे आवश्यक आहे.</string>
<string name="login_failed_generic">सनोंद प्रवेश अयशस्वी!</string> <string name="login_failed_generic">सनोंद प्रवेश अयशस्वी!</string>
<string name="share_upload_button">अपभारण करा</string> <string name="share_upload_button">अपभारण करा</string>
@ -50,36 +50,52 @@
<string name="menu_upload_single">अपभारण करा</string> <string name="menu_upload_single">अपभारण करा</string>
<string name="categories_search_text_hint">वर्ग शोधा</string> <string name="categories_search_text_hint">वर्ग शोधा</string>
<string name="menu_save_categories">जतन करा</string> <string name="menu_save_categories">जतन करा</string>
<plurals name="contributions_subtitle" fuzzy="true"> <string name="refresh_button">ताजेतवाने करा</string>
<string name="gps_disabled">आपल्या मोबाईलचे गिपीएस बंद आहे, तुम्हांला ते चालू करायचे आहे का?</string>
<string name="enable_gps">जिपीएस चालू करा</string>
<string name="contributions_subtitle_zero">अद्याप काहीही चढवलेले नाही</string>
<plurals name="contributions_subtitle">
<item quantity="zero">अद्याप अपभारणे नाहीत</item> <item quantity="zero">अद्याप अपभारणे नाहीत</item>
<item quantity="one">एक अपभारण</item> <item quantity="one">एक अपभारण</item>
<item quantity="other">%1$d अपभारणे</item> <item quantity="other">%1$d अपभारणे</item>
</plurals> </plurals>
<plurals name="starting_multiple_uploads" fuzzy="true"> <plurals name="starting_multiple_uploads">
<item quantity="one">१ अपभारण सुरू करीत आहे upload</item> <item quantity="one">१ अपभारण सुरू करीत आहे upload</item>
<item quantity="other">%1$d अपभारणे सुरू करीत आहे</item> <item quantity="other">%1$d अपभारणे सुरू करीत आहे</item>
</plurals> </plurals>
<plurals name="multiple_uploads_title" fuzzy="true"> <plurals name="multiple_uploads_title">
<item quantity="one">१ अपभारण</item> <item quantity="one">१ अपभारण</item>
<item quantity="other">%1$d अपभारणे</item> <item quantity="other">%1$d अपभारणे</item>
</plurals> </plurals>
<string name="categories_not_found">%1$s शी जुळणारे कोणतेच वर्ग सापडले नाहीत</string> <string name="categories_not_found">%1$s शी जुळणारे कोणतेच वर्ग सापडले नाहीत</string>
<string name="categories_skip_explanation" fuzzy="true">विकिमिडिया कॉमन्सवर आपल्या संचिकांना शोधणे सोपी जाण्यासाठी त्यांना वर्ग जोडा.\n\nवर्ग जोडण्यास टंकन सुरू करा.\nही पायरी चुकविण्यास या संदेशावर अलगद टिचका (किंवा बॅक कळ टिचका)</string> <string name="categories_skip_explanation">विकिमिडिया कॉमन्सवर आपल्या संचिकांना शोधणे सोपी जाण्यासाठी त्यांना वर्ग जोडा.\n\nवर्ग जोडण्यास टंकन सुरू करा.\nही पायरी चुकविण्यास या संदेशावर अलगद टिचका (किंवा बॅक कळ टिचका)</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_signup">नोंदणी करा</string>
<string name="menu_about">आमच्याबद्दल</string> <string name="menu_about">आमच्याबद्दल</string>
<string name="about_license">विकीमिडीया कॉमन्स अॅप हे एक मुक्तस्त्रोत अॅप असून ते विकीमिडीया समुदायातील स्वयंसेवकांनी आणि अनुदानित सदस्यांकडून निर्माण आणि सांभाळले जाते. विकीमिडीया फ़ांउंडेशनचा ह्या अॅपच्या निर्मिती,सांभाळामध्ये सहभाग नाही.</string>
<string name="about_improve">नव्याने तयार करा &lt;a href=\"https://github.com/commons-app/apps-android-commons/issues\"&gt;GitHub issue&lt;/a&gt; त्रुटी अहवालांसाठी आणि सुचनांसाठी.</string>
<string name="about_privacy_policy">&lt;a href=\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\"&gt;Privacy policy&lt;/a&gt;</string>
<string name="about_credits">&lt;a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\"&gt;Credits&lt;/a&gt;</string>
<string name="title_activity_about">च्या विषयी</string> <string name="title_activity_about">च्या विषयी</string>
<string name="menu_feedback">प्रतिसाद पाठवा (विपत्राद्वारे)</string> <string name="menu_feedback">प्रतिसाद पाठवा (विपत्राद्वारे)</string>
<string name="no_email_client">कोणतेही ईमेल क्लायंट स्थापित नाहीत</string>
<string name="provider_categories">अलीकडे वापरलेले वर्ग</string> <string name="provider_categories">अलीकडे वापरलेले वर्ग</string>
<string name="waiting_first_sync">प्रथम संकालनाची प्रतीक्षा करीत आहे ...</string>
<string name="no_uploads_yet">आपण अद्याप काहीच चित्रे अपभारीत केली नाहीत.</string> <string name="no_uploads_yet">आपण अद्याप काहीच चित्रे अपभारीत केली नाहीत.</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="share_license_summary">ही संचिका %1$s या परवान्यांतर्गत राहील</string> <string name="share_license_summary">ही संचिका %1$s या परवान्यांतर्गत राहील</string>
<string name="media_upload_policy">हे चित्र इथे चढवत असताना, मी हे घोषीत करतो की हे माझेच काम आहे आणि ह्या कामावर इतर कुणाचाही प्रताधिकार नाही तसेच हे सेल्फ़ी नाहीये, म्हणून हे काम ह्या संकेतांचे पालन करेल &lt;a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\"&gt;Wikimedia Commons policies&lt;/a&gt;.</string>
<string name="menu_download">अधिभारण करा</string> <string name="menu_download">अधिभारण करा</string>
<string name="preference_license">परवाना</string> <string name="preference_license">परवाना</string>
<string name="use_previous">मागील शीर्षक/वर्णन वापरा</string> <string name="use_previous">मागील शीर्षक/वर्णन वापरा</string>
<string name="allow_gps">आपोआप सध्याचे स्थान मिळवा</string> <string name="allow_gps">आपोआप सध्याचे स्थान मिळवा</string>
<string name="allow_gps_summary">जर छायाचित्राला जिओटॅग नसल्यास तुम्ही तुमच्या स्थानाची निश्चिती करा जेणे करुन संबंधीत वर्ग सुचवले जातील</string>
<string name="preference_theme">रात्रीच्या वेळेच्या व्यवस्था</string>
<string name="preference_theme_summary">गडद त्वचा वापरा</string>
<string name="license_name_cc_by_sa_four"> Attribution-ShareAlike 3.0</string>
<string name="license_name_cc_by_four"> Attribution 3.0</string>
<string name="license_name_cc_by_sa"> Attribution-ShareAlike 3.0</string> <string name="license_name_cc_by_sa"> Attribution-ShareAlike 3.0</string>
<string name="license_name_cc_by"> Attribution 3.0</string> <string name="license_name_cc_by"> Attribution 3.0</string>
<string name="license_name_cc0">CC0</string> <string name="license_name_cc0">CC0</string>
@ -103,10 +119,10 @@
<string name="tutorial_2_text">कृपया निव्वळ आपण घेतलेल्या किंवा तयार केलेल्या चित्रांचेच अपभारण करा:</string> <string name="tutorial_2_text">कृपया निव्वळ आपण घेतलेल्या किंवा तयार केलेल्या चित्रांचेच अपभारण करा:</string>
<string name="tutorial_2_subtext">- नैसर्गिक गोष्टी (फुले, प्राणी, पर्वत)\n- नित्योपयोगी गोष्टी (दुचाकी, रेल्वे स्थानके)\n- प्रसिद्ध व्यक्ति (आपले महापौर, आपणास भेटलेले ऑलिंपिक खेळाडू)</string> <string name="tutorial_2_subtext">- नैसर्गिक गोष्टी (फुले, प्राणी, पर्वत)\n- नित्योपयोगी गोष्टी (दुचाकी, रेल्वे स्थानके)\n- प्रसिद्ध व्यक्ति (आपले महापौर, आपणास भेटलेले ऑलिंपिक खेळाडू)</string>
<string name="tutorial_3_text">कृपया अपभारण करू \'\'\'नका\'\'\':</string> <string name="tutorial_3_text">कृपया अपभारण करू \'\'\'नका\'\'\':</string>
<string name="tutorial_3_subtext">-आपल्या किंवा मित्रांच्या सेल्फी\n-आपण आंतरजाल (इंटरनेट) वरुन अधिभारण केलेली चित्रे\n-प्रोप्रायटरी अप्सचे स्क्रिनशॉट</string> <string name="tutorial_3_subtext">-आपल्या किंवा मित्रांच्या सेल्फी\n-आपण आंतरजाल (इंटरनेट) वरुन अधिभारण केलेली चित्रे\n-प्रोप्रायटरी अप्सचे स्क्रिनशॉट</string>
<string name="tutorial_4_text">उदाहरणादाखल अपभारण:</string> <string name="tutorial_4_text">उदाहरणादाखल अपभारण:</string>
<string name="tutorial_4_subtext" fuzzy="true">- शीर्षक: Sydney Opera House\n- वर्णन: Sydney Opera House as viewed from across the bay\n- वर्ग: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string> <string name="tutorial_4_subtext">- शीर्षक: Sydney Opera House\n- वर्णन: Sydney Opera House as viewed from across the bay\n- वर्ग: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote views</string>
<string name="welcome_wikipedia_text">आपली चित्रे सहभागा. विकिपीडियावरील लेखात जीवंतपणा आणा!</string> <string name="welcome_wikipedia_text">आपली चित्रे जोडा. विकिपीडियावरील लेखात जीवंतपणा आणा!</string>
<string name="welcome_wikipedia_subtext">विकिपीडियावरची चित्रे विकिमिडिया कॉमन्सवरुन येतात.</string> <string name="welcome_wikipedia_subtext">विकिपीडियावरची चित्रे विकिमिडिया कॉमन्सवरुन येतात.</string>
<string name="welcome_copyright_text">जगातल्या अनेक लोकांना आपल्या चित्राद्वारे शिकता येते.</string> <string name="welcome_copyright_text">जगातल्या अनेक लोकांना आपल्या चित्राद्वारे शिकता येते.</string>
<string name="welcome_copyright_subtext">आपण इंटरनेटवर शोधलेले प्रताधिकारीत साहित्य टाळा तसेच भित्तीपत्रकांची चित्रे, पुस्तकांचे कव्हर इत्यादी.</string> <string name="welcome_copyright_subtext">आपण इंटरनेटवर शोधलेले प्रताधिकारीत साहित्य टाळा तसेच भित्तीपत्रकांची चित्रे, पुस्तकांचे कव्हर इत्यादी.</string>
@ -118,12 +134,87 @@
<string name="detail_description_empty">वर्णन नाही.</string> <string name="detail_description_empty">वर्णन नाही.</string>
<string name="detail_license_empty">अनोळखी परवाना</string> <string name="detail_license_empty">अनोळखी परवाना</string>
<string name="menu_refresh">ताजेतवाने करा</string> <string name="menu_refresh">ताजेतवाने करा</string>
<string name="read_storage_permission_rationale">परवानगी आवश्यक:बाह्य भंडारण वाचन. याशिवाय अॲप काम करू शकत नाही.</string> <string name="read_storage_permission_rationale">परवानगी आवश्यक:बाह्य भंडारण वाचन. याशिवाय अॅप काम करू शकत नाही.</string>
<string name="write_storage_permission_rationale">परवानगी आवश्यक:बाह्य भंडारण वाचन. याशिवाय अॅप काम करू शकत नाही.</string>
<string name="location_permission_rationale">ऐच्छिक परवानगी:वर्ग सुचवण्यांसाठी सध्याचे स्थान मिळवा</string> <string name="location_permission_rationale">ऐच्छिक परवानगी:वर्ग सुचवण्यांसाठी सध्याचे स्थान मिळवा</string>
<string name="ok">ठीक आहे</string> <string name="ok">ठीक आहे</string>
<string name="title_activity_nearby">जवळपासची स्थाने</string> <string name="title_activity_nearby">जवळपासची स्थाने</string>
<string name="no_nearby">आसपास काहीही सापडले नाही</string>
<string name="warning">इशारा</string> <string name="warning">इशारा</string>
<string name="file_exists">ही संचिका पूर्वीच कॉमन्सवर उपलब्ध आहे. आपणास पुढे जायचे याची निश्चिती करता काय?</string> <string name="file_exists">ही संचिका पूर्वीच कॉमन्सवर उपलब्ध आहे. आपणास पुढे जायचे याची निश्चिती करता काय?</string>
<string name="yes">होय</string> <string name="yes">होय</string>
<string name="no">नाही</string> <string name="no">नाही</string>
<string name="media_detail_title">शीर्षक</string>
<string name="media_detail_media_title">माध्यमाचे शिर्षक</string>
<string name="media_detail_description">वर्णन</string>
<string name="media_detail_description_explanation">माध्यमाची माहिती इथे दिली आहे. ती बरीच मोठी असू शकते, तरीही आम्हांला वाटते ती आपल्या उपयोगाची असावी.</string>
<string name="media_detail_uploaded_date">चढवल्याची तारिख</string>
<string name="media_detail_license">परवाना</string>
<string name="media_detail_coordinates">अक्षांश-रेखांश</string>
<string name="media_detail_coordinates_empty">दिलेले नाही</string>
<string name="become_a_tester_title">बिटा आवृत्तीचे तपासक बना</string>
<string name="become_a_tester_description">गुगल प्ले वरील आमच्या बिटा चॅनलचा पाठलाग करा आणि आमच्या नव्या सेवा-सुविधांचा तसाच त्रुटी-निरसनांचा फ़ायदा घ्या.</string>
<string name="use_wikidata">विकीडाटा वापरा</string>
<string name="use_wikidata_summary">(ताकीद: हे बंद केल्यामुळे तुम्हांला मोठ्याप्रमाणात डेटा खर्च करावा लागेल)</string>
<string name="_2fa_code">2FA कोड</string>
<string name="number_of_uploads">माझ्या अलिकडच्या अपभरणाची मर्यादा</string>
<string name="maximum_limit">जास्तीची मर्यादा</string>
<string name="maximum_limit_alert">५०० पेक्षा जास्त दाखवण्यास असमर्थ</string>
<string name="set_limit">माझ्या अलिकडच्या अपभरणाची मर्यादा</string>
<string name="login_failed_2fa_not_supported">दोन पायऱ्यांची वैधता तपासणी सध्या उपलब्ध नाही.</string>
<string name="logout_verification">काय आपणास खरेच बंद करायचे आहे?</string>
<string name="commons_logo">कॉमन्सचे चिन्ह</string>
<string name="commons_website">कॉमन्सचे संकेतस्थळ</string>
<string name="commons_facebook">कॉमन्सचे फ़ेसबुक पान</string>
<string name="commons_github">कॉमन्सचे गिटहब स्त्रोत कोड</string>
<string name="background_image">पार्श्वभूमी चित्र</string>
<string name="mediaimage_failed"> चित्र माध्यमे कोसळली</string>
<string name="no_image_found">कोणतेही चित्र सापडले नाही</string>
<string name="upload_image">चित्र अपभारीत करा</string>
<string name="welcome_image_mount_zao">जाओ जान पर्वत</string>
<string name="welcome_image_llamas">लामा</string>
<string name="welcome_image_rainbow_bridge">रेनबो पूल</string>
<string name="welcome_image_tulip">टुलिप</string>
<string name="welcome_image_no_selfies">सेल्फ़ी चालणार नाहीत</string>
<string name="welcome_image_proprietary">मालकी हक्क प्रतिमा</string>
<string name="welcome_image_welcome_wikipedia">विकीपिडीयात स्वागत आहे</string>
<string name="welcome_image_welcome_copyright">प्रताधिकार स्वागत आहे</string>
<string name="welcome_image_sydney_opera_house">सिडनीचे ओपेरा हाऊस</string>
<string name="cancel">रद्द करा</string>
<string name="navigation_drawer_open">उघडा</string>
<string name="navigation_drawer_close">बंद करा</string>
<string name="navigation_item_home">मुख्य</string>
<string name="navigation_item_upload">अपभारण करा</string>
<string name="navigation_item_nearby">जवळपास</string>
<string name="navigation_item_about">आमच्याबद्दल</string>
<string name="navigation_item_settings">सेटिंग्स</string>
<string name="navigation_item_feedback">प्रतिक्रिया</string>
<string name="navigation_item_logout">बाहेर पडा</string>
<string name="navigation_item_info">माहिती पुस्तिका</string>
<string name="navigation_item_notification">अधिसूचना</string>
<string name="nearby_needs_permissions">लोकेशन सेवा वापराची परवानगी दिल्याशिवाय जवळपासची ठिकाणे दाखवली जाउ शकत नाहीत.</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="error_while_cache">चित्र दाखवताना त्रुटी आढळली</string>
<string name="title_info">फ़ाईलला असे नाव द्या जे सुयोग्य असेल,चित्राविषयी त्यामधून माहिती कळेल अशी साधी भाषा वापरा,नावामध्ये फ़ाईलचे एक्सटेन्शन लिहू नका.</string>
<string name="description_info">माध्यमांची शक्य तितकी जास्त माहिती द्या:छायाचित्र/चलचित्र/ध्वनिमुद्रण कोठे घेतले आहे? त्यात काय दाखवले आहे? त्या माध्यमांचा संदर्भ काय? त्यातील वस्तू,व्यक्ति व इतर माहिती द्या? अशी सगळी माहिती जी त्या माध्यमाकडे पाहून लक्षात येणार नाही पण ती महत्वाचे आहे ती सर्व पुरवा. जर त्या माध्यमामध्ये काहीही वेगळे दिसत असेल तर ते वेगळे का आहे याची माहिती पुरवा.</string>
<string name="upload_image_too_dark">हे छायाचित्र खुप अंधारलेले आहे, तुम्ही खरच हे छायाचित्र येथे चढवू इच्छीता का? विकीमिडीया कॉमन्सवर नेहमी विश्वकोषात महत्त्वाची असलेलीच चित्रे चढवली जाऊ शकतात.</string>
<string name="upload_image_blurry">हे छायाचित्र खुप फ़िकट आलेले आहे, तुम्ही खरच हे छायाचित्र येथे चढवू इच्छीता का? विकीमिडीया कॉमन्सवर नेहमी विश्वकोषात महत्त्वाची असलेलीच चित्रे चढवली जाऊ शकतात.</string>
<string name="give_permission">परवानगी द्या</string>
<string name="use_external_storage">बाहेरील स्टोरेज वापरा</string>
<string name="use_external_storage_summary">आपल्या डिव्हाइसवरील इन-अॅप्स कॅमेर्यासह घेतलेली चित्रे जतन करा</string>
<string name="login_to_your_account">तुमच्या खात्यावरुन सनोंद प्रवेश करा</string>
<string name="send_log_file">लॉग फ़ाईल पाठवा</string>
<string name="send_log_file_description">विकसकांना लॉग फ़ाईल विपत्राने पाठवा</string>
<string name="nearby_location_has_not_changed">लोकेशन बदलली नाहीये.</string>
<string name="nearby_location_not_available">ही लोकेशन उपलब्ध नाही</string>
<string name="location_permission_rationale_nearby">जवळपासच्या ठिकाणांची यादी दाखवण्यासाठी आपली परवानगी आवश्यक आहे</string>
<string name="get_directions">दिशानिर्देश मिळवा</string>
<string name="read_article">लेख वाचा</string>
<string name="notifications_welcome">विकीमिडीया कॉमन्समध्ये आपले स्वागत आहे,%1$s! आम्हांला आनंद आहे आपण इथे आलात.</string>
<string name="notifications_talk_page_message">%1$s यांनी तुमच्या चर्चापानावर संदेश टाकला</string>
<string name="notifications_thank_you_edit">तुमच्या संपादनासाठी तुमचे आभार !</string>
<string name="notifications_mention">%1$s यांनी तुमचा उल्लेख %2$s येथे केला.</string>
<string name="toggle_view_button">टॉगल दृश्य</string>
</resources> </resources>

View file

@ -20,7 +20,7 @@
<string name="upload_progress_notification_title_finishing">Avslutter opplasting av %1$s</string> <string name="upload_progress_notification_title_finishing">Avslutter opplasting av %1$s</string>
<string name="upload_failed_notification_title">Opplastingen av %1$s feilet</string> <string name="upload_failed_notification_title">Opplastingen av %1$s feilet</string>
<string name="upload_failed_notification_subtitle">Trykk for å vise</string> <string name="upload_failed_notification_subtitle">Trykk for å vise</string>
<plurals name="uploads_pending_notification_indicator" fuzzy="true"> <plurals name="uploads_pending_notification_indicator">
<item quantity="one">%1$d fil lastes opp</item> <item quantity="one">%1$d fil lastes opp</item>
<item quantity="other">%1$d filer lastes opp</item> <item quantity="other">%1$d filer lastes opp</item>
</plurals> </plurals>
@ -54,7 +54,7 @@
<string name="gps_disabled">GPS er slått av på denne enheten. Ønsker du å slå den på?</string> <string name="gps_disabled">GPS er slått av på denne enheten. Ønsker du å slå den på?</string>
<string name="enable_gps">Slå på GPS</string> <string name="enable_gps">Slå på GPS</string>
<string name="contributions_subtitle_zero">Ingen opplastinger ennå</string> <string name="contributions_subtitle_zero">Ingen opplastinger ennå</string>
<plurals name="contributions_subtitle" fuzzy="true"> <plurals name="contributions_subtitle">
<item quantity="zero">\@string/contributions_subtitle_zero</item> <item quantity="zero">\@string/contributions_subtitle_zero</item>
<item quantity="one">%1$d opplasting</item> <item quantity="one">%1$d opplasting</item>
<item quantity="other">%1$d opplastinger</item> <item quantity="other">%1$d opplastinger</item>
@ -63,7 +63,7 @@
<item quantity="one">Starter %1$d opplasting</item> <item quantity="one">Starter %1$d opplasting</item>
<item quantity="other">Starter %1$d opplastinger</item> <item quantity="other">Starter %1$d opplastinger</item>
</plurals> </plurals>
<plurals name="multiple_uploads_title" fuzzy="true"> <plurals name="multiple_uploads_title">
<item quantity="one">%1$d opplasting</item> <item quantity="one">%1$d opplasting</item>
<item quantity="other">%1$d opplastinger</item> <item quantity="other">%1$d opplastinger</item>
</plurals> </plurals>
@ -199,12 +199,14 @@
<string name="error_while_cache">Feil under mellomlagring av bilder</string> <string name="error_while_cache">Feil under mellomlagring av bilder</string>
<string name="title_info">En unik beskrivende tittel for fila, som vil fungere som filnavn. Du kan bruke vanlig språk med mellomrom. Ikke ta med filendelsen</string> <string name="title_info">En unik beskrivende tittel for fila, som vil fungere som filnavn. Du kan bruke vanlig språk med mellomrom. Ikke ta med filendelsen</string>
<string name="description_info">Beskriv bidraget så mye som mulig: Hvor ble det tatt? Hva viser det? Hva er konteksten? Beskriv objektene eller personene. Gi informasjon som ikke kan gjettes lett, for eksempel når på dagen bildet ble tatt om det er et landskapsbilde. Om bildet viser noe uvanlig, forklar hva som gjør det uvanlig.</string> <string name="description_info">Beskriv bidraget så mye som mulig: Hvor ble det tatt? Hva viser det? Hva er konteksten? Beskriv objektene eller personene. Gi informasjon som ikke kan gjettes lett, for eksempel når på dagen bildet ble tatt om det er et landskapsbilde. Om bildet viser noe uvanlig, forklar hva som gjør det uvanlig.</string>
<string name="upload_image_too_dark">Dette bildet er for mørkt, er du sikker på at du ønsker å laste det opp? Wikimedia Commons er kun for bilder med ensyklopedisk verdi.</string>
<string name="upload_image_blurry">Dette bildet er uklart, er du sikker på at du ønsker å laste det opp? Wikimedia Commons er bare for bilder med ensyklopedisk verdi.</string>
<string name="give_permission">Gi tillatelse</string> <string name="give_permission">Gi tillatelse</string>
<string name="use_external_storage">Bruk ekstern lagring</string> <string name="use_external_storage">Bruk ekstern lagring</string>
<string name="use_external_storage_summary">Lagre bilder som er tatt med kameraet i appen på enheten din</string> <string name="use_external_storage_summary">Lagre bilder som er tatt med kameraet i appen på enheten din</string>
<string name="login_to_your_account">Logg inn med kontoen din</string>
<string name="send_log_file">Send loggfil</string> <string name="send_log_file">Send loggfil</string>
<string name="send_log_file_description">Send loggfil til utviklerne via epost</string> <string name="send_log_file_description">Send loggfil til utviklerne via epost</string>
<string name="login_to_your_account">Logg inn med kontoen din</string>
<string name="nearby_location_has_not_changed">Stedet har ikke blitt endret.</string> <string name="nearby_location_has_not_changed">Stedet har ikke blitt endret.</string>
<string name="nearby_location_not_available">Sted ikke tilgjengelig.</string> <string name="nearby_location_not_available">Sted ikke tilgjengelig.</string>
<string name="location_permission_rationale_nearby">Tillatelse kreves for å vise listen over steder i nærheten</string> <string name="location_permission_rationale_nearby">Tillatelse kreves for å vise listen over steder i nærheten</string>
@ -214,4 +216,5 @@
<string name="notifications_talk_page_message">%1$s la igjen en beskjed på diskusjonssiden din</string> <string name="notifications_talk_page_message">%1$s la igjen en beskjed på diskusjonssiden din</string>
<string name="notifications_thank_you_edit">Takk for at du har gjort en redigering</string> <string name="notifications_thank_you_edit">Takk for at du har gjort en redigering</string>
<string name="notifications_mention">%1$s nevnte deg på %2$s.</string> <string name="notifications_mention">%1$s nevnte deg på %2$s.</string>
<string name="toggle_view_button">Skift visning</string>
</resources> </resources>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Eror antramentre ch\'as butavo le plance an memòria local</string> <string name="error_while_cache">Eror antramentre ch\'as butavo le plance an memòria local</string>
<string name="title_info">Un tìtol dëscritiv ùnich për l\'archivi, che a servirà com nòm d\'archivi. A peul dovré un lengagi sempi con djë spassi. Ch\'a ancluda pa l\'estension dl\'archivi</string> <string name="title_info">Un tìtol dëscritiv ùnich për l\'archivi, che a servirà com nòm d\'archivi. A peul dovré un lengagi sempi con djë spassi. Ch\'a ancluda pa l\'estension dl\'archivi</string>
<string name="description_info">Për piasì, ch\'a descriva ël mojen mej ch\'a peul: Andoa a l\'é stàit fàit? Për piasì, ch\'a descriva j\'oget o le përson-e. Ch\'a arvela j\'anformassion ch\'a l\'é nen belfé andviné, për esempi l\'ora dël dì, s\'a l\'é un panorama. Si ël mojen a smon cheicòs ëd foravìa, për piasì ch\'a spiega lòn ch\'a lo rend foravìa.</string> <string name="description_info">Për piasì, ch\'a descriva ël mojen mej ch\'a peul: Andoa a l\'é stàit fàit? Për piasì, ch\'a descriva j\'oget o le përson-e. Ch\'a arvela j\'anformassion ch\'a l\'é nen belfé andviné, për esempi l\'ora dël dì, s\'a l\'é un panorama. Si ël mojen a smon cheicòs ëd foravìa, për piasì ch\'a spiega lòn ch\'a lo rend foravìa.</string>
<string name="upload_image_too_dark">Sa plancia a l\'é tròp sombra, e-lo sigur ëd vorèj cariela? Wikipedia Comun a l\'é mach për plance con un valor enciclopédich.</string>
<string name="upload_image_blurry">Sa plancia a l\'é tërbola, e-lo sigur ëd vorèj cariela? Wikipedia Comun a l\'é mach për plance con un valor enciclopédich.</string>
<string name="give_permission">Dé ël përmess</string> <string name="give_permission">Dé ël përmess</string>
<string name="use_external_storage">Dovré n\'anmagasinament estern</string> <string name="use_external_storage">Dovré n\'anmagasinament estern</string>
<string name="use_external_storage_summary">Argistré le plance pijà con la màchina fòto ëd sò angign</string> <string name="use_external_storage_summary">Argistré le plance pijà con la màchina fòto ëd sò angign</string>
<string name="login_to_your_account">Ch\'as colega a sò cont</string>
<string name="send_log_file">Mandé l\'archivi d\'argistr</string> <string name="send_log_file">Mandé l\'archivi d\'argistr</string>
<string name="send_log_file_description">Mandé l\'archivi d\'argistr ai dësvlupator për pòsta eletrònica</string> <string name="send_log_file_description">Mandé l\'archivi d\'argistr ai dësvlupator për pòsta eletrònica</string>
<string name="login_to_your_account">Ch\'as colega a sò cont</string>
<string name="nearby_location_has_not_changed">Ël leu a l\'é nen cangià.</string> <string name="nearby_location_has_not_changed">Ël leu a l\'é nen cangià.</string>
<string name="nearby_location_not_available">Leu nen disponìbil.</string> <string name="nearby_location_not_available">Leu nen disponìbil.</string>
<string name="location_permission_rationale_nearby">A-i é da manca dël përmess pr\'ësmon-e na lista dij pòst davzin</string> <string name="location_permission_rationale_nearby">A-i é da manca dël përmess pr\'ësmon-e na lista dij pòst davzin</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Erro durante o cache de imagens</string> <string name="error_while_cache">Erro durante o cache de imagens</string>
<string name="title_info">Um título descritivo exclusivo para o arquivo, que servirá como um nome de arquivo. Você pode usar linguagem simples com espaços. Não inclua a extensão do arquivo</string> <string name="title_info">Um título descritivo exclusivo para o arquivo, que servirá como um nome de arquivo. Você pode usar linguagem simples com espaços. Não inclua a extensão do arquivo</string>
<string name="description_info">Por favor, descreva a mídia tanto quanto possível: onde foi tomada? O que isso mostra? Qual é o contexto? Descreva os objetos ou pessoas. Revelar informações que não podem ser facilmente adivinhadas, por exemplo, a hora do dia, se for uma paisagem. Se a mídia mostrar algo incomum, explique o que torna incomum.</string> <string name="description_info">Por favor, descreva a mídia tanto quanto possível: onde foi tomada? O que isso mostra? Qual é o contexto? Descreva os objetos ou pessoas. Revelar informações que não podem ser facilmente adivinhadas, por exemplo, a hora do dia, se for uma paisagem. Se a mídia mostrar algo incomum, explique o que torna incomum.</string>
<string name="upload_image_too_dark">Esta foto está muito escura, você tem certeza de que deseja enviá-la? O Wikimedia Commons é apenas para imagens com valor enciclopédico.</string>
<string name="upload_image_blurry">Esta foto está embaçada, tem certeza de que deseja enviá-la? O Wikimedia Commons é apenas para imagens com valor enciclopédico.</string>
<string name="give_permission">Dar permissão</string> <string name="give_permission">Dar permissão</string>
<string name="use_external_storage">Usar o armazenamento externo</string> <string name="use_external_storage">Usar o armazenamento externo</string>
<string name="use_external_storage_summary">Salvar as fotos tiradas com a câmera no aplicativo no seu dispositivo</string> <string name="use_external_storage_summary">Salvar as fotos tiradas com a câmera no aplicativo no seu dispositivo</string>
<string name="login_to_your_account">Faça login na sua conta</string>
<string name="send_log_file">Enviar arquivo de registro</string> <string name="send_log_file">Enviar arquivo de registro</string>
<string name="send_log_file_description">Enviar arquivo de log para desenvolvedores por e-mail</string> <string name="send_log_file_description">Enviar arquivo de log para desenvolvedores por e-mail</string>
<string name="login_to_your_account">Faça login na sua conta</string>
<string name="nearby_location_has_not_changed">O local não mudou.</string> <string name="nearby_location_has_not_changed">O local não mudou.</string>
<string name="nearby_location_not_available">Localização não disponível.</string> <string name="nearby_location_not_available">Localização não disponível.</string>
<string name="location_permission_rationale_nearby">Permissão necessária para exibir uma lista de locais próximos</string> <string name="location_permission_rationale_nearby">Permissão necessária para exibir uma lista de locais próximos</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Erro ao colocar imagens na cache</string> <string name="error_while_cache">Erro ao colocar imagens na cache</string>
<string name="title_info">Um título descritivo exclusivo para o ficheiro, que servirá como um nome de ficheiro. Pode utilizar uma linguagem simples com espaços. Não inclua a extensão do ficheiro</string> <string name="title_info">Um título descritivo exclusivo para o ficheiro, que servirá como um nome de ficheiro. Pode utilizar uma linguagem simples com espaços. Não inclua a extensão do ficheiro</string>
<string name="description_info">Por favor, descreva o ficheiro da melhor forma possível: Onde foi tirado? O que isso mostra? Qual é o contexto? Por favor, descreva os objetos ou as pessoas. Indique as informações que não podem ser facilmente adivinhadas, por exemplo, a hora do dia, se for uma paisagem. Se o ficheiro mostrar algo incomum, explique o que torna incomum.</string> <string name="description_info">Por favor, descreva o ficheiro da melhor forma possível: Onde foi tirado? O que isso mostra? Qual é o contexto? Por favor, descreva os objetos ou as pessoas. Indique as informações que não podem ser facilmente adivinhadas, por exemplo, a hora do dia, se for uma paisagem. Se o ficheiro mostrar algo incomum, explique o que torna incomum.</string>
<string name="upload_image_too_dark">Esta imagem está demasiada escura, tem a certeza de que deseja carregá-la? O Wikimedia Commons só aceita as imagens de valor enciclopédico.</string>
<string name="upload_image_blurry">Esta imagem está desfocada, tem a certeza de que deseja carregá-la? O Wikimedia Commons serve apenas para imagens de valor enciclopédico.</string>
<string name="give_permission">Permitir</string> <string name="give_permission">Permitir</string>
<string name="use_external_storage">Utilizar a armazenagem externa</string> <string name="use_external_storage">Utilizar a armazenagem externa</string>
<string name="use_external_storage_summary">Gravar as fotografias tiradas com a câmara da aplicação no seu dispositivo</string> <string name="use_external_storage_summary">Gravar as fotografias tiradas com a câmara da aplicação no seu dispositivo</string>
<string name="login_to_your_account">Inicie sessão na sua conta</string>
<string name="send_log_file">Enviar ficheiro de registo</string> <string name="send_log_file">Enviar ficheiro de registo</string>
<string name="send_log_file_description">Enviar o ficheiro de registo aos programadores por correio eletrónico</string> <string name="send_log_file_description">Enviar o ficheiro de registo aos programadores por correio eletrónico</string>
<string name="login_to_your_account">Inicie sessão na sua conta</string>
<string name="nearby_location_has_not_changed">A localização não foi alterada.</string> <string name="nearby_location_has_not_changed">A localização não foi alterada.</string>
<string name="nearby_location_not_available">A localização não está disponível.</string> <string name="nearby_location_not_available">A localização não está disponível.</string>
<string name="location_permission_rationale_nearby">É necessária a permissão para mostrar uma lista dos sítios aqui perto</string> <string name="location_permission_rationale_nearby">É necessária a permissão para mostrar uma lista dos sítios aqui perto</string>

View file

@ -203,12 +203,14 @@
<string name="error_while_cache">Ошибка при кэшировании картинок</string> <string name="error_while_cache">Ошибка при кэшировании картинок</string>
<string name="title_info">Уникальное описание, которое будет сохранено как имя файла. Вы можете использовать естественный язык, разделяя слова пробелами. Пожалуйста, не указывайте расширение файла.</string> <string name="title_info">Уникальное описание, которое будет сохранено как имя файла. Вы можете использовать естественный язык, разделяя слова пробелами. Пожалуйста, не указывайте расширение файла.</string>
<string name="description_info">Пожалуйста, подробно опишите загружаемый файл: где он был снят? что на нём изображено? каков его контекст? Пожалуйста опишите изображённых персон или объекты. Добавьте информацию, о которой нельзя легко догадаться, например, время суток, когда снимался файл. Если снято что-то необычное, постарайтесь пояснить, что именно в этом необычного.</string> <string name="description_info">Пожалуйста, подробно опишите загружаемый файл: где он был снят? что на нём изображено? каков его контекст? Пожалуйста опишите изображённых персон или объекты. Добавьте информацию, о которой нельзя легко догадаться, например, время суток, когда снимался файл. Если снято что-то необычное, постарайтесь пояснить, что именно в этом необычного.</string>
<string name="upload_image_too_dark">Это изображение слишком тёмное. Вы уверены, что хотите его загрузить? Викисклад подходит только для фотографий, имеющих энциклопедическую ценность.</string>
<string name="upload_image_blurry">Это изображение размыто. Вы уверены, что хотите его загрузить? Викисклад подходит только для фотографий, имеющих энциклопедическую ценность.</string>
<string name="give_permission">Дать разрешение</string> <string name="give_permission">Дать разрешение</string>
<string name="use_external_storage">Использовать внешнее хранилище</string> <string name="use_external_storage">Использовать внешнее хранилище</string>
<string name="use_external_storage_summary">Сохранять изображения, сделанные с помощью встроенной камеры на устройстве</string> <string name="use_external_storage_summary">Сохранять изображения, сделанные с помощью встроенной камеры на устройстве</string>
<string name="login_to_your_account">Войдите в свою учётную запись</string>
<string name="send_log_file">Выслать лог-файл</string> <string name="send_log_file">Выслать лог-файл</string>
<string name="send_log_file_description">Выслать лог-файл разработчикам по е-мейлу</string> <string name="send_log_file_description">Выслать лог-файл разработчикам по е-мейлу</string>
<string name="login_to_your_account">Войдите в свою учётную запись</string>
<string name="nearby_location_has_not_changed">Местоположение не изменено.</string> <string name="nearby_location_has_not_changed">Местоположение не изменено.</string>
<string name="nearby_location_not_available">Местоположение недоступно.</string> <string name="nearby_location_not_available">Местоположение недоступно.</string>
<string name="location_permission_rationale_nearby">Необходимо разрешение для отображения списка мест поблизости</string> <string name="location_permission_rationale_nearby">Необходимо разрешение для отображения списка мест поблизости</string>

View file

@ -176,9 +176,9 @@
<string name="give_permission">اجازت ڏيو</string> <string name="give_permission">اجازت ڏيو</string>
<string name="use_external_storage">ٻاھري سنڀار استعمال ڪريو</string> <string name="use_external_storage">ٻاھري سنڀار استعمال ڪريو</string>
<string name="use_external_storage_summary">ايپ ۾ ڪئمرا سان ڪڍيل تصويرون پنھنجي ڊوائيس تي سانڍيو</string> <string name="use_external_storage_summary">ايپ ۾ ڪئمرا سان ڪڍيل تصويرون پنھنجي ڊوائيس تي سانڍيو</string>
<string name="login_to_your_account">پنھنجي کاتي ۾ داخل ٿيو</string>
<string name="send_log_file">لاگ فائيل موڪليو</string> <string name="send_log_file">لاگ فائيل موڪليو</string>
<string name="send_log_file_description">لاگ فائيل سرجڻھارن کي برقٽپال ذريعي موڪليو</string> <string name="send_log_file_description">لاگ فائيل سرجڻھارن کي برقٽپال ذريعي موڪليو</string>
<string name="login_to_your_account">پنھنجي کاتي ۾ داخل ٿيو</string>
<string name="nearby_location_has_not_changed">مڪانيت تبديلي ناھي ٿي.</string> <string name="nearby_location_has_not_changed">مڪانيت تبديلي ناھي ٿي.</string>
<string name="nearby_location_not_available">مڪانيت موجود ناھي.</string> <string name="nearby_location_not_available">مڪانيت موجود ناھي.</string>
<string name="location_permission_rationale_nearby">ويجھين جڳھن جي فھرست ڏيکارڻ لاءِ اجازت گھربل آھي</string> <string name="location_permission_rationale_nearby">ويجھين جڳھن جي فھرست ڏيکارڻ لاءِ اجازت گھربل آھي</string>

View file

@ -106,6 +106,6 @@
<string name="navigation_item_info">ٹیٹوریل</string> <string name="navigation_item_info">ٹیٹوریل</string>
<string name="nearby_info_menu_wikidata_article">وکی ڈیٹا آئٹم</string> <string name="nearby_info_menu_wikidata_article">وکی ڈیٹا آئٹم</string>
<string name="give_permission">اجازت ݙیوو</string> <string name="give_permission">اجازت ݙیوو</string>
<string name="send_log_file">لاگ فائل بھیجو</string>
<string name="login_to_your_account">آپݨے کھاتے وچ لاگ ان تھیوو</string> <string name="login_to_your_account">آپݨے کھاتے وچ لاگ ان تھیوو</string>
<string name="send_log_file">لاگ فائل بھیجو</string>
</resources> </resources>

View file

@ -54,12 +54,12 @@
<string name="gps_disabled">GPS је онемогућен на Вашем уређају. Желите ли га омогућити?</string> <string name="gps_disabled">GPS је онемогућен на Вашем уређају. Желите ли га омогућити?</string>
<string name="enable_gps">Омогући GPS</string> <string name="enable_gps">Омогући GPS</string>
<string name="contributions_subtitle_zero">Још увек нема отпремања</string> <string name="contributions_subtitle_zero">Још увек нема отпремања</string>
<plurals name="contributions_subtitle" fuzzy="true"> <plurals name="contributions_subtitle">
<item quantity="zero">\@string/contributions_subtitle_zero</item> <item quantity="zero">\@string/contributions_subtitle_zero</item>
<item quantity="one">%1$d отпремање</item> <item quantity="one">%1$d отпремање</item>
<item quantity="other">%1$d отпремања</item> <item quantity="other">%1$d отпремања</item>
</plurals> </plurals>
<plurals name="starting_multiple_uploads" fuzzy="true"> <plurals name="starting_multiple_uploads">
<item quantity="one">Започни %1$d отпремање</item> <item quantity="one">Започни %1$d отпремање</item>
<item quantity="other">Започни %1$d отпремања</item> <item quantity="other">Започни %1$d отпремања</item>
</plurals> </plurals>
@ -74,7 +74,7 @@
<string name="title_activity_signup">Отвори налог</string> <string name="title_activity_signup">Отвори налог</string>
<string name="menu_about">О апликацији</string> <string name="menu_about">О апликацији</string>
<string name="about_license">Софтвер отвореног кода доступан под лиценцом &lt;a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\"&gt;Apache вер. 2&lt;/a&gt; Викимедијина Остава и њен лого су заштитни знаци Викимедијине Фондације и користе се са дозволом Викимедијине Фондацине. Ми не одобравамо или подржавмо Викимедијину Фондацију.\n\nАпликација за Викимедијину оставу је апликација отвореног кода која је направљена и која се одржава помоћу грантова и волонтера Викимедијине заједнице. Задужбина Викимедија није укључена у стварање, развој или одржавање апликације.</string> <string name="about_license">Софтвер отвореног кода доступан под лиценцом &lt;a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\"&gt;Apache вер. 2&lt;/a&gt; Викимедијина Остава и њен лого су заштитни знаци Викимедијине Фондације и користе се са дозволом Викимедијине Фондацине. Ми не одобравамо или подржавмо Викимедијину Фондацију.\n\nАпликација за Викимедијину оставу је апликација отвореног кода која је направљена и која се одржава помоћу грантова и волонтера Викимедијине заједнице. Задужбина Викимедија није укључена у стварање, развој или одржавање апликације.</string>
<string name="about_improve" fuzzy="true">&lt;a href=\"https://github.com/commons-app/apps-android-commons\"&gt;Изворни кôд&lt;/a&gt; и &lt;a href=\"https://commons-app.github.io/\"&gt;веб-сајт&lt;/a&gt; на GitHub-у. Направите нови &lt;a href=\"https://github.com/commons-app/apps-android-commons/issues\"&gt;захтев на GitHub-у&lt;/a&gt; да бисте пријавили грешке или дали предлоге.</string> <string name="about_improve">Направите нови &lt;a href=\"https://github.com/commons-app/apps-android-commons/issues\"&gt;захтев на GitHub-у&lt;/a&gt; да бисте пријавили грешке или дали предлоге.</string>
<string name="about_privacy_policy">&lt;a href=\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\"&gt;Политика приватности&lt;/a&gt;</string> <string name="about_privacy_policy">&lt;a href=\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\"&gt;Политика приватности&lt;/a&gt;</string>
<string name="about_credits">&lt;a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\"&gt;Заслуге&lt;/a&gt;</string> <string name="about_credits">&lt;a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\"&gt;Заслуге&lt;/a&gt;</string>
<string name="title_activity_about">О апликацији</string> <string name="title_activity_about">О апликацији</string>
@ -164,6 +164,9 @@
<string name="login_failed_2fa_not_supported">Двофакторска аутентификација тренутно није подржана.</string> <string name="login_failed_2fa_not_supported">Двофакторска аутентификација тренутно није подржана.</string>
<string name="logout_verification">Заиста желите да се одјавите?</string> <string name="logout_verification">Заиста желите да се одјавите?</string>
<string name="commons_logo">Лого Оставе</string> <string name="commons_logo">Лого Оставе</string>
<string name="commons_website">Веб-сајт Оставе</string>
<string name="commons_facebook">Фејсбук страница Оставе</string>
<string name="commons_github">Изворни код на Github-у</string>
<string name="background_image">Позадинска слика</string> <string name="background_image">Позадинска слика</string>
<string name="mediaimage_failed">Медијска слика неуспешна</string> <string name="mediaimage_failed">Медијска слика неуспешна</string>
<string name="no_image_found">Нисам пронашла слику</string> <string name="no_image_found">Нисам пронашла слику</string>
@ -199,12 +202,14 @@
<string name="give_permission">Давање дозволе</string> <string name="give_permission">Давање дозволе</string>
<string name="use_external_storage">Употреба спољашње меморије</string> <string name="use_external_storage">Употреба спољашње меморије</string>
<string name="use_external_storage_summary">Спремање слика направљених камером апликације на Вашем уређају</string> <string name="use_external_storage_summary">Спремање слика направљених камером апликације на Вашем уређају</string>
<string name="login_to_your_account">Пријавите се на Ваш налог</string>
<string name="send_log_file">Пошаљи дневничку датотеку</string> <string name="send_log_file">Пошаљи дневничку датотеку</string>
<string name="send_log_file_description">Пошаљи дневничку датотеку девелоперима преко имејла</string> <string name="send_log_file_description">Пошаљи дневничку датотеку девелоперима преко имејла</string>
<string name="login_to_your_account">Пријавите се на Ваш налог</string>
<string name="nearby_location_has_not_changed">Локација није промењена.</string> <string name="nearby_location_has_not_changed">Локација није промењена.</string>
<string name="nearby_location_not_available">Локација није доступна.</string> <string name="nearby_location_not_available">Локација није доступна.</string>
<string name="location_permission_rationale_nearby">Потребна је дозвола за приказивање листе локација у близини</string> <string name="location_permission_rationale_nearby">Потребна је дозвола за приказивање листе локација у близини</string>
<string name="get_directions">Добити упутства</string> <string name="get_directions">Добити упутства</string>
<string name="read_article">Прочитај чланак</string> <string name="read_article">Прочитај чланак</string>
<string name="notifications_thank_you_edit">Хвала Вам за прављење измене</string>
<string name="toggle_view_button">Пребаци приказ</string>
</resources> </resources>

View file

@ -198,7 +198,7 @@
<string name="give_permission">Béré idin</string> <string name="give_permission">Béré idin</string>
<string name="use_external_storage">Paké panyimpenan éksternal</string> <string name="use_external_storage">Paké panyimpenan éksternal</string>
<string name="use_external_storage_summary">Simpen gambar nu nyomotna ku aplikasi kaména na parangkat anjeun</string> <string name="use_external_storage_summary">Simpen gambar nu nyomotna ku aplikasi kaména na parangkat anjeun</string>
<string name="login_to_your_account">Asup log kana akun anjeun</string>
<string name="send_log_file">Kirim berkas log</string> <string name="send_log_file">Kirim berkas log</string>
<string name="send_log_file_description">Kirim berkas log ka pamekar liwat surélék</string> <string name="send_log_file_description">Kirim berkas log ka pamekar liwat surélék</string>
<string name="login_to_your_account">Asup log kana akun anjeun</string>
</resources> </resources>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">Fel uppstod när bilder cachelagras</string> <string name="error_while_cache">Fel uppstod när bilder cachelagras</string>
<string name="title_info">En unik beskrivande titel för filen, som kommer att fungera som ett filnamn. Du kan använda klarspråk med mellanslag. Ta inte med filändelsen</string> <string name="title_info">En unik beskrivande titel för filen, som kommer att fungera som ett filnamn. Du kan använda klarspråk med mellanslag. Ta inte med filändelsen</string>
<string name="description_info">Beskriv mediafilen så mycket som möjligt. Var togs den? Vad visar den? Vad är sammanhanget? Beskriv föremålen eller personerna. Ge information som inte kan gissas fram, t.ex. tidpunkten om det är ett landskap. Om mediafilen visar någonting ovanligt, förklara vad som gör den ovanlig.</string> <string name="description_info">Beskriv mediafilen så mycket som möjligt. Var togs den? Vad visar den? Vad är sammanhanget? Beskriv föremålen eller personerna. Ge information som inte kan gissas fram, t.ex. tidpunkten om det är ett landskap. Om mediafilen visar någonting ovanligt, förklara vad som gör den ovanlig.</string>
<string name="upload_image_too_dark">Denna bild är för mörk, är du säker på att du vill ladda upp den? Wikimedia Commons är endast till för bilder med encyklopediskt värde.</string>
<string name="upload_image_blurry">Denna bild är suddig, är du säker på att du vill ladda upp den? Wikimedia Commons är endast till för bilder med encyklopediskt värde.</string>
<string name="give_permission">Ge behörighet</string> <string name="give_permission">Ge behörighet</string>
<string name="use_external_storage">Använd extern lagring</string> <string name="use_external_storage">Använd extern lagring</string>
<string name="use_external_storage_summary">Spara bilder som tas med kameran i appen på din enhet</string> <string name="use_external_storage_summary">Spara bilder som tas med kameran i appen på din enhet</string>
<string name="login_to_your_account">Logga in på ditt konto</string>
<string name="send_log_file">Skicka loggfil</string> <string name="send_log_file">Skicka loggfil</string>
<string name="send_log_file_description">Skicka loggfilen till utvecklarna via e-post</string> <string name="send_log_file_description">Skicka loggfilen till utvecklarna via e-post</string>
<string name="login_to_your_account">Logga in på ditt konto</string>
<string name="nearby_location_has_not_changed">Platsen har inte ändrats.</string> <string name="nearby_location_has_not_changed">Platsen har inte ändrats.</string>
<string name="nearby_location_not_available">Platsen är inte tillgänglig.</string> <string name="nearby_location_not_available">Platsen är inte tillgänglig.</string>
<string name="location_permission_rationale_nearby">Behörighet krävs för att visa en lista över platser i närheten</string> <string name="location_permission_rationale_nearby">Behörighet krävs för att visa en lista över platser i närheten</string>

View file

@ -199,9 +199,9 @@
<string name="give_permission">İzin ver</string> <string name="give_permission">İzin ver</string>
<string name="use_external_storage">Harici depolamayı kullanın</string> <string name="use_external_storage">Harici depolamayı kullanın</string>
<string name="use_external_storage_summary">Uygulama kamerası kullanıldığında çekilen fotoğrafları cihazına kaydedin</string> <string name="use_external_storage_summary">Uygulama kamerası kullanıldığında çekilen fotoğrafları cihazına kaydedin</string>
<string name="login_to_your_account">Hesabınızda oturum açın</string>
<string name="send_log_file">Kayıt dosyasını gönder</string> <string name="send_log_file">Kayıt dosyasını gönder</string>
<string name="send_log_file_description">Kayıt dosyasını, e-posta aracılığıyla geliştiricilere gönderin</string> <string name="send_log_file_description">Kayıt dosyasını, e-posta aracılığıyla geliştiricilere gönderin</string>
<string name="login_to_your_account">Hesabınızda oturum açın</string>
<string name="nearby_location_has_not_changed">Konum değiştirilmedi</string> <string name="nearby_location_has_not_changed">Konum değiştirilmedi</string>
<string name="nearby_location_not_available">Konum kullanılamıyor.</string> <string name="nearby_location_not_available">Konum kullanılamıyor.</string>
<string name="location_permission_rationale_nearby">Yakındaki yerler listesini görüntülemek için izin vermeniz gerekiyor</string> <string name="location_permission_rationale_nearby">Yakındaki yerler listesini görüntülemek için izin vermeniz gerekiyor</string>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name" fuzzy="true">ۋىكى ۋاستە ھەمبەھىر</string> <string name="app_name">بايلىق ھەمبەھىرلەش</string>
<string name="menu_settings">تەڭشەكلەر</string> <string name="menu_settings">تەڭشەكلەر</string>
<string name="username">ئىشلەتكۇچى ئىسمى</string> <string name="username">ئىشلەتكۇچى ئىسمى</string>
<string name="password">پارول</string> <string name="password">پارول</string>
@ -20,7 +20,7 @@
<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>
<string name="upload_failed_notification_subtitle">چېكىپ كۆرۈش</string> <string name="upload_failed_notification_subtitle">چېكىپ كۆرۈش</string>
<string name="title_activity_contributions" fuzzy="true">يۈكلىگەنلىرىم</string> <string name="title_activity_contributions">يىقىندا يوللىغىنىم</string>
<string name="contribution_state_queued">ئادەم كىردى</string> <string name="contribution_state_queued">ئادەم كىردى</string>
<string name="contribution_state_failed">مەغلۇپ بولدى</string> <string name="contribution_state_failed">مەغلۇپ بولدى</string>
<string name="contribution_state_in_progress">%1$d%% تاماملاندى</string> <string name="contribution_state_in_progress">%1$d%% تاماملاندى</string>
@ -54,8 +54,8 @@
<string name="menu_cancel_upload">ۋاز كەچ</string> <string name="menu_cancel_upload">ۋاز كەچ</string>
<string name="menu_download">چۈشۈرۈڭ</string> <string name="menu_download">چۈشۈرۈڭ</string>
<string name="preference_license">ئىجازەتنامە</string> <string name="preference_license">ئىجازەتنامە</string>
<string name="license_name_cc_by_sa" fuzzy="true">CC Attribution-ShareAlike 3.0</string> <string name="license_name_cc_by_sa">ئوخشاش ئىمزالىق ئورتاق ھەمبەھىرلىنىش</string>
<string name="license_name_cc_by" fuzzy="true">CC Attribution 3.0</string> <string name="license_name_cc_by">ئىمزا قويۇش</string>
<string name="license_name_cc0">CC0</string> <string name="license_name_cc0">CC0</string>
<string name="license_name_cc_by_sa_3_0">CC BY-SA 3.0</string> <string name="license_name_cc_by_sa_3_0">CC BY-SA 3.0</string>
<string name="license_name_cc_by_sa_3_0_at">CC BY-SA 3.0 (ئاۋستىرىيە)</string> <string name="license_name_cc_by_sa_3_0_at">CC BY-SA 3.0 (ئاۋستىرىيە)</string>
@ -70,9 +70,11 @@
<string name="license_name_cc_zero">CC0</string> <string name="license_name_cc_zero">CC0</string>
<string name="welcome_final_button_text">ھەئە!</string> <string name="welcome_final_button_text">ھەئە!</string>
<string name="detail_panel_cats_label">تۈرلەر</string> <string name="detail_panel_cats_label">تۈرلەر</string>
<string name="detail_panel_cats_loading" fuzzy="true">يۈكلەۋاتىدۇ…</string> <string name="detail_panel_cats_loading">يۈكلىنۋاتىدۇ…</string>
<string name="detail_panel_cats_none">تاللانمىغان</string> <string name="detail_panel_cats_none">تاللانمىغان</string>
<string name="detail_description_empty">چۈشەندۈرۈلۈشى يوق</string> <string name="detail_description_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="yes">ھەئە</string> <string name="yes">ھەئە</string>

View file

@ -207,12 +207,14 @@
<string name="error_while_cache">Помилка кешування зображень</string> <string name="error_while_cache">Помилка кешування зображень</string>
<string name="title_info">Унікальна описова назва файлу. Ви можете використовувати простий текст з пробілами. Не вказуйте розширення файлу</string> <string name="title_info">Унікальна описова назва файлу. Ви можете використовувати простий текст з пробілами. Не вказуйте розширення файлу</string>
<string name="description_info">Будь ласка, докладно опишіть файл: де його було зроблено? що на ньому зображено? який контекст? Будь ласка, опишіть об\'єкти чи осіб. Додайте інформацію, яку не можна легко здогадатися, наприклад, пору доби для фотографії пейзажу. Якщо зображено щось незвичайне, постарайтеся пояснити, що робить його незвичайним.</string> <string name="description_info">Будь ласка, докладно опишіть файл: де його було зроблено? що на ньому зображено? який контекст? Будь ласка, опишіть об\'єкти чи осіб. Додайте інформацію, яку не можна легко здогадатися, наприклад, пору доби для фотографії пейзажу. Якщо зображено щось незвичайне, постарайтеся пояснити, що робить його незвичайним.</string>
<string name="upload_image_too_dark">Це зображення надто темне. Ви упевнені, що хочете його завантажити? Вікісховище призначене лише для зображень, що мають енциклопедичну цінність.</string>
<string name="upload_image_blurry">Це зображення розмите. Ви упевнені, що хочете його завантажити? Вікісховище призначене лише для зображень, що мають енциклопедичну цінність.</string>
<string name="give_permission">Надати дозвіл</string> <string name="give_permission">Надати дозвіл</string>
<string name="use_external_storage">Використовувати зовнішнє сховище</string> <string name="use_external_storage">Використовувати зовнішнє сховище</string>
<string name="use_external_storage_summary">Зберігати зображення, виконані вбудованою камерою Вашого пристрою</string> <string name="use_external_storage_summary">Зберігати зображення, виконані вбудованою камерою Вашого пристрою</string>
<string name="login_to_your_account">Увійдіть у свій обліковий запис</string>
<string name="send_log_file">Надіслати лог-файл</string> <string name="send_log_file">Надіслати лог-файл</string>
<string name="send_log_file_description">Надіслати лог-файл розробникам електронною поштою</string> <string name="send_log_file_description">Надіслати лог-файл розробникам електронною поштою</string>
<string name="login_to_your_account">Увійдіть у свій обліковий запис</string>
<string name="nearby_location_has_not_changed">Розташування не змінено</string> <string name="nearby_location_has_not_changed">Розташування не змінено</string>
<string name="nearby_location_not_available">Місцезнаходження недоступне</string> <string name="nearby_location_not_available">Місцезнаходження недоступне</string>
<string name="location_permission_rationale_nearby">Потрібний дозвіл для показу списку місць поблизу</string> <string name="location_permission_rationale_nearby">Потрібний дозвіл для показу списку місць поблизу</string>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="crash_dialog_title">同享壞咗</string>
<string name="crash_dialog_text">哎呀。出咗錯!</string>
<string name="crash_dialog_ok_toast">多謝你!</string>
</resources>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">在快取圖片時發生錯誤</string> <string name="error_while_cache">在快取圖片時發生錯誤</string>
<string name="title_info">用於本檔案的唯一描述性標題。您可以使用帶有空格的簡明語言,另外請不要包含副檔名。</string> <string name="title_info">用於本檔案的唯一描述性標題。您可以使用帶有空格的簡明語言,另外請不要包含副檔名。</string>
<string name="description_info">請盡可能說明媒體內容:拍攝於何處?是顯示什麼事物?有什麼脈絡?請描述對象或人物。透露出一些較不易猜測的訊息,例如是風景的話,可以是一天裡的時間。如果媒體顯示出一些不正常的事物,請說明出造成不正常原因。</string> <string name="description_info">請盡可能說明媒體內容:拍攝於何處?是顯示什麼事物?有什麼脈絡?請描述對象或人物。透露出一些較不易猜測的訊息,例如是風景的話,可以是一天裡的時間。如果媒體顯示出一些不正常的事物,請說明出造成不正常原因。</string>
<string name="upload_image_too_dark">此圖片太暗,您確定您要上傳它嗎?維基共享資源僅適用對於百科全書有價值的圖片。</string>
<string name="upload_image_blurry">此圖片太模糊,您確定您要上傳它嗎?維基共享資源僅適用對於百科全書有價值的圖片。</string>
<string name="give_permission">給予權限</string> <string name="give_permission">給予權限</string>
<string name="use_external_storage">使用外部存儲裝置</string> <string name="use_external_storage">使用外部存儲裝置</string>
<string name="use_external_storage_summary">在您的裝置上使用照相機應用程式來儲存照片</string> <string name="use_external_storage_summary">在您的裝置上使用照相機應用程式來儲存照片</string>
<string name="login_to_your_account">登入您的帳號</string>
<string name="send_log_file">寄送日誌檔案</string> <string name="send_log_file">寄送日誌檔案</string>
<string name="send_log_file_description">經由電子郵件寄送日誌檔案給開發人員</string> <string name="send_log_file_description">經由電子郵件寄送日誌檔案給開發人員</string>
<string name="login_to_your_account">登入您的帳號</string>
<string name="nearby_location_has_not_changed">位置無法更改。</string> <string name="nearby_location_has_not_changed">位置無法更改。</string>
<string name="nearby_location_not_available">位置無效。</string> <string name="nearby_location_not_available">位置無效。</string>
<string name="location_permission_rationale_nearby">需權限來顯示附近地點清單</string> <string name="location_permission_rationale_nearby">需權限來顯示附近地點清單</string>

View file

@ -199,12 +199,14 @@
<string name="error_while_cache">缓存图片时出错</string> <string name="error_while_cache">缓存图片时出错</string>
<string name="title_info">用于文件的唯一描述性标题,它将作为文件名使用。您可以使用有空格的简明语言。请不要包含文件扩展名</string> <string name="title_info">用于文件的唯一描述性标题,它将作为文件名使用。您可以使用有空格的简明语言。请不要包含文件扩展名</string>
<string name="description_info">请尽可能详细地描述媒体:拍摄在何地?显示什么?例文是什么?请描述对象或个人。透露一些不易猜想到的信息,例如这幅风景画的具体日期时间。如果媒体显示了一些不寻常的事物,请说明为什么它显得不寻常。</string> <string name="description_info">请尽可能详细地描述媒体:拍摄在何地?显示什么?例文是什么?请描述对象或个人。透露一些不易猜想到的信息,例如这幅风景画的具体日期时间。如果媒体显示了一些不寻常的事物,请说明为什么它显得不寻常。</string>
<string name="upload_image_too_dark">此图片太暗,您确定要上传它么?维基共享资源只接受对百科全书有价值的图片。</string>
<string name="upload_image_blurry">此图片模糊不清,您确定要上传它么?维基共享资源只接受对百科全书有价值的图片。</string>
<string name="give_permission">提供权限</string> <string name="give_permission">提供权限</string>
<string name="use_external_storage">使用外部存储</string> <string name="use_external_storage">使用外部存储</string>
<string name="use_external_storage_summary">在您的设备上,使用应用中的照相机保存照片</string> <string name="use_external_storage_summary">在您的设备上,使用应用中的照相机保存照片</string>
<string name="login_to_your_account">登录您的账户</string>
<string name="send_log_file">发送日志文件</string> <string name="send_log_file">发送日志文件</string>
<string name="send_log_file_description">通过电子邮件将日志文件发送给开发人员</string> <string name="send_log_file_description">通过电子邮件将日志文件发送给开发人员</string>
<string name="login_to_your_account">登录您的账户</string>
<string name="nearby_location_has_not_changed">位置没有更新。</string> <string name="nearby_location_has_not_changed">位置没有更新。</string>
<string name="nearby_location_not_available">位置不可用。</string> <string name="nearby_location_not_available">位置不可用。</string>
<string name="location_permission_rationale_nearby">需要权限以显示附近地点列表</string> <string name="location_permission_rationale_nearby">需要权限以显示附近地点列表</string>

View file

@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="app_name">Commons</string> <string name="app_name">Commons</string>
<string name="bullet">&#8226; </string>
<string name="menu_settings">Settings</string> <string name="menu_settings">Settings</string>
<string name="username">Username</string> <string name="username">Username</string>
<string name="password">Password</string> <string name="password">Password</string>
<string name="login_credential">Log in to your Commons Beta account</string>
<string name="login">Log in</string> <string name="login">Log in</string>
<string name="signup">Sign up</string> <string name="signup">Sign up</string>
<string name="logging_in_title">Logging in</string> <string name="logging_in_title">Logging in</string>
@ -77,8 +79,8 @@
<string name="about_license">The Wikimedia Commons app is an open-source app created and maintained by grantees and volunteers of the Wikimedia community. The Wikimedia Foundation is not involved in the creation, development, or maintenance of the app. </string> <string name="about_license">The Wikimedia Commons app is an open-source app created and maintained by grantees and volunteers of the Wikimedia community. The Wikimedia Foundation is not involved in the creation, development, or maintenance of the app. </string>
<string name="trademarked_name" translatable="false">Wikimedia Commons</string> <string name="trademarked_name" translatable="false">Wikimedia Commons</string>
<string name="about_improve">Create a new &lt;a href=\"https://github.com/commons-app/apps-android-commons/issues\"&gt;GitHub issue&lt;/a&gt; for bug reports and suggestions.</string> <string name="about_improve">Create a new &lt;a href=\"https://github.com/commons-app/apps-android-commons/issues\"&gt;GitHub issue&lt;/a&gt; for bug reports and suggestions.</string>
<string name="about_privacy_policy">&lt;a href=\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\"&gt;Privacy policy&lt;/a&gt;</string> <string name="about_privacy_policy"><u>Privacy policy</u></string>
<string name="about_credits">&lt;a href=\"https://github.com/commons-app/apps-android-commons/blob/master/CREDITS\"&gt;Credits&lt;/a&gt;</string> <string name="about_credits"><u>Credits</u></string>
<string name="title_activity_about">About</string> <string name="title_activity_about">About</string>
<string name="menu_feedback">Send Feedback (via Email)</string> <string name="menu_feedback">Send Feedback (via Email)</string>
<string name="no_email_client">No email client installed</string> <string name="no_email_client">No email client installed</string>
@ -119,11 +121,20 @@
<string name="tutorial_1_text">Wikimedia Commons hosts most of the images that are used in Wikipedia.</string> <string name="tutorial_1_text">Wikimedia Commons hosts most of the images that are used in Wikipedia.</string>
<string name="tutorial_1_subtext">Your images help educate people around the world!</string> <string name="tutorial_1_subtext">Your images help educate people around the world!</string>
<string name="tutorial_2_text">Please upload pictures that are taken or created entirely by yourself:</string> <string name="tutorial_2_text">Please upload pictures that are taken or created entirely by yourself:</string>
<string name="tutorial_2_subtext">- Natural objects (flowers, animals, mountains)\n- Useful objects (bicycles, train stations)\n- Famous people (your mayor, Olympic athletes you met)</string> <string name="tutorial_2_subtext">Natural objects (flowers, animals, mountains)\n&#8226; Useful objects (bicycles, train stations)\n&#8226; Famous people (your mayor, Olympic athletes you met)</string>
<string name="tutorial_2_subtext_1">Natural objects (flowers, animals, mountains)</string>
<string name="tutorial_2_subtext_2">Useful objects (bicycles, train stations)</string>
<string name="tutorial_2_subtext_3">Famous people (your mayor, Olympic athletes you met)</string>
<string name="tutorial_3_text">Please do NOT upload:</string> <string name="tutorial_3_text">Please do NOT upload:</string>
<string name="tutorial_3_subtext">- Selfies or pictures of your friends\n- Pictures you downloaded from the Internet\n- Screenshots of proprietary apps</string> <string name="tutorial_3_subtext">- Selfies or pictures of your friends\n- Pictures you downloaded from the Internet\n- Screenshots of proprietary apps</string>
<string name="tutorial_3_subtext_1">Selfies or pictures of your friends</string>
<string name="tutorial_3_subtext_2">Pictures you downloaded from the Internet</string>
<string name="tutorial_3_subtext_3">Screenshots of proprietary apps</string>
<string name="tutorial_4_text">Example upload:</string> <string name="tutorial_4_text">Example upload:</string>
<string name="tutorial_4_subtext">- Title: Sydney Opera House\n- Description: Sydney Opera House as viewed from across the bay\n- Categories: Sydney Opera House from the west, Sydney Opera House remote views</string> <string name="tutorial_4_subtext">- Title: Sydney Opera House\n- Description: Sydney Opera House as viewed from across the bay\n- Categories: Sydney Opera House from the west, Sydney Opera House remote views</string>
<string name="tutorial_4_subtext_1">Title: Sydney Opera House</string>
<string name="tutorial_4_subtext_2">Description: Sydney Opera House as viewed from across the bay</string>
<string name="tutorial_4_subtext_3">Categories: Sydney Opera House from the west, Sydney Opera House remote views</string>
<string name="welcome_wikipedia_text">Contribute your images. Help Wikipedia articles come to life!</string> <string name="welcome_wikipedia_text">Contribute your images. Help Wikipedia articles come to life!</string>
<string name="welcome_wikipedia_subtext">Images on Wikipedia come from Wikimedia Commons.</string> <string name="welcome_wikipedia_subtext">Images on Wikipedia come from Wikimedia Commons.</string>
<string name="welcome_copyright_text">Your images help educate people around the world.</string> <string name="welcome_copyright_text">Your images help educate people around the world.</string>
@ -205,12 +216,15 @@
<string name="error_while_cache">Error while caching pictures</string> <string name="error_while_cache">Error while caching pictures</string>
<string name="title_info">A unique descriptive title for the file, which will serve as a filename. You may use plain language with spaces. Do not include the file extension</string> <string name="title_info">A unique descriptive title for the file, which will serve as a filename. You may use plain language with spaces. Do not include the file extension</string>
<string name="description_info">Please describe the media as much as possible: Where was it taken? What does it show? What is the context? Please describe the objects or persons. Reveal information that can not be easily guessed, for instance the time of day if it is a landscape. If the media shows something unusual, please explain what makes it unusual.</string> <string name="description_info">Please describe the media as much as possible: Where was it taken? What does it show? What is the context? Please describe the objects or persons. Reveal information that can not be easily guessed, for instance the time of day if it is a landscape. If the media shows something unusual, please explain what makes it unusual.</string>
<string name="upload_image_too_dark">This picture is too dark, are you sure you want to upload it? Wikimedia Commons is only for pictures with encyclopedic value.</string>
<string name="upload_image_blurry">This picture is blurry, are you sure you want to upload it? Wikimedia Commons is only for pictures with encyclopedic value.</string>
<string name="give_permission">Give permission</string> <string name="give_permission">Give permission</string>
<string name="use_external_storage">Use external storage</string> <string name="use_external_storage">Use external storage</string>
<string name="use_external_storage_summary">Save pictures taken with the in-app camera on your device</string> <string name="use_external_storage_summary">Save pictures taken with the in-app camera on your device</string>
<string name="login_to_your_account">Login to your account</string>
<string name="send_log_file">Send log file</string> <string name="send_log_file">Send log file</string>
<string name="send_log_file_description">Send log file to developers via email</string> <string name="send_log_file_description">Send log file to developers via email</string>
<string name="login_to_your_account">Login to your account</string> <string name="null_url">Error! URL not found</string>
<string name="nearby_location_has_not_changed">Location has not changed.</string> <string name="nearby_location_has_not_changed">Location has not changed.</string>
<string name="nearby_location_not_available">Location not available.</string> <string name="nearby_location_not_available">Location not available.</string>

Some files were not shown because too many files have changed in this diff Show more