diff --git a/.travis.yml b/.travis.yml
index d9abeedbe..3d330c506 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,54 +1,55 @@
language: android
-
addons:
apt:
packages:
- - w3m
-
+ - w3m
env:
global:
- - ANDROID_TARGET=android-22
- - ANDROID_ABI=armeabi-v7a
- - ADB_INSTALL_TIMEOUT=12 # in minutes
-
+ - ANDROID_TARGET=android-22
+ - ANDROID_ABI=armeabi-v7a
+ - ADB_INSTALL_TIMEOUT=12
+ - secure: okdkna5DaH/2Fay9vI6Enrx7u9UwRm4/IJXvcaWJcvjF3JTsLQr0r+dlMT2X5E1GsNk4WcoGcfZJcVonULkaW4S96B43g3EyevWbLFWjii0cMUO00OshToKyboSvNUf+d5B6rghrbnxTIBNel2ZBFj8MXHdtz6Az20q8VywqPeBZupo7olyKKS1nYdvoo7ypNScVjDGEjEPonWplztYlSDT1w81Vww4kF9oiOPEzDOPw1lOiD8FTyKLXhK0WYlnc3cnyFjZwVMlKcomnFYPfe/J2zO6OP/XInxYSXRkZ6wiOC5gMPYAYanUAuzm91vsTBQMk6jMCglSM9Nl6dPusGgEqOyTwLVALlgvS3km9HNVsHuVJhU+bmJ6scFBWrAOhbsV2ioSEsQ8NgU0Zv1SC0wN9ZruF4ae03Re+k+eHgwA3taZXrT2pvkkSmfRex6oFZReypcPGFQYiHo31NsO39WPRYYxr4edYisVXw75x/BJyOcUULhG1YmwHYYeXOzbNp0Sf9ADtUDi0oip/BO2tkLxbE+z1GJSmC83fX2YpoK+IwDHNm+4w8OJAJBvdxA3Q4HrJBAbd8jnQYP+sBBaki8t5WuwJmfOucx0vgKJ7pzqRY/MOUVe/dACnjLgFDLuS7MMqr6xU/oMM6/rrt4209tL+GQbn/R98UKtmMRRq1hY=
jdk:
- - oraclejdk8
-
+- oraclejdk8
android:
components:
- - tools
- - platform-tools
- - build-tools-27.0.3
- - extra-google-m2repository
- - extra-android-m2repository
- - android-22
- - android-27
- - sys-img-${ANDROID_ABI}-${ANDROID_TARGET}
+ - tools
+ - platform-tools
+ - build-tools-27.0.3
+ - extra-google-m2repository
+ - extra-android-m2repository
+ - android-22
+ - android-27
+ - sys-img-${ANDROID_ABI}-${ANDROID_TARGET}
licenses:
- - 'android-sdk-license-.+'
-
+ - android-sdk-license-.+
before_script:
- - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI
- - emulator -avd test -no-audio -no-window -no-boot-anim &
- - android-wait-for-emulator
-
+- echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI
+- emulator -avd test -no-audio -no-window -no-boot-anim &
+- android-wait-for-emulator
script:
- - ./gradlew clean check connectedCheck jacocoTestReport
-
+- "./gradlew clean check connectedCheck jacocoTestReport"
+- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
+ ./gradlew publishProdReleaseApk;
+ fi
after_success:
- - bash <(curl -s https://codecov.io/bash)
-
+- bash <(curl -s https://codecov.io/bash)
after_failure:
- - echo '*** Debug Unit Test Results ***'
- - w3m -dump ${TRAVIS_BUILD_DIR}/app/build/reports/tests/*/classes/*Test.html
- - echo '*** Connected Test Results ***'
- - w3m -dump ${TRAVIS_BUILD_DIR}/app/build/reports/androidTests/connected/flavors/*/*Test.html
-
+- echo '*** Debug Unit Test Results ***'
+- w3m -dump ${TRAVIS_BUILD_DIR}/app/build/reports/tests/*/classes/*Test.html
+- echo '*** Connected Test Results ***'
+- w3m -dump ${TRAVIS_BUILD_DIR}/app/build/reports/androidTests/connected/flavors/*/*Test.html
before_cache:
- - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- - rm -fr $HOME/.gradle/caches/*/plugin-resolution/
-
+- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
+- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- - $HOME/.gradle/caches/
- - $HOME/.gradle/wrapper/
+ - "$HOME/.gradle/caches/"
+ - "$HOME/.gradle/wrapper/"
+before_install:
+- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
+ openssl aes-256-cbc -K $encrypted_7b5c925cc32c_key -iv $encrypted_7b5c925cc32c_iv -in nr-commons.keystore.enc -out nr-commons.keystore -d;
+ fi
+- if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$TRAVIS_BRANCH" == "master" ]; then
+ openssl aes-256-cbc -K $encrypted_38ac1a5053f6_key -iv $encrypted_38ac1a5053f6_iv -in play.p12.enc -out play.p12 -d;
+ fi
diff --git a/README.md b/README.md
index 28b923351..54649a830 100644
--- a/README.md
+++ b/README.md
@@ -11,37 +11,13 @@ Initially started by the Wikimedia Foundation, this app is now maintained by gra
## Documentation
-We try to have an extensive documentation at [our wiki here at Github][5]:
+We try to have an extensive documentation at [our wiki here at Github][4]:
-* [User Documentation][6]
-* [Contributor Documentation][7]
- * [Volunteers Welcome!][9]
+* [User Documentation][5]
+* [Contributor Documentation][6]
+ * [Volunteers Welcome!][7]
* [Developer Documentation][8]
-
-## Libraries Used ##
-
-* [Picasso][11]
-* [RSS-Parser][12]
-* [ViewPagerIndicator][13]
-* [PhotoView][14]
-* [Acra][15]
-* [Renderers][16]
-* [Gson][17]
-* [Timber][18]
-* [Java-String-Similarity][19]
-* [ReadMoreTextView][20]
-* [MaterialShowcaseView][21]
-* [Butterknife][22]
-* [OKHttp][23]
-* [Okio][24]
-* [RxJava][25]
-* [JSoup][26]
-* [Fresco][27]
-* [Stetho][28]
-* [Dagger][29]
-* [Java-HTTP-Fluent][30]
-* [CircleProgressBar][31]
-* [Leak Canary][32]
+ * [Libraries Used][9]
## Contributors ##
@@ -60,37 +36,18 @@ Thank you all for your work!
## License ##
-This software is open source, licensed under the [Apache License 2.0][4].
-
+This software is open source, licensed under the [Apache License 2.0][10].
[1]: https://play.google.com/store/apps/details?id=fr.free.nrw.commons
[2]: https://commons-app.github.io/
[3]: https://github.com/commons-app/apps-android-commons/issues
-[4]: https://www.apache.org/licenses/LICENSE-2.0
-[5]: https://github.com/commons-app/apps-android-commons/wiki
-[6]: https://github.com/commons-app/apps-android-commons/wiki#user-documentation
-[7]: https://github.com/commons-app/apps-android-commons/wiki#contributor-documentation
+
+[4]: https://github.com/commons-app/apps-android-commons/wiki
+[5]: https://github.com/commons-app/apps-android-commons/wiki#user-documentation
+[6]: https://github.com/commons-app/apps-android-commons/wiki#contributor-documentation
+[7]: https://github.com/commons-app/apps-android-commons/wiki/Volunteers-welcome%21
[8]: https://github.com/commons-app/apps-android-commons/wiki#developer-documentation
-[9]: https://github.com/commons-app/apps-android-commons/wiki/Volunteers-welcome%21
-[10]: https://meta.wikimedia.org/wiki/Grants:Project/Improve_%27Upload_to_Commons%27_Android_App/Renewal
-[11]: https://github.com/square/picasso
-[13]: https://github.com/avianey/Android-ViewPagerIndicator
-[14]: https://github.com/chrisbanes/PhotoView
-[15]: https://github.com/ACRA/acra
-[16]: https://github.com/pedrovgs/Renderers
-[17]: https://github.com/google/gson
-[18]: https://github.com/JakeWharton/timber
-[19]: https://github.com/tdebatty/java-string-similarity
-[20]: https://github.com/bravoborja/ReadMoreTextView
-[21]: https://github.com/deano2390/MaterialShowcaseView
-[22]: https://github.com/JakeWharton/butterknife
-[23]: https://github.com/square/okhttp
-[24]: https://github.com/square/okio
-[25]: https://github.com/ReactiveX/RxJava
-[27]: https://github.com/facebook/fresco
-[28]: https://github.com/facebook/stetho
-[29]: https://github.com/google/dagger
-[30]: https://github.com/yuvipanda/java-http-fluent/blob/master/src/main/java/in/yuvi/http/fluent/Http.java
-[31]: https://github.com/dinuscxj/CircleProgressBar
-[32]: https://github.com/square/leakcanary
+[9]: https://github.com/commons-app/apps-android-commons/wiki/Libraries-used
+
+[10]: https://www.apache.org/licenses/LICENSE-2.0
diff --git a/app/build.gradle b/app/build.gradle
index bff2a631b..9accea101 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -5,83 +5,90 @@ apply plugin: 'kotlin-kapt'
apply plugin: 'jacoco-android'
apply from: 'quality.gradle'
+def isRunningOnTravisAndIsNotPRBuild = System.getenv("CI") == "true" && file('../play.p12').exists()
+
+if(isRunningOnTravisAndIsNotPRBuild) {
+ apply plugin: 'com.github.triplet.play'
+}
+
dependencies {
+ // Utils
implementation 'com.github.nicolas-raoul:Quadtree:ac16ea8035bf07'
- implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
- implementation 'in.yuvi:http.fluent:1.3'
- implementation 'com.github.chrisbanes:PhotoView:2.0.0'
-
- implementation 'ch.acra:acra:4.9.2'
-
- implementation 'org.mediawiki:api:1.3'
implementation 'commons-codec:commons-codec:1.10'
- implementation 'com.github.pedrovgs:renderers:3.3.3'
implementation 'com.google.code.gson:gson:2.8.5'
- implementation 'com.jakewharton.timber:timber:4.4.0'
implementation 'info.debatty:java-string-similarity:0.24'
- implementation 'com.borjabravo:readmoretextview:2.1.0'
-
- implementation 'com.android.support.constraint:constraint-layout:1.1.3'
-
- implementation 'org.slf4j:slf4j-api:1.7.25'
- api ("com.github.tony19:logback-android-classic:1.1.1-6") {
- exclude group: 'com.google.android', module: 'android'
- }
-
- implementation('com.mapbox.mapboxsdk:mapbox-android-sdk:5.5.0@aar') {
- transitive = true
- }
- implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
-
- //noinspection GradleCompatible
- implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION"
- implementation "com.android.support:appcompat-v7:$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.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
- kapt "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
+ implementation 'in.yuvi:http.fluent:1.3'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okio:okio:1.14.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
- // 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.
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
implementation 'com.facebook.fresco:fresco:1.10.0'
- implementation 'com.facebook.stetho:stetho:1.5.0'
+
+ // UI
+ implementation 'fr.avianey.com.viewpagerindicator:library:2.4.1.1@aar'
+ implementation 'com.github.chrisbanes:PhotoView:2.0.0'
+ implementation 'com.github.pedrovgs:renderers:3.3.3'
+
+ implementation 'com.mapzen.android:lost:3.0.4'
+ implementation('com.mapbox.mapboxsdk:mapbox-android-sdk:5.5.0@aar') {
+ transitive = true
+ }
+ implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0'
+ implementation 'com.dinuscxj:circleprogressbar:1.1.1'
+ implementation 'com.karumi:dexter:5.0.0'
+ implementation files('libs/simplemagic-1.9.jar')
+ implementation "com.jakewharton:butterknife:$BUTTERKNIFE_VERSION"
+ kapt "com.jakewharton:butterknife-compiler:$BUTTERKNIFE_VERSION"
+
+ // Logging
+ implementation 'ch.acra:acra:4.9.2'
+ implementation 'com.jakewharton.timber:timber:4.4.0'
+ implementation 'org.slf4j:slf4j-api:1.7.25'
+ api ("com.github.tony19:logback-android-classic:1.1.1-6") {
+ exclude group: 'com.google.android', module: 'android'
+ }
+
+ // Dependency injector
implementation "com.google.dagger:dagger:$DAGGER_VERSION"
implementation "com.google.dagger:dagger-android-support:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-android-processor:$DAGGER_VERSION"
kapt "com.google.dagger:dagger-compiler:$DAGGER_VERSION"
+
+ // Unit testing
testImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
testImplementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
testImplementation 'junit:junit:4.12'
testImplementation 'org.robolectric:robolectric:3.7.1'
testImplementation 'com.nhaarman:mockito-kotlin:1.5.0'
testImplementation 'com.squareup.okhttp3:mockwebserver:3.10.0'
- implementation 'com.dinuscxj:circleprogressbar:1.1.1'
-
- implementation 'com.tspoon.traceur:traceur:1.0.1'
+ // Android testing
androidTestImplementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.10.0'
- androidTestImplementation "com.android.support:support-annotations:$SUPPORT_LIB_VERSION"
androidTestImplementation 'com.android.support.test:rules:1.0.2'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation "com.android.support:support-annotations:$SUPPORT_LIB_VERSION"
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+ androidTestImplementation "org.mockito:mockito-core:2.10.0"
+
+ // Debugging
+ implementation 'com.tspoon.traceur:traceur:1.0.1'
+ implementation 'com.facebook.stetho:stetho:1.5.0'
debugImplementation "com.squareup.leakcanary:leakcanary-android:$LEAK_CANARY"
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY"
testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$LEAK_CANARY"
- //For handling runtime permissions
- implementation 'com.karumi:dexter:5.0.0'
-
- implementation files('libs/simplemagic-1.9.jar')
+ // Support libraries
+ implementation "com.android.support:support-v4:$SUPPORT_LIB_VERSION"
+ implementation "com.android.support:appcompat-v7:$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.constraint:constraint-layout:1.1.3'
}
android {
@@ -101,6 +108,8 @@ android {
}
testOptions {
+ unitTests.returnDefaultValues = true
+
unitTests.all {
jvmArgs '-noverify'
}
@@ -115,11 +124,18 @@ android {
test.resources.srcDirs += 'src/main/resoures'
}
+ signingConfigs {
+ release
+ }
+
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
testProguardFile 'test-proguard-rules.txt'
+ if(isRunningOnTravisAndIsNotPRBuild) {
+ signingConfig signingConfigs.release
+ }
}
debug {
minifyEnabled true
@@ -129,6 +145,14 @@ android {
versionNameSuffix "-debug-" + getBranchName() + "~" + getBuildVersion()
}
}
+
+ if (isRunningOnTravisAndIsNotPRBuild) {
+ // configure keystore based on env vars in Travis for automated alpha builds
+ signingConfigs.release.storeFile = file("../nr-commons.keystore")
+ signingConfigs.release.storePassword = System.getenv("keystore_password")
+ signingConfigs.release.keyAlias = System.getenv("key_alias")
+ signingConfigs.release.keyPassword = System.getenv("key_password")
+ }
flavorDimensions 'tier'
productFlavors {
@@ -204,3 +228,17 @@ android {
buildToolsVersion buildToolsVersion
}
+
+if(isRunningOnTravisAndIsNotPRBuild) {
+ play {
+ track = "alpha"
+ userFraction = 1
+ serviceAccountEmail = System.getenv("SERVICE_ACCOUNT_NAME")
+ serviceAccountCredentials = file("../play.p12")
+
+ resolutionStrategy = "auto"
+ outputProcessor { // this: ApkVariantOutput
+ versionNameOverride = "$versionNameOverride.$versionCode"
+ }
+ }
+}
diff --git a/app/src/betaDebug/ic_launcher-web.png b/app/src/betaDebug/ic_launcher-web.png
new file mode 100644
index 000000000..5b1546360
Binary files /dev/null and b/app/src/betaDebug/ic_launcher-web.png differ
diff --git a/app/src/betaDebug/res/drawable-hdpi/ic_launcher.png b/app/src/betaDebug/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 46c0a4202..000000000
Binary files a/app/src/betaDebug/res/drawable-hdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/betaDebug/res/drawable-mdpi/ic_launcher.png b/app/src/betaDebug/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 2e5499676..000000000
Binary files a/app/src/betaDebug/res/drawable-mdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/betaDebug/res/drawable-xhdpi/ic_launcher.png b/app/src/betaDebug/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 0f0c702ed..000000000
Binary files a/app/src/betaDebug/res/drawable-xhdpi/ic_launcher.png and /dev/null differ
diff --git a/app/src/betaDebug/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/betaDebug/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/app/src/betaDebug/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/betaDebug/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/betaDebug/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..036d09bc5
--- /dev/null
+++ b/app/src/betaDebug/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/betaDebug/res/mipmap-hdpi/ic_launcher.png b/app/src/betaDebug/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..90c044ccd
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/betaDebug/res/mipmap-hdpi/ic_launcher_foreground.png b/app/src/betaDebug/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..f826d5544
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-hdpi/ic_launcher_foreground.png differ
diff --git a/app/src/betaDebug/res/mipmap-hdpi/ic_launcher_round.png b/app/src/betaDebug/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..9b273c43f
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/betaDebug/res/mipmap-mdpi/ic_launcher.png b/app/src/betaDebug/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..b09b8d252
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/betaDebug/res/mipmap-mdpi/ic_launcher_foreground.png b/app/src/betaDebug/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..5002ec69d
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-mdpi/ic_launcher_foreground.png differ
diff --git a/app/src/betaDebug/res/mipmap-mdpi/ic_launcher_round.png b/app/src/betaDebug/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..9aa2611ba
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher.png b/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..d7b349b4d
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher_foreground.png b/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..9297963fd
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..59b088069
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher.png b/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..d473d0aed
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher_foreground.png b/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..aeb616311
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..0b7797049
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..e88874931
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 000000000..fa5017d72
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ
diff --git a/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..00a9e4bd5
Binary files /dev/null and b/app/src/betaDebug/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/betaDebug/res/values/ic_launcher_background.xml b/app/src/betaDebug/res/values/ic_launcher_background.xml
new file mode 100644
index 000000000..c5d5899fd
--- /dev/null
+++ b/app/src/betaDebug/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+
+
+ #FFFFFF
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ad76ee14d..559470c84 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -24,7 +24,7 @@
@@ -44,7 +44,7 @@
@@ -65,7 +65,7 @@
diff --git a/app/src/main/ic_launcher-web.png b/app/src/main/ic_launcher-web.png
new file mode 100644
index 000000000..c7f0bc3fe
Binary files /dev/null and b/app/src/main/ic_launcher-web.png differ
diff --git a/app/src/main/java/fr/free/nrw/commons/BasePresenter.java b/app/src/main/java/fr/free/nrw/commons/BasePresenter.java
new file mode 100644
index 000000000..041fde6b2
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/BasePresenter.java
@@ -0,0 +1,16 @@
+package fr.free.nrw.commons;
+
+/**
+ * Base presenter, enforcing contracts to atach and detach view
+ */
+public interface BasePresenter {
+ /**
+ * Until a view is attached, it is open to listen events from the presenter
+ */
+ void onAttachView(MvpView view);
+
+ /**
+ * Detaching a view makes sure that the view no more receives events from the presenter
+ */
+ void onDetachView();
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java
index d874bae40..61beb9a6b 100644
--- a/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java
+++ b/app/src/main/java/fr/free/nrw/commons/CommonsApplication.java
@@ -91,6 +91,7 @@ public class CommonsApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
+ ACRA.init(this);
if (BuildConfig.DEBUG) {
//FIXME: Traceur should be disabled for release builds until error fixed
//See https://github.com/commons-app/apps-android-commons/issues/1877
@@ -118,8 +119,7 @@ public class CommonsApplication extends Application {
// Empty temp directory in case some temp files are created and never removed.
ContributionUtils.emptyTemporaryDirectory();
- initAcra();
- if (BuildConfig.DEBUG) {
+ if (BuildConfig.DEBUG && !isRoboUnitTest()) {
Stetho.initializeWithDefaults(this);
}
@@ -152,14 +152,8 @@ public class CommonsApplication extends Application {
Timber.plant(new Timber.DebugTree());
}
- /**
- * Remove ACRA's UncaughtExceptionHandler
- * We do this because ACRA's handler spawns a new process possibly screwing up with a few things
- */
- private void initAcra() {
- Thread.UncaughtExceptionHandler exceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
- ACRA.init(this);
- Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
+ public static boolean isRoboUnitTest() {
+ return "robolectric".equals(Build.FINGERPRINT);
}
private ThreadPoolService getFileLoggingThreadPool() {
diff --git a/app/src/main/java/fr/free/nrw/commons/MvpView.java b/app/src/main/java/fr/free/nrw/commons/MvpView.java
new file mode 100644
index 000000000..7485b2aaf
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/MvpView.java
@@ -0,0 +1,8 @@
+package fr.free.nrw.commons;
+
+/**
+ * Base interface for all the views
+ */
+public interface MvpView {
+ void showMessage(String message);
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.java b/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.java
index 109d115d4..21bc8af20 100644
--- a/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.java
+++ b/app/src/main/java/fr/free/nrw/commons/WelcomeActivity.java
@@ -2,20 +2,33 @@ package fr.free.nrw.commons;
import android.content.Context;
import android.content.Intent;
+import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
+import android.view.View;
import com.viewpagerindicator.CirclePageIndicator;
+import javax.inject.Inject;
+import javax.inject.Named;
+
import butterknife.BindView;
import butterknife.ButterKnife;
+import butterknife.OnClick;
+import butterknife.Optional;
import fr.free.nrw.commons.quiz.QuizActivity;
import fr.free.nrw.commons.theme.BaseActivity;
public class WelcomeActivity extends BaseActivity {
- @BindView(R.id.welcomePager) ViewPager pager;
- @BindView(R.id.welcomePagerIndicator) CirclePageIndicator indicator;
+ @Inject
+ @Named("application_preferences")
+ SharedPreferences prefs;
+
+ @BindView(R.id.welcomePager)
+ ViewPager pager;
+ @BindView(R.id.welcomePagerIndicator)
+ CirclePageIndicator indicator;
private WelcomePagerAdapter adapter = new WelcomePagerAdapter();
private boolean isQuiz;
@@ -38,15 +51,20 @@ public class WelcomeActivity extends BaseActivity {
if (bundle != null) {
isQuiz = bundle.getBoolean("isQuiz");
}
- } else{
+ } else {
isQuiz = false;
}
+ // Enable skip button if beta flavor
+ if (BuildConfig.FLAVOR == "beta") {
+ findViewById(R.id.finishTutorialButton).setVisibility(View.VISIBLE);
+ }
+
ButterKnife.bind(this);
pager.setAdapter(adapter);
indicator.setViewPager(pager);
- adapter.setCallback(this::finish);
+ adapter.setCallback(this::finishTutorial);
}
/**
@@ -54,7 +72,7 @@ public class WelcomeActivity extends BaseActivity {
*/
@Override
public void onDestroy() {
- if (isQuiz){
+ if (isQuiz) {
Intent i = new Intent(WelcomeActivity.this, QuizActivity.class);
startActivity(i);
}
@@ -71,4 +89,22 @@ public class WelcomeActivity extends BaseActivity {
Intent welcomeIntent = new Intent(context, WelcomeActivity.class);
context.startActivity(welcomeIntent);
}
+
+ /**
+ * Override onBackPressed() to go to previous tutorial 'pages' if not on first page
+ */
+ @Override
+ public void onBackPressed() {
+ if (pager.getCurrentItem() != 0) {
+ pager.setCurrentItem(pager.getCurrentItem() - 1, true);
+ } else {
+ finish();
+ }
+ }
+
+ @OnClick(R.id.finishTutorialButton)
+ public void finishTutorial() {
+ prefs.edit().putBoolean("firstrun", false).apply();
+ finish();
+ }
}
diff --git a/app/src/main/java/fr/free/nrw/commons/WelcomePagerAdapter.java b/app/src/main/java/fr/free/nrw/commons/WelcomePagerAdapter.java
index f2c6d1054..4776abfe4 100644
--- a/app/src/main/java/fr/free/nrw/commons/WelcomePagerAdapter.java
+++ b/app/src/main/java/fr/free/nrw/commons/WelcomePagerAdapter.java
@@ -14,7 +14,7 @@ import butterknife.OnClick;
import butterknife.Optional;
public class WelcomePagerAdapter extends PagerAdapter {
- static final int[] PAGE_LAYOUTS = new int[]{
+ private static final int[] PAGE_LAYOUTS = new int[]{
R.layout.welcome_wikipedia,
R.layout.welcome_do_upload,
R.layout.welcome_dont_upload,
@@ -57,29 +57,31 @@ public class WelcomePagerAdapter extends PagerAdapter {
@Override
public Object instantiateItem(ViewGroup container, int position) {
- this.container=container;
+ this.container = container;
LayoutInflater inflater = LayoutInflater.from(container.getContext());
ViewGroup layout = (ViewGroup) inflater.inflate(PAGE_LAYOUTS[position], container, false);
- if (BuildConfig.FLAVOR == "beta") {
- TextView textView = layout.findViewById(R.id.welcomeYesButton);
- if (textView.getVisibility() != View.VISIBLE) {
- textView.setVisibility(View.VISIBLE);
- }
- ViewHolder holder = new ViewHolder(layout);
- layout.setTag(holder);
- if (position == PAGE_FINAL){
- TextView moreInfo = layout.findViewById(R.id.welcomeInfo);
- moreInfo.setText(Html.fromHtml(WelcomeActivity.moreInformation));
- ViewHolder holder1 = new ViewHolder(layout);
- layout.setTag(holder1);
- }
- } else {
- if (position == PAGE_FINAL) {
- ViewHolder holder = new ViewHolder(layout);
- layout.setTag(holder);
- }
+ // If final page
+ if (position == PAGE_FINAL) {
+ // Add link to more information
+ TextView moreInfo = layout.findViewById(R.id.welcomeInfo);
+ moreInfo.setText(Html.fromHtml(WelcomeActivity.moreInformation));
+ moreInfo.setOnClickListener(view -> {
+ try {
+ Utils.handleWebUrl(
+ container.getContext(),
+ Uri.parse("https://commons.wikimedia.org/wiki/Help:Contents")
+ );
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ });
+
+ // Handle click of finishTutorialButton ("YES!" button) inside layout
+ layout.findViewById(R.id.finishTutorialButton)
+ .setOnClickListener(view -> callback.finishTutorial());
}
+
container.addView(layout);
return layout;
}
@@ -96,33 +98,6 @@ public class WelcomePagerAdapter extends PagerAdapter {
}
public interface Callback {
- void onYesClicked();
- }
-
- class ViewHolder {
- ViewHolder(View view) {
- ButterKnife.bind(this, view);
- }
-
- /**
- * Triggers on click callback on button click
- */
- @OnClick(R.id.welcomeYesButton)
- void onClicked() {
- if (callback != null) {
- callback.onYesClicked();
- }
- }
-
- @Optional
- @OnClick(R.id.welcomeInfo)
- void onHelpClicked () {
- try {
- Utils.handleWebUrl(container.getContext(),Uri.parse("https://commons.wikimedia.org/wiki/Help:Contents" ));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
+ void finishTutorial();
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java
index f4d5dd7c9..320a896eb 100644
--- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java
+++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java
@@ -177,7 +177,6 @@ public class LoginActivity extends AccountAuthenticatorActivity {
super.onResume();
if (prefs.getBoolean("firstrun", true)) {
WelcomeActivity.startYourself(this);
- prefs.edit().putBoolean("firstrun", false).apply();
}
if (sessionManager.getCurrentAccount() != null
@@ -215,6 +214,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
loginCurrentlyInProgress = true;
Timber.d("Login to start!");
final String username = canonicializeUsername(usernameEdit.getText().toString());
+ final String rawUsername = Utils.capitalize(usernameEdit.getText().toString().trim());
final String password = passwordEdit.getText().toString();
String twoFactorCode = twoFactorEdit.getText().toString();
@@ -222,7 +222,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
Observable.fromCallable(() -> login(username, password, twoFactorCode))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe(result -> handleLogin(username, password, result));
+ .subscribe(result -> handleLogin(username, rawUsername, password, result));
}
private String login(String username, String password, String twoFactorCode) {
@@ -238,10 +238,10 @@ public class LoginActivity extends AccountAuthenticatorActivity {
}
}
- private void handleLogin(String username, String password, String result) {
+ private void handleLogin(String username, String rawUsername, String password, String result) {
Timber.d("Login done!");
if (result.equals("PASS")) {
- handlePassResult(username, password);
+ handlePassResult(username, rawUsername , password);
} else {
loginCurrentlyInProgress = false;
errorMessageShown = true;
@@ -259,7 +259,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
progressDialog.show();
}
- private void handlePassResult(String username, String password) {
+ private void handlePassResult(String username, String rawUsername, String password) {
showSuccessAndDismissDialog();
requestAuthToken();
AccountAuthenticatorResponse response = null;
@@ -276,7 +276,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
}
}
- sessionManager.createAccount(response, username, password);
+ sessionManager.createAccount(response, username, rawUsername, password);
startMainActivity();
}
diff --git a/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java b/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java
index e8745e25b..20cd06ed8 100644
--- a/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java
+++ b/app/src/main/java/fr/free/nrw/commons/auth/SessionManager.java
@@ -28,7 +28,8 @@ public class SessionManager {
private final MediaWikiApi mediaWikiApi;
private Account currentAccount; // Unlike a savings account... ;-)
private SharedPreferences sharedPreferences;
-
+ private static final String KEY_RAWUSERNAME = "rawusername";
+ private Bundle userdata = new Bundle();
public SessionManager(Context context,
MediaWikiApi mediaWikiApi,
@@ -44,13 +45,15 @@ public class SessionManager {
*
* @param response
* @param username
+ * @param rawusername
* @param password
*/
public void createAccount(@Nullable AccountAuthenticatorResponse response,
- String username, String password) {
+ String username, String rawusername, String password) {
Account account = new Account(username, BuildConfig.ACCOUNT_TYPE);
- boolean created = accountManager().addAccountExplicitly(account, password, null);
+ userdata.putString(KEY_RAWUSERNAME, rawusername);
+ boolean created = accountManager().addAccountExplicitly(account, password, userdata);
Timber.d("account creation " + (created ? "successful" : "failure"));
@@ -97,6 +100,17 @@ public class SessionManager {
return account == null ? null : account.name;
}
+ @Nullable
+ public String getRawUserName() {
+ Account account = getCurrentAccount();
+ return account == null ? null : accountManager().getUserData(account, KEY_RAWUSERNAME);
+ }
+
+ public String getAuthorName(){
+ return getRawUserName() == null ? getUserName() : getRawUserName();
+ }
+
+
@Nullable
public String getPassword() {
Account account = getCurrentAccount();
diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsFragment.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsFragment.java
index 5d67c3093..c5c445cee 100644
--- a/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsFragment.java
@@ -34,6 +34,8 @@ import timber.log.Timber;
import static android.app.Activity.RESULT_OK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_PREF;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCATION;
public class BookmarkLocationsFragment extends DaggerFragment {
@@ -136,13 +138,14 @@ public class BookmarkLocationsFragment extends DaggerFragment {
if (resultCode == RESULT_OK) {
Timber.d("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
requestCode, resultCode, data);
- String wikidataEntityId = directPrefs.getString("WikiDataEntityId", null);
+ String wikidataEntityId = directPrefs.getString(WIKIDATA_ENTITY_ID_PREF, null);
+ String wikidataItemLocation = directPrefs.getString(WIKIDATA_ITEM_LOCATION, null);
if (requestCode == ContributionController.SELECT_FROM_CAMERA) {
// If coming from camera, pass null as uri. Because camera photos get saved to a
// fixed directory
- contributionController.handleImagePicked(requestCode, null, true, wikidataEntityId);
+ contributionController.handleImagePicked(requestCode, null, true, wikidataEntityId, wikidataItemLocation);
} else {
- contributionController.handleImagePicked(requestCode, data.getData(), true, wikidataEntityId);
+ contributionController.handleImagePicked(requestCode, data.getData(), true, wikidataEntityId, wikidataItemLocation);
}
} else {
Timber.e("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
diff --git a/app/src/main/java/fr/free/nrw/commons/campaigns/Campaign.java b/app/src/main/java/fr/free/nrw/commons/campaigns/Campaign.java
new file mode 100644
index 000000000..2bd4893b8
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/campaigns/Campaign.java
@@ -0,0 +1,55 @@
+package fr.free.nrw.commons.campaigns;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * A data class to hold a campaign
+ */
+public class Campaign {
+
+ @SerializedName("title") private String title;
+ @SerializedName("description") private String description;
+ @SerializedName("startDate") private String startDate;
+ @SerializedName("endDate") private String endDate;
+ @SerializedName("link") private String link;
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getStartDate() {
+ return startDate;
+ }
+
+ public void setStartDate(String startDate) {
+ this.startDate = startDate;
+ }
+
+ public String getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(String endDate) {
+ this.endDate = endDate;
+ }
+
+ public String getLink() {
+ return link;
+ }
+
+ public void setLink(String link) {
+ this.link = link;
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignConfig.java b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignConfig.java
new file mode 100644
index 000000000..a715aaf63
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignConfig.java
@@ -0,0 +1,12 @@
+package fr.free.nrw.commons.campaigns;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * A data class to hold the campaign configs
+ */
+class CampaignConfig {
+
+ @SerializedName("showOnlyLiveCampaigns") private boolean showOnlyLiveCampaigns;
+ @SerializedName("sortBy") private String sortBy;
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignResponseDTO.java b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignResponseDTO.java
new file mode 100644
index 000000000..dd0bd51ce
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignResponseDTO.java
@@ -0,0 +1,24 @@
+package fr.free.nrw.commons.campaigns;
+
+import com.google.gson.annotations.SerializedName;
+import java.util.List;
+
+/**
+ * Data class to hold the response from the campaigns api
+ */
+public class CampaignResponseDTO {
+
+ @SerializedName("config")
+ private CampaignConfig campaignConfig;
+
+ @SerializedName("campaigns")
+ private List campaigns;
+
+ public CampaignConfig getCampaignConfig() {
+ return campaignConfig;
+ }
+
+ public List getCampaigns() {
+ return campaigns;
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignView.java b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignView.java
new file mode 100644
index 000000000..dec62cc1b
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignView.java
@@ -0,0 +1,110 @@
+package fr.free.nrw.commons.campaigns;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import fr.free.nrw.commons.R;
+import fr.free.nrw.commons.contributions.MainActivity;
+import fr.free.nrw.commons.utils.SwipableCardView;
+import fr.free.nrw.commons.utils.ViewUtil;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * A view which represents a single campaign
+ */
+public class CampaignView extends SwipableCardView {
+ Campaign campaign = null;
+ private ViewHolder viewHolder;
+
+ public CampaignView(@NonNull Context context) {
+ super(context);
+ init();
+ }
+
+ public CampaignView(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ init();
+ }
+
+ public CampaignView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init();
+ }
+
+ public void setCampaign(Campaign campaign) {
+ this.campaign = campaign;
+ if (campaign != null) {
+ this.setVisibility(View.VISIBLE);
+ viewHolder.init();
+ } else {
+ this.setVisibility(View.GONE);
+ }
+ }
+
+ @Override public boolean onSwipe(View view) {
+ view.setVisibility(View.GONE);
+ ((MainActivity) getContext()).prefs.edit()
+ .putBoolean("displayCampaignsCardView", false)
+ .apply();
+ ViewUtil.showLongToast(getContext(),
+ getResources().getString(R.string.nearby_campaign_dismiss_message));
+ return true;
+ }
+
+ private void init() {
+ View rootView = inflate(getContext(), R.layout.layout_campagin, this);
+ viewHolder = new ViewHolder(rootView);
+ setOnClickListener(view -> {
+ if (campaign != null) {
+ showCampaignInBrowser(campaign.getLink());
+ }
+ });
+ }
+
+ /**
+ * open the url associated with the campaign in the system's default browser
+ */
+ private void showCampaignInBrowser(String link) {
+ Intent view = new Intent();
+ view.setAction(Intent.ACTION_VIEW);
+ view.setData(Uri.parse(link));
+ getContext().startActivity(view);
+ }
+
+ public class ViewHolder {
+
+ @BindView(R.id.tv_title) TextView tvTitle;
+ @BindView(R.id.tv_description) TextView tvDescription;
+ @BindView(R.id.tv_dates) TextView tvDates;
+
+ public ViewHolder(View itemView) {
+ ButterKnife.bind(this, itemView);
+ }
+
+ public void init() {
+ if (campaign != null) {
+ tvTitle.setText(campaign.getTitle());
+ tvDescription.setText(campaign.getDescription());
+ SimpleDateFormat inputDateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ SimpleDateFormat outputDateFormat = new SimpleDateFormat("dd MMM");
+ try {
+ Date startDate = inputDateFormat.parse(campaign.getStartDate());
+ Date endDate = inputDateFormat.parse(campaign.getEndDate());
+ tvDates.setText(String.format("%1s - %2s", outputDateFormat.format(startDate),
+ outputDateFormat.format(endDate)));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignsPresenter.java b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignsPresenter.java
new file mode 100644
index 000000000..c9dac27af
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/campaigns/CampaignsPresenter.java
@@ -0,0 +1,101 @@
+package fr.free.nrw.commons.campaigns;
+
+import android.util.Log;
+import fr.free.nrw.commons.BasePresenter;
+import fr.free.nrw.commons.MvpView;
+import fr.free.nrw.commons.mwapi.MediaWikiApi;
+import io.reactivex.Single;
+import io.reactivex.SingleObserver;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.schedulers.Schedulers;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * The presenter for the campaigns view, fetches the campaigns from the api and informs the view on
+ * success and error
+ */
+public class CampaignsPresenter implements BasePresenter {
+ private final String TAG = "#CampaignsPresenter#";
+ private ICampaignsView view;
+ private MediaWikiApi mediaWikiApi;
+ private Disposable disposable;
+ private Campaign campaign;
+
+ @Override public void onAttachView(MvpView view) {
+ this.view = (ICampaignsView) view;
+ this.mediaWikiApi = ((ICampaignsView) view).getMediaWikiApi();
+ }
+
+ @Override public void onDetachView() {
+ this.view = null;
+ disposable.dispose();
+ }
+
+ /**
+ * make the api call to fetch the campaigns
+ */
+ public void getCampaigns() {
+ if (view != null && mediaWikiApi != null) {
+ //If we already have a campaign, lets not make another call
+ if (this.campaign != null) {
+ view.showCampaigns(campaign);
+ return;
+ }
+ Single campaigns = mediaWikiApi.getCampaigns();
+ campaigns.observeOn(AndroidSchedulers.mainThread())
+ .subscribeOn(Schedulers.io())
+ .subscribeWith(new SingleObserver() {
+
+ @Override public void onSubscribe(Disposable d) {
+ disposable = d;
+ }
+
+ @Override public void onSuccess(CampaignResponseDTO campaignResponseDTO) {
+ List campaigns = campaignResponseDTO.getCampaigns();
+ SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+ if (campaigns == null || campaigns.isEmpty()) {
+ Log.e(TAG, "The campaigns list is empty");
+ view.showCampaigns(null);
+ }
+ Collections.sort(campaigns, (campaign, t1) -> {
+ Date date1, date2;
+ try {
+ date1 = dateFormat.parse(campaign.getStartDate());
+ date2 = dateFormat.parse(t1.getStartDate());
+ } catch (ParseException e) {
+ e.printStackTrace();
+ return -1;
+ }
+ return date1.compareTo(date2);
+ });
+ Date campaignEndDate, campaignStartDate;
+ Date currentDate = new Date();
+ try {
+ for (Campaign aCampaign : campaigns) {
+ campaignEndDate = dateFormat.parse(aCampaign.getEndDate());
+ campaignStartDate =
+ dateFormat.parse(aCampaign.getStartDate());
+ if (campaignEndDate.compareTo(currentDate) >= 0
+ && campaignStartDate.compareTo(currentDate) <= 0) {
+ campaign = aCampaign;
+ break;
+ }
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ view.showCampaigns(campaign);
+ }
+
+ @Override public void onError(Throwable e) {
+ Log.e(TAG, "could not fetch campaigns: " + e.getMessage());
+ }
+ });
+ }
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/campaigns/ICampaignsView.java b/app/src/main/java/fr/free/nrw/commons/campaigns/ICampaignsView.java
new file mode 100644
index 000000000..8610728b3
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/campaigns/ICampaignsView.java
@@ -0,0 +1,13 @@
+package fr.free.nrw.commons.campaigns;
+
+import fr.free.nrw.commons.MvpView;
+import fr.free.nrw.commons.mwapi.MediaWikiApi;
+
+/**
+ * Interface which defines the view contracts of the campaign view
+ */
+public interface ICampaignsView extends MvpView {
+ MediaWikiApi getMediaWikiApi();
+
+ void showCampaigns(Campaign campaign);
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryImageUtils.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryImageUtils.java
index fdcae3aad..b246fb98e 100644
--- a/app/src/main/java/fr/free/nrw/commons/category/CategoryImageUtils.java
+++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryImageUtils.java
@@ -26,9 +26,11 @@ public class CategoryImageUtils {
*/
public static List getMediaList(NodeList childNodes) {
List categoryImages = new ArrayList<>();
+
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
- if (getMediaFromPage(node).getFilename().substring(0,5).equals("File:")){
+
+ if (getFileName(node).substring(0, 5).equals("File:")) {
categoryImages.add(getMediaFromPage(node));
}
}
@@ -46,7 +48,7 @@ public class CategoryImageUtils {
List subCategories = new ArrayList<>();
for (int i = 0; i < childNodes.getLength(); i++) {
Node node = childNodes.item(i);
- subCategories.add(getMediaFromPage(node).getFilename());
+ subCategories.add(getFileName(node));
}
Collections.sort(subCategories);
return subCategories;
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java
index c3a0f329b..82ad7765a 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionController.java
@@ -30,6 +30,7 @@ import static fr.free.nrw.commons.contributions.Contribution.SOURCE_CAMERA;
import static fr.free.nrw.commons.contributions.Contribution.SOURCE_GALLERY;
import static fr.free.nrw.commons.upload.UploadService.EXTRA_SOURCE;
import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_PREF;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCATION;
public class ContributionController {
@@ -131,7 +132,7 @@ public class ContributionController {
}
}
- public void handleImagePicked(int requestCode, @Nullable Uri uri, boolean isDirectUpload, String wikiDataEntityId) {
+ public void handleImagePicked(int requestCode, @Nullable Uri uri, boolean isDirectUpload, String wikiDataEntityId, String wikidateItemLocation) {
FragmentActivity activity = fragment.getActivity();
Timber.d("handleImagePicked() called with onActivityResult(). Boolean isDirectUpload: " + isDirectUpload + "String wikiDataEntityId: " + wikiDataEntityId);
Intent shareIntent = new Intent(activity, UploadActivity.class);
@@ -163,6 +164,7 @@ public class ContributionController {
try {
if (wikiDataEntityId != null && !wikiDataEntityId.equals("")) {
shareIntent.putExtra(WIKIDATA_ENTITY_ID_PREF, wikiDataEntityId);
+ shareIntent.putExtra(WIKIDATA_ITEM_LOCATION, wikidateItemLocation);
}
} catch (SecurityException e) {
Timber.e(e, "Security Exception");
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java
index 50666e65a..8b43c9f90 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java
@@ -14,6 +14,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
@@ -22,6 +23,8 @@ import android.support.v4.content.Loader;
import android.support.v4.app.LoaderManager;
import android.support.v4.widget.CursorAdapter;
import android.support.v7.app.AlertDialog;
+import android.support.v7.widget.RecyclerView;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -30,6 +33,14 @@ import android.widget.AdapterView;
import android.widget.CheckBox;
import android.widget.CompoundButton;
+import android.widget.Toast;
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import fr.free.nrw.commons.campaigns.Campaign;
+import fr.free.nrw.commons.campaigns.CampaignResponseDTO;
+import fr.free.nrw.commons.campaigns.CampaignView;
+import fr.free.nrw.commons.campaigns.CampaignsPresenter;
+import fr.free.nrw.commons.campaigns.ICampaignsView;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
@@ -60,6 +71,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
+import org.acra.util.ToastSender;
import timber.log.Timber;
import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED;
@@ -76,7 +88,7 @@ public class ContributionsFragment
MediaDetailPagerFragment.MediaDetailProvider,
FragmentManager.OnBackStackChangedListener,
ContributionsListFragment.SourceRefresher,
- LocationUpdateListener
+ LocationUpdateListener,ICampaignsView
{
@Inject
@Named("default_preferences")
@@ -112,6 +124,10 @@ public class ContributionsFragment
private boolean isFragmentAttachedBefore = false;
private View checkBoxView;
private CheckBox checkBox;
+ private CampaignsPresenter presenter;
+
+
+ @BindView(R.id.campaigns_view) CampaignView campaignView;
/**
* Since we will need to use parent activity on onAuthCookieAcquired, we have to wait
@@ -142,6 +158,10 @@ public class ContributionsFragment
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_contributions, container, false);
+ ButterKnife.bind(this, view);
+ presenter = new CampaignsPresenter();
+ presenter.onAttachView(this);
+ campaignView.setVisibility(View.GONE);
nearbyNoificationCardView = view.findViewById(R.id.card_view_nearby);
checkBoxView = View.inflate(getActivity(), R.layout.nearby_permission_dialog, null);
checkBox = (CheckBox) checkBoxView.findViewById(R.id.never_ask_again);
@@ -173,6 +193,27 @@ public class ContributionsFragment
setUploadCount();
}
+ getChildFragmentManager().registerFragmentLifecycleCallbacks(
+ new FragmentManager.FragmentLifecycleCallbacks() {
+ @Override public void onFragmentResumed(FragmentManager fm, Fragment f) {
+ super.onFragmentResumed(fm, f);
+ //If media detail pager fragment is visible, hide the campaigns view [might not be the best way to do, this but yeah, this proves to work for now]
+ Log.e("#CF#", "onFragmentResumed" + f.getClass().getName());
+ if (f instanceof MediaDetailPagerFragment) {
+ campaignView.setVisibility(View.GONE);
+ }
+ }
+
+ @Override public void onFragmentDetached(FragmentManager fm, Fragment f) {
+ super.onFragmentDetached(fm, f);
+ Log.e("#CF#", "onFragmentDetached" + f.getClass().getName());
+ //If media detail pager fragment is detached, ContributionsList fragment is gonna be visible, [becomes tightly coupled though]
+ if (f instanceof MediaDetailPagerFragment) {
+ fetchCampaigns();
+ }
+ }
+ }, true);
+
return view;
}
@@ -537,7 +578,7 @@ public class ContributionsFragment
nearbyNoificationCardView.setVisibility(View.GONE);
}
-
+ fetchCampaigns();
}
/**
@@ -622,7 +663,7 @@ public class ContributionsFragment
curLatLng = locationManager.getLastLocation();
placesDisposable = Observable.fromCallable(() -> nearbyController
- .loadAttractionsFromLocation(curLatLng, true)) // thanks to boolean, it will only return closest result
+ .loadAttractionsFromLocation(curLatLng, curLatLng, true, false)) // thanks to boolean, it will only return closest result
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateNearbyNotification,
@@ -694,5 +735,38 @@ public class ContributionsFragment
// Update closest nearby card view if location changed more than 500 meters
updateClosestNearbyCardViewInfo();
}
+
+ @Override public void onViewCreated(@NonNull View view,
+ @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ }
+
+ /**
+ * ask the presenter to fetch the campaigns only if user has not manually disabled it
+ */
+ private void fetchCampaigns() {
+ if (prefs.getBoolean("displayCampaignsCardView", true)) {
+ presenter.getCampaigns();
+ }
+ }
+
+ @Override public void showMessage(String message) {
+ Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
+ }
+
+ @Override public MediaWikiApi getMediaWikiApi() {
+ return mediaWikiApi;
+ }
+
+ @Override public void showCampaigns(Campaign campaign) {
+ if (campaign != null) {
+ campaignView.setCampaign(campaign);
+ }
+ }
+
+ @Override public void onDestroyView() {
+ super.onDestroyView();
+ presenter.onDetachView();
+ }
}
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java
index b238c8b8b..65c997a3b 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListFragment.java
@@ -255,11 +255,11 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
if (requestCode == ContributionController.SELECT_FROM_CAMERA) {
// If coming from camera, pass null as uri. Because camera photos get saved to a
// fixed directory
- controller.handleImagePicked(requestCode, null, false, null);
+ controller.handleImagePicked(requestCode, null, false, null, null);
} else if (requestCode == ContributionController.PICK_IMAGE_MULTIPLE) {
handleMultipleImages(requestCode, data);
} else if (requestCode == ContributionController.SELECT_FROM_GALLERY){
- controller.handleImagePicked(requestCode, data.getData(), false, null);
+ controller.handleImagePicked(requestCode, data.getData(), false, null, null);
}
} else {
Timber.e("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
@@ -319,7 +319,7 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
Log.v("LOG_TAG", "Selected Images" + mArrayUri.size());
controller.handleImagesPicked(requestCode, mArrayUri);
} else if(data.getData() != null) {
- controller.handleImagePicked(SELECT_FROM_GALLERY, data.getData(), false, null);
+ controller.handleImagePicked(SELECT_FROM_GALLERY, data.getData(), false, null, null);
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/delete/ReasonBuilder.java b/app/src/main/java/fr/free/nrw/commons/delete/ReasonBuilder.java
new file mode 100644
index 000000000..5a1700ec1
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/delete/ReasonBuilder.java
@@ -0,0 +1,101 @@
+package fr.free.nrw.commons.delete;
+
+import android.accounts.Account;
+import android.content.Context;
+import android.util.Log;
+
+import com.google.gson.JsonObject;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+import javax.inject.Inject;
+
+import fr.free.nrw.commons.Media;
+import fr.free.nrw.commons.R;
+import fr.free.nrw.commons.achievements.FeedbackResponse;
+import fr.free.nrw.commons.auth.SessionManager;
+import fr.free.nrw.commons.mwapi.MediaWikiApi;
+import fr.free.nrw.commons.utils.ViewUtil;
+import io.reactivex.android.schedulers.AndroidSchedulers;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.schedulers.Schedulers;
+import timber.log.Timber;
+
+public class ReasonBuilder {
+
+ private SessionManager sessionManager;
+ private MediaWikiApi mediaWikiApi;
+ private CompositeDisposable compositeDisposable = new CompositeDisposable();
+
+ private String reason;
+ private Context context;
+ private Media media;
+
+ public ReasonBuilder(String reason,
+ Context context,
+ Media media,
+ SessionManager sessionManager,
+ MediaWikiApi mediaWikiApi){
+ this.reason = reason;
+ this.context = context;
+ this.media = media;
+ this.sessionManager = sessionManager;
+ this.mediaWikiApi = mediaWikiApi;
+ }
+
+ private String prettyUploadedDate(Media media) {
+ Date date = media.getDateUploaded();
+ if (date == null || date.toString() == null || date.toString().isEmpty()) {
+ return "Uploaded date not available";
+ }
+ SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy", Locale.getDefault());
+ return formatter.format(date);
+ }
+
+ private void fetchArticleNumber() {
+ if (checkAccount()) {
+ compositeDisposable.add(mediaWikiApi
+ .getAchievements(sessionManager.getCurrentAccount().name)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ jsonObject -> appendArticlesUsed(jsonObject),
+ t -> Timber.e(t, "Fetching achievements statistics failed")
+ ));
+ }
+ }
+
+ private void appendArticlesUsed(FeedbackResponse object){
+ reason += context.getString(R.string.uploaded_by_myself).toString() + prettyUploadedDate(media);
+ reason += context.getString(R.string.used_by).toString()
+ + object.getArticlesUsingImages()
+ + context.getString(R.string.articles).toString();
+ Log.i("New Reason", reason);
+ }
+
+
+ public String getReason(){
+ fetchArticleNumber();
+ return reason;
+ }
+
+ /**
+ * check to ensure that user is logged in
+ * @return
+ */
+ private boolean checkAccount(){
+ Account currentAccount = sessionManager.getCurrentAccount();
+ if(currentAccount == null) {
+ Timber.d("Current account is null");
+ ViewUtil.showLongToast(context, context.getResources().getString(R.string.user_not_logged_in));
+ sessionManager.forceLogin(context);
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java
index f5a28304d..cfe4f2657 100644
--- a/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java
+++ b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java
@@ -3,6 +3,7 @@ package fr.free.nrw.commons.explore;
import android.content.res.Configuration;
import android.database.DataSetObserver;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
@@ -57,9 +58,16 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ boolean currentThemeIsDark = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("theme", false);
setContentView(R.layout.activity_search);
ButterKnife.bind(this);
initDrawer();
+ if (currentThemeIsDark) {
+ searchView.setBackgroundResource(R.color.vpi__bright_foreground_disabled_holo_dark);
+ tabLayout.setBackgroundResource(R.color.vpi__bright_foreground_disabled_holo_dark);
+ toolbar.setBackgroundResource(R.color.vpi__bright_foreground_disabled_holo_dark);
+ viewPager.setBackgroundResource(R.color.vpi__bright_foreground_disabled_holo_dark);
+ }
setTitle(getString(R.string.title_activity_search));
toolbar.setNavigationOnClickListener(v->onBackPressed());
supportFragmentManager = getSupportFragmentManager();
@@ -93,9 +101,9 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai
searchImageFragment = new SearchImageFragment();
searchCategoryFragment= new SearchCategoryFragment();
fragmentList.add(searchImageFragment);
- titleList.add("MEDIA");
+ titleList.add(getResources().getString(R.string.search_tab_title_media));
fragmentList.add(searchCategoryFragment);
- titleList.add("CATEGORIES");
+ titleList.add(getResources().getString(R.string.search_tab_title_categories));
viewPagerAdapter.setTabData(fragmentList, titleList);
viewPagerAdapter.notifyDataSetChanged();
diff --git a/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesFragment.java b/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesFragment.java
index 173d93129..289def4b2 100644
--- a/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/explore/recentsearches/RecentSearchesFragment.java
@@ -1,6 +1,8 @@
package fr.free.nrw.commons.explore.recentsearches;
+import android.content.Context;
import android.os.Bundle;
+import android.preference.PreferenceManager;
import android.support.v7.app.AlertDialog;
import android.view.LayoutInflater;
import android.view.View;
@@ -8,6 +10,7 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
@@ -31,6 +34,9 @@ public class RecentSearchesFragment extends CommonsDaggerSupportFragment {
ArrayAdapter adapter;
@BindView(R.id.recent_searches_delete_button)
ImageView recent_searches_delete_button;
+ boolean currentThemeIsDark = false;
+ @BindView(R.id.recent_searches_text_view)
+ TextView recent_searches_text_view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
@@ -38,21 +44,33 @@ public class RecentSearchesFragment extends CommonsDaggerSupportFragment {
View rootView = inflater.inflate(R.layout.fragment_search_history, container, false);
ButterKnife.bind(this, rootView);
recentSearches = recentSearchesDao.recentSearches(10);
- recent_searches_delete_button.setOnClickListener(v -> new AlertDialog.Builder(getContext())
- .setMessage(getString(R.string.delete_recent_searches_dialog))
- .setPositiveButton(android.R.string.yes, (dialog, which) -> {
- recentSearchesDao.deleteAll(recentSearches);
- Toast.makeText(getContext(),getString(R.string.search_history_deleted),Toast.LENGTH_SHORT).show();
- recentSearches = recentSearchesDao.recentSearches(10);
- adapter = new ArrayAdapter(getContext(),R.layout.item_recent_searches, recentSearches);
- recentSearchesList.setAdapter(adapter);
- adapter.notifyDataSetChanged();
- dialog.dismiss();
- })
- .setNegativeButton(android.R.string.no, null)
- .create()
- .show());
- adapter = new ArrayAdapter(getContext(),R.layout.item_recent_searches, recentSearches);
+
+ if(recentSearches.isEmpty()) {
+ recent_searches_delete_button.setVisibility(View.GONE);
+ recent_searches_text_view.setText(R.string.no_recent_searches);
+ }
+
+ recent_searches_delete_button.setOnClickListener(v -> {
+ new AlertDialog.Builder(getContext())
+ .setMessage(getString(R.string.delete_recent_searches_dialog))
+ .setPositiveButton(android.R.string.yes, (dialog, which) -> {
+ recentSearchesDao.deleteAll(recentSearches);
+ recent_searches_delete_button.setVisibility(View.GONE);
+ recent_searches_text_view.setText(R.string.no_recent_searches);
+ Toast.makeText(getContext(),getString(R.string.search_history_deleted),Toast.LENGTH_SHORT).show();
+ recentSearches = recentSearchesDao.recentSearches(10);
+ adapter = new ArrayAdapter(getContext(),R.layout.item_recent_searches, recentSearches);
+ recentSearchesList.setAdapter(adapter);
+ adapter.notifyDataSetChanged();
+ dialog.dismiss();
+ })
+ .setNegativeButton(android.R.string.no, null)
+ .create()
+ .show();
+ });
+ currentThemeIsDark = PreferenceManager.getDefaultSharedPreferences(getContext()).getBoolean("theme", false);
+ setAdapterForThemes(getContext(), currentThemeIsDark);
+
recentSearchesList.setAdapter(adapter);
recentSearchesList.setOnItemClickListener((parent, view, position, id) -> (
(SearchActivity)getContext()).updateText(recentSearches.get(position)));
@@ -76,8 +94,21 @@ public class RecentSearchesFragment extends CommonsDaggerSupportFragment {
*/
public void updateRecentSearches() {
recentSearches = recentSearchesDao.recentSearches(10);
- adapter = new ArrayAdapter(getContext(),R.layout.item_recent_searches, recentSearches);
+ setAdapterForThemes(getContext(), currentThemeIsDark);
recentSearchesList.setAdapter(adapter);
adapter.notifyDataSetChanged();
+
+ if(!recentSearches.isEmpty()) {
+ recent_searches_delete_button.setVisibility(View.VISIBLE);
+ recent_searches_text_view.setText(R.string.search_recent_header);
+ }
+ }
+
+ private void setAdapterForThemes(Context context, boolean currentThemeIsDark) {
+ if (currentThemeIsDark) {
+ adapter = new ArrayAdapter(context, R.layout.item_recent_searches_dark_theme, recentSearches);
+ } else {
+ adapter = new ArrayAdapter(context, R.layout.item_recent_searches, recentSearches);
+ }
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java
index 4b28a40fb..32870e897 100644
--- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java
@@ -14,15 +14,18 @@ import android.text.Editable;
import android.text.Html;
import android.text.TextUtils;
import android.text.TextWatcher;
+import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
+import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
@@ -44,9 +47,11 @@ import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.MediaDataExtractor;
import fr.free.nrw.commons.MediaWikiImageView;
import fr.free.nrw.commons.R;
+import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.category.CategoryDetailsActivity;
import fr.free.nrw.commons.contributions.ContributionsFragment;
import fr.free.nrw.commons.delete.DeleteTask;
+import fr.free.nrw.commons.delete.ReasonBuilder;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
@@ -65,6 +70,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
private MediaDetailPagerFragment.MediaDetailProvider detailProvider;
private int index;
private Locale locale;
+ private boolean isDeleted = false;
+
public static MediaDetailFragment forMedia(int index, boolean editable, boolean isCategoryImage) {
MediaDetailFragment mf = new MediaDetailFragment();
@@ -85,6 +92,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
Provider mediaDataExtractorProvider;
@Inject
MediaWikiApi mwApi;
+ @Inject
+ SessionManager sessionManager;
private int initialListTop = 0;
@@ -128,6 +137,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
//Had to make this class variable, to implement various onClicks, which access the media, also I fell why make separate variables when one can serve the purpose
private Media media;
+ private ArrayList reasonList;
+
@Override
public void onSaveInstanceState(Bundle outState) {
@@ -163,6 +174,13 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
initialListTop = 0;
}
+ reasonList = new ArrayList<>();
+ reasonList.add(getString(R.string.deletion_reason_uploaded_by_mistake));
+ reasonList.add(getString(R.string.deletion_reason_publicly_visible));
+ reasonList.add(getString(R.string.deletion_reason_not_interesting));
+ reasonList.add(getString(R.string.deletion_reason_no_longer_want_public));
+ reasonList.add(getString(R.string.deletion_reason_bad_for_my_privacy));
+
categoryNames = new ArrayList<>();
categoryNames.add(getString(R.string.detail_panel_cats_loading));
@@ -379,48 +397,43 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
@OnClick(R.id.nominateDeletion)
public void onDeleteButtonClicked(){
- //Reviewer correct me if i have misunderstood something over here
- //But how does this if (delete.getVisibility() == View.VISIBLE) {
- // enableDeleteButton(true); makes sense ?
- AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
- alert.setMessage("Why should this file be deleted?");
- final EditText input = new EditText(getActivity());
- alert.setView(input);
- input.requestFocus();
- alert.setPositiveButton(R.string.ok, (dialog, whichButton) -> {
- String reason = input.getText().toString();
- DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
- deleteTask.execute();
- enableDeleteButton(false);
- });
- alert.setNegativeButton(R.string.cancel, (dialog, whichButton) -> {
- });
- AlertDialog d = alert.create();
- input.addTextChangedListener(new TextWatcher() {
- private void handleText() {
- final Button okButton = d.getButton(AlertDialog.BUTTON_POSITIVE);
- if (input.getText().length() == 0) {
- okButton.setEnabled(false);
- } else {
- okButton.setEnabled(true);
- }
- }
+ final ArrayAdapter languageAdapter = new ArrayAdapter(getActivity(),
+ R.layout.simple_spinner_dropdown_list, reasonList);
+ final Spinner spinner = new Spinner(getActivity());
+ spinner.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
+ spinner.setAdapter(languageAdapter);
+ spinner.setGravity(17);
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setView(spinner);
+ builder.setTitle(R.string.nominate_delete)
+ .setPositiveButton(R.string.about_translate_proceed, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ String reason = spinner.getSelectedItem().toString();
+ ReasonBuilder reasonBuilder = new ReasonBuilder(reason,
+ getActivity(),
+ media,
+ sessionManager,
+ mwApi);
+ reason = reasonBuilder.getReason();
+ DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
+ deleteTask.execute();
+ isDeleted = true;
+ enableDeleteButton(false);
+ }
+ });
+ builder.setNegativeButton(R.string.about_translate_cancel, new DialogInterface.OnClickListener() {
@Override
- public void afterTextChanged(Editable arg0) {
- handleText();
- }
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {
- }
-
- @Override
- public void onTextChanged(CharSequence s, int start, int before, int count) {
+ public void onClick(DialogInterface dialog, int which) {
+ dialog.dismiss();
}
});
- d.show();
- d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+ AlertDialog dialog = builder.create();
+ dialog.show();
+ if(isDeleted) {
+ dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+ }
}
@OnClick(R.id.seeMore)
@@ -442,8 +455,19 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
private void rebuildCatList() {
categoryContainer.removeAllViews();
// @fixme add the category items
- for (String cat : categoryNames) {
- View catLabel = buildCatLabel(cat, categoryContainer);
+
+ //As per issue #1826(see https://github.com/commons-app/apps-android-commons/issues/1826), some categories come suffixed with strings prefixed with |. As per the discussion
+ //that was meant for alphabetical sorting of the categories and can be safely removed.
+ for (int i = 0; i < categoryNames.size(); i++) {
+ String categoryName = categoryNames.get(i);
+ //Removed everything after '|'
+ int indexOfPipe = categoryName.indexOf('|');
+ if (indexOfPipe != -1) {
+ categoryName = categoryName.substring(0, indexOfPipe);
+ //Set the updated category to the list as well
+ categoryNames.set(i, categoryName);
+ }
+ View catLabel = buildCatLabel(categoryName, categoryContainer);
categoryContainer.addView(catLabel);
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java
index ad5bf77e1..4eb69af7c 100644
--- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java
@@ -343,7 +343,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
@Override
public void onPageScrolled(int i, float v, int i2) {
- if (getActivity() == null) {
+ if(getActivity() == null) {
Timber.d("Returning as activity is destroyed!");
return;
}
@@ -398,7 +398,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
public Fragment getItem(int i) {
if (i == 0) {
// See bug https://code.google.com/p/android/issues/detail?id=27526
- if (getActivity() == null) {
+ if(getActivity() == null) {
Timber.d("Skipping getItem. Returning as activity is destroyed!");
return null;
}
diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java
index f35bb7f24..5ad6b52fc 100644
--- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java
+++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java
@@ -11,6 +11,7 @@ import android.text.TextUtils;
import com.google.gson.Gson;
+import fr.free.nrw.commons.campaigns.CampaignResponseDTO;
import org.apache.http.HttpResponse;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
@@ -77,6 +78,8 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
private SharedPreferences categoryPreferences;
private Gson gson;
private final OkHttpClient okHttpClient;
+ private final String WIKIMEDIA_CAMPAIGNS_BASE_URL =
+ "https://raw.githubusercontent.com/commons-app/campaigns/master/campaigns.json";
public ApacheHttpClientMediaWikiApi(Context context,
String apiURL,
@@ -1056,4 +1059,18 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
}
}
+ @Override public Single getCampaigns() {
+ return Single.fromCallable(() -> {
+ Request request = new Request.Builder().url(WIKIMEDIA_CAMPAIGNS_BASE_URL).build();
+ Response response = okHttpClient.newCall(request).execute();
+ if (response != null && response.body() != null && response.isSuccessful()) {
+ String json = response.body().string();
+ if (json == null) {
+ return null;
+ }
+ return gson.fromJson(json, CampaignResponseDTO.class);
+ }
+ return null;
+ });
+ }
}
diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java
index d7bf65802..46d71dc26 100644
--- a/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java
+++ b/app/src/main/java/fr/free/nrw/commons/mwapi/MediaWikiApi.java
@@ -4,6 +4,7 @@ import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import fr.free.nrw.commons.campaigns.CampaignResponseDTO;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
@@ -105,6 +106,8 @@ public interface MediaWikiApi {
void logout();
+ Single getCampaigns();
+
interface ProgressListener {
void onProgress(long transferred, long total);
}
diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java
index a84e86218..abf02362f 100644
--- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java
+++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java
@@ -5,6 +5,7 @@ import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.support.graphics.drawable.VectorDrawableCompat;
+import android.util.Log;
import com.mapbox.mapboxsdk.annotations.IconFactory;
@@ -31,6 +32,8 @@ public class NearbyController {
private static final int MAX_RESULTS = 1000;
private final NearbyPlaces nearbyPlaces;
private final SharedPreferences prefs;
+ public static double searchedRadius = 10.0; //in kilometers
+ public static LatLng currentLocation;
@Inject
public NearbyController(NearbyPlaces nearbyPlaces,
@@ -44,18 +47,21 @@ public class NearbyController {
* Prepares Place list to make their distance information update later.
*
* @param curLatLng current location for user
+ * @param latLangToSearchAround the location user wants to search around
+ * @param returnClosestResult if this search is done to find closest result or all results
* @return NearbyPlacesInfo a variable holds Place list without distance information
* and boundary coordinates of current Place List
*/
- public NearbyPlacesInfo loadAttractionsFromLocation(LatLng curLatLng, boolean returnClosestResult) throws IOException {
- Timber.d("Loading attractions near %s", curLatLng);
+ public NearbyPlacesInfo loadAttractionsFromLocation(LatLng curLatLng, LatLng latLangToSearchAround, boolean returnClosestResult, boolean checkingAroundCurrentLocation) throws IOException {
+
+ Timber.d("Loading attractions near %s", latLangToSearchAround);
NearbyPlacesInfo nearbyPlacesInfo = new NearbyPlacesInfo();
- if (curLatLng == null) {
+ if (latLangToSearchAround == null) {
Timber.d("Loading attractions neari, but curLatLng is null");
return null;
}
- List places = nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage(), returnClosestResult);
+ List places = nearbyPlaces.getFromWikidataQuery(latLangToSearchAround, Locale.getDefault().getLanguage(), returnClosestResult);
if (null != places && places.size() > 0) {
LatLng[] boundaryCoordinates = {places.get(0).location, // south
@@ -93,6 +99,11 @@ public class NearbyController {
}
nearbyPlacesInfo.placeList = places;
nearbyPlacesInfo.boundaryCoordinates = boundaryCoordinates;
+ if (!returnClosestResult && checkingAroundCurrentLocation) {
+ // Do not update searched radius, if controller is used for nearby card notification
+ searchedRadius = nearbyPlaces.radius;
+ currentLocation = curLatLng;
+ }
return nearbyPlacesInfo;
}
else {
diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java
index 9eba63cf4..5a1c48edf 100644
--- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java
@@ -14,6 +14,7 @@ import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.Snackbar;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AlertDialog;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -64,8 +65,6 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
LinearLayout bottomSheetDetails;
@BindView(R.id.transparentView)
View transparentView;
- @BindView(R.id.fab_recenter)
- View fabRecenter;
@Inject
LocationServiceManager locationManager;
@@ -87,16 +86,19 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
private LatLng curLatLng;
private Disposable placesDisposable;
+ private Disposable placesDisposableCustom;
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
public View view;
private Snackbar snackbar;
private LatLng lastKnownLocation;
+ private LatLng customLatLng;
private final String NETWORK_INTENT_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
private BroadcastReceiver broadcastReceiver;
private boolean onOrientationChanged = false;
+ private boolean populateForCurrentLocation = false;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
@@ -215,24 +217,27 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
@Override
public void onLocationChangedSignificantly(LatLng latLng) {
- refreshView(LOCATION_SIGNIFICANTLY_CHANGED);
+ refreshView(LOCATION_SIGNIFICANTLY_CHANGED);
}
@Override
public void onLocationChangedSlightly(LatLng latLng) {
- refreshView(LOCATION_SLIGHTLY_CHANGED);
+ refreshView(LOCATION_SLIGHTLY_CHANGED);
}
@Override
public void onLocationChangedMedium(LatLng latLng) {
// For nearby map actions, there are no differences between 500 meter location change (aka medium change) and slight change
- refreshView(LOCATION_SLIGHTLY_CHANGED);
+ refreshView(LOCATION_SLIGHTLY_CHANGED);
}
@Override
public void onWikidataEditSuccessful() {
- refreshView(MAP_UPDATED);
+ // Do not refresh nearby map if we are checking other areas with search this area button
+ if (!nearbyMapFragment.searchThisAreaModeOn) {
+ refreshView(MAP_UPDATED);
+ }
}
/**
@@ -240,7 +245,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
*
* @param locationChangeType defines if location shanged significantly or slightly
*/
- private void refreshView(LocationServiceManager.LocationChangeType locationChangeType) {
+ public void refreshView(LocationServiceManager.LocationChangeType locationChangeType) {
Timber.d("Refreshing nearby places");
if (lockNearbyView) {
return;
@@ -256,9 +261,11 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
if (curLatLng != null && curLatLng.equals(lastLocation)
&& !locationChangeType.equals(MAP_UPDATED)) { //refresh view only if location has changed
+ // Two exceptional cases to refresh nearby map manually.
if (!onOrientationChanged) {
return;
}
+
}
curLatLng = lastLocation;
@@ -291,7 +298,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
bundle.putString("CurLatLng", gsonCurLatLng);
placesDisposable = Observable.fromCallable(() -> nearbyController
- .loadAttractionsFromLocation(curLatLng, false))
+ .loadAttractionsFromLocation(curLatLng, curLatLng, false, true))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::populatePlaces,
@@ -300,6 +307,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
showErrorMessage(getString(R.string.error_fetching_nearby_places));
progressBar.setVisibility(View.GONE);
});
+
} else if (locationChangeType
.equals(LOCATION_SLIGHTLY_CHANGED)) {
Gson gson = new GsonBuilder()
@@ -307,7 +315,62 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
.create();
String gsonCurLatLng = gson.toJson(curLatLng);
bundle.putString("CurLatLng", gsonCurLatLng);
- updateMapFragment(true);
+ updateMapFragment(false,true, null, null);
+ }
+
+ if (nearbyMapFragment != null) {
+ nearbyMapFragment.searchThisAreaButton.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * This method should be used with "Search this are button". This method will search nearby
+ * points around any custom location (target location when user clicked on search this area)
+ * button. It populates places for custom location.
+ * @param customLatLng Custom area which we will search around
+ */
+ public void refreshViewForCustomLocation(LatLng customLatLng, boolean refreshForCurrentLocation) {
+
+ if (customLatLng == null) {
+ // If null, return
+ return;
+ }
+
+ populateForCurrentLocation = refreshForCurrentLocation;
+ this.customLatLng = customLatLng;
+ placesDisposableCustom = Observable.fromCallable(() -> nearbyController
+ .loadAttractionsFromLocation(curLatLng, customLatLng, false, populateForCurrentLocation))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(this::populatePlacesFromCustomLocation,
+ throwable -> {
+ Timber.d(throwable);
+ showErrorMessage(getString(R.string.error_fetching_nearby_places));
+ });
+
+ if (nearbyMapFragment != null) {
+ nearbyMapFragment.searchThisAreaButton.setVisibility(View.GONE);
+ }
+ }
+
+ /**
+ * Populates places for custom location, should be used for finding nearby places around a
+ * location where you are not at.
+ * @param nearbyPlacesInfo This variable has place list information and distances.
+ */
+ private void populatePlacesFromCustomLocation(NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
+ //NearbyMapFragment nearbyMapFragment = getMapFragment();
+ if (nearbyMapFragment != null) {
+ nearbyMapFragment.searchThisAreaButtonProgressBar.setVisibility(View.GONE);
+ }
+
+ if (nearbyMapFragment != null && curLatLng != null) {
+ if (!populateForCurrentLocation) {
+ nearbyMapFragment.updateMapSignificantlyForCustomLocation(customLatLng, nearbyPlacesInfo.placeList);
+ } else {
+ updateMapFragment(true,true, customLatLng, nearbyPlacesInfo);
+ }
+ updateListFragmentForCustomLocation(nearbyPlacesInfo.placeList);
}
}
@@ -341,7 +404,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
} else {
// There are fragments, just update the map and list
Timber.d("Map fragment already exists, just update the map and list");
- updateMapFragment(false);
+ updateMapFragment(false,false, null, null);
updateListFragment();
}
}
@@ -363,7 +426,11 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
}
}
- private void updateMapFragment(boolean isSlightUpdate) {
+ private void updateMapFragment(boolean updateViaButton, boolean isSlightUpdate, @Nullable LatLng customLatLng, @Nullable NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
+
+ if (nearbyMapFragment.searchThisAreaModeOn) {
+ return;
+ }
/*
Significant update means updating nearby place markers. Slightly update means only
updating current location marker and camera target.
@@ -379,14 +446,14 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
* If we are close to nearby places boundaries, we need a significant update to
* get new nearby places. Check order is south, north, west, east
* */
- if (nearbyMapFragment.boundaryCoordinates != null
+ if (nearbyMapFragment.boundaryCoordinates != null && !nearbyMapFragment.searchThisAreaModeOn
&& (curLatLng.getLatitude() <= nearbyMapFragment.boundaryCoordinates[0].getLatitude()
|| curLatLng.getLatitude() >= nearbyMapFragment.boundaryCoordinates[1].getLatitude()
|| curLatLng.getLongitude() <= nearbyMapFragment.boundaryCoordinates[2].getLongitude()
|| curLatLng.getLongitude() >= nearbyMapFragment.boundaryCoordinates[3].getLongitude())) {
// populate places
placesDisposable = Observable.fromCallable(() -> nearbyController
- .loadAttractionsFromLocation(curLatLng, false))
+ .loadAttractionsFromLocation(curLatLng, curLatLng, false, updateViaButton))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::populatePlaces,
@@ -396,11 +463,16 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
progressBar.setVisibility(View.GONE);
});
nearbyMapFragment.setBundleForUpdtes(bundle);
- nearbyMapFragment.updateMapSignificantly();
+ nearbyMapFragment.updateMapSignificantlyForCurrentLocation();
updateListFragment();
return;
}
+ if (updateViaButton) {
+ nearbyMapFragment.updateMapSignificantlyForCustomLocation(customLatLng, nearbyPlacesInfo.placeList);
+ return;
+ }
+
/*
If this is the map update just after orientation change, then it is not a slight update
anymore. We want to significantly update map after each orientation change
@@ -415,7 +487,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
nearbyMapFragment.updateMapSlightly();
} else {
nearbyMapFragment.setBundleForUpdtes(bundle);
- nearbyMapFragment.updateMapSignificantly();
+ nearbyMapFragment.updateMapSignificantlyForCurrentLocation();
updateListFragment();
}
} else {
@@ -432,6 +504,15 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
nearbyListFragment.updateNearbyListSignificantly();
}
+ /**
+ * Updates nearby list for custom location, will be used with search this area method. When you
+ * want to search for a place where you are not at.
+ * @param placeList List of places around your manually chosen target location from map.
+ */
+ private void updateListFragmentForCustomLocation(List placeList) {
+ nearbyListFragment.updateNearbyListSignificantlyForCustomLocation(placeList);
+ }
+
/**
* Calls fragment for map view.
*/
@@ -658,6 +739,9 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
placesDisposable.dispose();
}
wikidataEditListener.setAuthenticationStateListener(null);
+ if (placesDisposableCustom != null) {
+ placesDisposableCustom.dispose();
+ }
}
@Override
diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java
index 3cf60c31d..c6423f8ab 100644
--- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java
@@ -35,6 +35,8 @@ import timber.log.Timber;
import static android.app.Activity.RESULT_OK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_PREF;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCATION;
public class NearbyListFragment extends DaggerFragment {
private Bundle bundleForUpdates; // Carry information from activity about changed nearby places and current location
@@ -98,6 +100,19 @@ public class NearbyListFragment extends DaggerFragment {
}
}
+ /**
+ * While nearby updates for current location held with bundle, automatically, custom updates are
+ * done by calling this methods, triddered by search this are button input from user.
+ * @param placeList
+ */
+ public void updateNearbyListSignificantlyForCustomLocation(List placeList) {
+ try {
+ adapterFactory.updateAdapterData(placeList, (RVRendererAdapter) recyclerView.getAdapter());
+ } catch (NullPointerException e) {
+ Timber.e("Null pointer exception from calling recyclerView.getAdapter()");
+ }
+ }
+
private List getPlaceListFromBundle(Bundle bundle) {
List placeList = Collections.emptyList();
@@ -146,13 +161,14 @@ public class NearbyListFragment extends DaggerFragment {
if (resultCode == RESULT_OK) {
Timber.d("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
requestCode, resultCode, data);
- String wikidataEntityId = directPrefs.getString("WikiDataEntityId", null);
+ String wikidataEntityId = directPrefs.getString(WIKIDATA_ENTITY_ID_PREF, null);
+ String wikidataItemLocation = directPrefs.getString(WIKIDATA_ITEM_LOCATION, null);
if (requestCode == ContributionController.SELECT_FROM_CAMERA) {
// If coming from camera, pass null as uri. Because camera photos get saved to a
// fixed directory
- controller.handleImagePicked(requestCode, null, true, wikidataEntityId);
+ controller.handleImagePicked(requestCode, null, true, wikidataEntityId, wikidataItemLocation);
} else {
- controller.handleImagePicked(requestCode, data.getData(), true, wikidataEntityId);
+ controller.handleImagePicked(requestCode, data.getData(), true, wikidataEntityId, wikidataItemLocation);
}
} else {
Timber.e("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java
index c8c1d3ebd..8d8f4989f 100644
--- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java
@@ -23,8 +23,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
+import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
+import android.widget.ProgressBar;
import android.widget.TextView;
import com.google.gson.Gson;
@@ -60,14 +62,17 @@ import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
import fr.free.nrw.commons.contributions.ContributionController;
+import fr.free.nrw.commons.location.LocationServiceManager;
+import fr.free.nrw.commons.utils.LocationUtils;
+import fr.free.nrw.commons.utils.PlaceUtils;
import fr.free.nrw.commons.utils.UriDeserializer;
import fr.free.nrw.commons.utils.ViewUtil;
import timber.log.Timber;
-import uk.co.deanwild.materialshowcaseview.MaterialShowcaseView;
import static android.app.Activity.RESULT_OK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_PREF;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCATION;
public class NearbyMapFragment extends DaggerFragment {
@@ -115,16 +120,21 @@ public class NearbyMapFragment extends DaggerFragment {
private Place place;
private Marker selected;
private Marker currentLocationMarker;
- private MapboxMap mapboxMap;
+ public MapboxMap mapboxMap;
private PolygonOptions currentLocationPolygonOptions;
+ public Button searchThisAreaButton;
+ public ProgressBar searchThisAreaButtonProgressBar;
+
private boolean isBottomListSheetExpanded;
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.06;
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.04;
private boolean isMapReady;
+ public boolean searchThisAreaModeOn = false;
private Bundle bundleForUpdtes;// Carry information from activity about changed nearby places and current location
+ private boolean searchedAroundCurrentLocation = true;
@Inject
@Named("prefs")
@@ -246,8 +256,8 @@ public class NearbyMapFragment extends DaggerFragment {
* called when user is out of boundaries (south, north, east or west) of markers drawn by
* previous nearby call.
*/
- public void updateMapSignificantly() {
- Timber.d("updateMapSignificantly called, bundle is:"+bundleForUpdtes);
+ public void updateMapSignificantlyForCurrentLocation() {
+ Timber.d("updateMapSignificantlyForCurrentLocation called, bundle is:"+bundleForUpdtes);
if (mapboxMap != null) {
if (bundleForUpdtes != null) {
Gson gson = new GsonBuilder()
@@ -271,10 +281,32 @@ public class NearbyMapFragment extends DaggerFragment {
mapboxMap.clear();
addCurrentLocationMarker(mapboxMap);
updateMapToTrackPosition();
- addNearbyMarkerstoMapBoxMap();
+ // We are trying to find nearby places around our current location, thus custom parameter is nullified
+ addNearbyMarkerstoMapBoxMap(null);
}
}
+ /**
+ * Will be used for map vew updates for custom locations (ie. with search this area method).
+ * Clears the map, adds current location marker, adds nearby markers around custom location,
+ * re-enables map gestures which was locked during place load, remove progress bar.
+ * @param customLatLng custom location that we will search around
+ * @param placeList places around of custom location
+ */
+ public void updateMapSignificantlyForCustomLocation(fr.free.nrw.commons.location.LatLng customLatLng, List placeList) {
+ List customBaseMarkerOptions = NearbyController
+ .loadAttractionsFromLocationToBaseMarkerOptions(curLatLng, // Curlatlang will be used to calculate distances
+ placeList,
+ getActivity());
+ mapboxMap.clear();
+ // We are trying to find nearby places around our custom searched area, thus custom parameter is nonnull
+ addNearbyMarkerstoMapBoxMap(customBaseMarkerOptions);
+ addCurrentLocationMarker(mapboxMap);
+ // Re-enable mapbox gestures on custom location markers load
+ mapboxMap.getUiSettings().setAllGesturesEnabled(true);
+ searchThisAreaButtonProgressBar.setVisibility(View.GONE);
+ }
+
// Only update current position marker and camera view
private void updateMapToTrackPosition() {
@@ -299,6 +331,9 @@ public class NearbyMapFragment extends DaggerFragment {
// Make camera to follow user on location change
CameraPosition position ;
+
+ // Do not update camera position is search this area mode on
+ if (!searchThisAreaModeOn) {
if (ViewUtil.isPortrait(getActivity())){
position = new CameraPosition.Builder()
.target(isBottomListSheetExpanded ?
@@ -323,10 +358,10 @@ public class NearbyMapFragment extends DaggerFragment {
mapboxMap.animateCamera(CameraUpdateFactory
.newCameraPosition(position), 1000);
-
+ }
}
}
-
+
private void initViews() {
Timber.d("initViews called");
bottomSheetList = ((NearbyFragment)getParentFragment()).view.findViewById(R.id.bottom_sheet);
@@ -366,6 +401,9 @@ public class NearbyMapFragment extends DaggerFragment {
bookmarkButton = getActivity().findViewById(R.id.bookmarkButton);
bookmarkButtonImage = getActivity().findViewById(R.id.bookmarkButtonImage);
+ searchThisAreaButton = ((NearbyFragment)getParentFragment()).view.findViewById(R.id.search_this_area_button);
+ searchThisAreaButtonProgressBar = ((NearbyFragment)getParentFragment()).view.findViewById(R.id.search_this_area_button_progres_bar);
+
}
private void setListeners() {
@@ -495,13 +533,77 @@ public class NearbyMapFragment extends DaggerFragment {
@Override
public void onMapReady(MapboxMap mapboxMap) {
NearbyMapFragment.this.mapboxMap = mapboxMap;
- updateMapSignificantly();
+ addMapMovementListeners();
+ updateMapSignificantlyForCurrentLocation();
}
});
mapView.setStyleUrl("asset://mapstyle.json");
}
}
+ private void addMapMovementListeners() {
+
+ mapboxMap.addOnCameraMoveListener(new MapboxMap.OnCameraMoveListener() {
+
+ @Override
+ public void onCameraMove() {
+
+ if (NearbyController.currentLocation != null) { // If our nearby markers are calculated at least once
+
+ if (searchThisAreaButton.getVisibility() == View.GONE) {
+ searchThisAreaButton.setVisibility(View.VISIBLE);
+ }
+ double distance = mapboxMap.getCameraPosition().target
+ .distanceTo(new LatLng(NearbyController.currentLocation.getLatitude()
+ , NearbyController.currentLocation.getLongitude()));
+
+ if (distance > NearbyController.searchedRadius*1000*3/4) { //Convert to meter, and compare if our distance is bigger than 3/4 or our searched area
+ if (!searchThisAreaModeOn) { // If we are changing mode, then change click action
+ searchThisAreaModeOn = true;
+ searchThisAreaButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ searchThisAreaModeOn = true;
+ // Lock map operations during search this area operation
+ mapboxMap.getUiSettings().setAllGesturesEnabled(false);
+ searchThisAreaButtonProgressBar.setVisibility(View.VISIBLE);
+ searchThisAreaButton.setVisibility(View.GONE);
+ searchedAroundCurrentLocation = false;
+ ((NearbyFragment)getParentFragment())
+ .refreshViewForCustomLocation(LocationUtils
+ .mapBoxLatLngToCommonsLatLng(mapboxMap.getCameraPosition().target), false);
+ }
+ });
+ }
+
+ } else {
+ if (searchThisAreaModeOn) {
+ searchThisAreaModeOn = false; // This flag will help us to understand should we folor users location or not
+ searchThisAreaButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ searchThisAreaModeOn = true;
+ // Lock map operations during search this area operation
+ mapboxMap.getUiSettings().setAllGesturesEnabled(false);
+ searchThisAreaButtonProgressBar.setVisibility(View.VISIBLE);
+ fabRecenter.callOnClick();
+ searchThisAreaButton.setVisibility(View.GONE);
+ searchedAroundCurrentLocation = true;
+ ((NearbyFragment)getParentFragment())
+ .refreshViewForCustomLocation(LocationUtils
+ .mapBoxLatLngToCommonsLatLng(mapboxMap.getCameraPosition().target), true);
+ }
+ });
+ }
+ if (searchedAroundCurrentLocation) {
+ searchThisAreaButton.setVisibility(View.GONE);
+ }
+ }
+ }
+ }
+ });
+ }
+
/**
* onLogoutComplete is called after shared preferences and data stored in local database are cleared.
*/
@@ -554,10 +656,17 @@ public class NearbyMapFragment extends DaggerFragment {
/**
* Adds markers for nearby places to mapbox map
*/
- private void addNearbyMarkerstoMapBoxMap() {
+ private void addNearbyMarkerstoMapBoxMap(@Nullable List customNearbyBaseMarker) {
+ List baseMarkerOptions;
Timber.d("addNearbyMarkerstoMapBoxMap is called");
+ if (customNearbyBaseMarker != null) {
+ // If we try to update nearby points for a custom location choosen from map (we are not there)
+ baseMarkerOptions = customNearbyBaseMarker;
+ } else {
+ // If we try to display nearby markers around our curret location
+ baseMarkerOptions = this.baseMarkerOptions;
+ }
mapboxMap.addMarkers(baseMarkerOptions);
-
mapboxMap.setOnInfoWindowCloseListener(marker -> {
if (marker == selected) {
bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
@@ -781,6 +890,7 @@ public class NearbyMapFragment extends DaggerFragment {
editor.putString("Desc", place.getLongDescription());
editor.putString("Category", place.getCategory());
editor.putString(WIKIDATA_ENTITY_ID_PREF, place.getWikiDataEntityId());
+ editor.putString(WIKIDATA_ITEM_LOCATION, PlaceUtils.latLangToString(place.location));
editor.apply();
}
@@ -817,13 +927,14 @@ public class NearbyMapFragment extends DaggerFragment {
if (resultCode == RESULT_OK) {
Timber.d("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
requestCode, resultCode, data);
- String wikidataEntityId = directPrefs.getString("WikiDataEntityId", null);
+ String wikidataEntityId = directPrefs.getString(WIKIDATA_ENTITY_ID_PREF, null);
+ String wikidataItemLocation = directPrefs.getString(WIKIDATA_ITEM_LOCATION, null);
if (requestCode == ContributionController.SELECT_FROM_CAMERA) {
// If coming from camera, pass null as uri. Because camera photos get saved to a
// fixed directory
- controller.handleImagePicked(requestCode, null, true, wikidataEntityId);
+ controller.handleImagePicked(requestCode, null, true, wikidataEntityId, wikidataItemLocation);
} else {
- controller.handleImagePicked(requestCode, data.getData(), true, wikidataEntityId);
+ controller.handleImagePicked(requestCode, data.getData(), true, wikidataEntityId, wikidataItemLocation);
}
} else {
Timber.e("OnActivityResult() parameters: Req code: %d Result code: %d Data: %s",
diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNoificationCardView.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNoificationCardView.java
index 61798a95a..c9f0e0ff2 100644
--- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNoificationCardView.java
+++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyNoificationCardView.java
@@ -6,12 +6,8 @@ import android.content.res.Resources;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.design.widget.CoordinatorLayout;
-import android.support.design.widget.SwipeDismissBehavior;
import android.support.v7.app.AlertDialog;
-import android.support.v7.widget.CardView;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
@@ -20,19 +16,17 @@ import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
-import android.widget.Toast;
-
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.contributions.MainActivity;
+import fr.free.nrw.commons.utils.SwipableCardView;
import fr.free.nrw.commons.utils.ViewUtil;
import timber.log.Timber;
/**
* Custom card view for nearby notification card view on main screen, above contributions list
*/
-public class NearbyNoificationCardView extends CardView{
+public class NearbyNoificationCardView extends SwipableCardView {
- private static final float MINIMUM_THRESHOLD_FOR_SWIPE = 100;
private Context context;
private Button permissionRequestButton;
@@ -99,41 +93,15 @@ public class NearbyNoificationCardView extends CardView{
private void setActionListeners() {
this.setOnClickListener(view -> ((MainActivity)context).viewPager.setCurrentItem(1));
-
- this.setOnTouchListener(
- (v, event) -> {
- boolean isSwipe = false;
- float deltaX=0.0f;
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- x1 = event.getX();
- break;
- case MotionEvent.ACTION_UP:
- x2 = event.getX();
- deltaX = x2 - x1;
- if (deltaX < 0) {
- //Right to left swipe
- isSwipe = true;
- } else if (deltaX > 0) {
- //Left to right swipe
- isSwipe = true;
- }
- break;
- }
- if (isSwipe && (pixelToDp(Math.abs(deltaX)) > MINIMUM_THRESHOLD_FOR_SWIPE)) {
- v.setVisibility(GONE);
- // Save shared preference for nearby card view accordingly
- ((MainActivity) context).prefs.edit()
- .putBoolean("displayNearbyCardView", false).apply();
- ViewUtil.showLongToast(context, getResources().getString(R.string.nearby_notification_dismiss_message));
- return true;
- }
- return false;
- });
}
- private float pixelToDp(float pixels) {
- return (pixels / Resources.getSystem().getDisplayMetrics().density);
+ @Override public boolean onSwipe(View view) {
+ view.setVisibility(GONE);
+ // Save shared preference for nearby card view accordingly
+ ((MainActivity) context).prefs.edit().putBoolean("displayNearbyCardView", false).apply();
+ ViewUtil.showLongToast(context,
+ getResources().getString(R.string.nearby_notification_dismiss_message));
+ return true;
}
/**
diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java
index 6ca4af318..74af35de5 100644
--- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java
+++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java
@@ -30,7 +30,7 @@ public class NearbyPlaces {
private static final Uri WIKIDATA_QUERY_URL = Uri.parse("https://query.wikidata.org/sparql");
private static final Uri WIKIDATA_QUERY_UI_URL = Uri.parse("https://query.wikidata.org/");
private final String wikidataQuery;
- private double radius = INITIAL_RADIUS;
+ public double radius = INITIAL_RADIUS;
public NearbyPlaces() {
try {
@@ -55,6 +55,7 @@ public class NearbyPlaces {
} else {
MIN_RESULTS = 40;
MAX_RADIUS = 300.0; // in kilometers
+ radius = INITIAL_RADIUS;
}
// increase the radius gradually to find a satisfactory number of nearby places
diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/PlaceRenderer.java b/app/src/main/java/fr/free/nrw/commons/nearby/PlaceRenderer.java
index 9ea492e81..d709ae47d 100644
--- a/app/src/main/java/fr/free/nrw/commons/nearby/PlaceRenderer.java
+++ b/app/src/main/java/fr/free/nrw/commons/nearby/PlaceRenderer.java
@@ -30,10 +30,12 @@ import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao;
import fr.free.nrw.commons.contributions.ContributionController;
import fr.free.nrw.commons.di.ApplicationlessInjection;
+import fr.free.nrw.commons.utils.PlaceUtils;
import timber.log.Timber;
import static fr.free.nrw.commons.theme.NavigationBaseActivity.startActivityWithFlags;
import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_PREF;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCATION;
public class PlaceRenderer extends Renderer {
@@ -193,6 +195,7 @@ public class PlaceRenderer extends Renderer {
editor.putString("Desc", place.getLongDescription());
editor.putString("Category", place.getCategory());
editor.putString(WIKIDATA_ENTITY_ID_PREF, place.getWikiDataEntityId());
+ editor.putString(WIKIDATA_ITEM_LOCATION, PlaceUtils.latLangToString(place.location));
editor.apply();
}
diff --git a/app/src/main/java/fr/free/nrw/commons/notification/NotificationRenderer.java b/app/src/main/java/fr/free/nrw/commons/notification/NotificationRenderer.java
index f843cda66..22bebb37a 100644
--- a/app/src/main/java/fr/free/nrw/commons/notification/NotificationRenderer.java
+++ b/app/src/main/java/fr/free/nrw/commons/notification/NotificationRenderer.java
@@ -1,18 +1,12 @@
package fr.free.nrw.commons.notification;
-import android.graphics.Color;
import android.text.Html;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.TextPaint;
-import android.text.style.ClickableSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
-import com.borjabravo.readmoretextview.ReadMoreTextView;
import com.pedrogomez.renderers.Renderer;
import butterknife.BindView;
@@ -24,7 +18,7 @@ import fr.free.nrw.commons.R;
*/
public class NotificationRenderer extends Renderer {
- @BindView(R.id.title) ReadMoreTextView title;
+ @BindView(R.id.title) TextView title;
@BindView(R.id.time) TextView time;
@BindView(R.id.icon) ImageView icon;
private NotificationClicked listener;
@@ -64,26 +58,12 @@ public class NotificationRenderer extends Renderer {
private void setTitle(String notificationText) {
notificationText = notificationText.trim().replaceAll("(^\\s*)|(\\s*$)", "");
notificationText = Html.fromHtml(notificationText).toString();
+ if(notificationText.length()>280){
+ notificationText = notificationText.substring(0,279);
+ notificationText = notificationText.concat("...");
+ }
notificationText = notificationText.concat(" ");
-
- SpannableString ss = new SpannableString(notificationText);
- ClickableSpan clickableSpan = new ClickableSpan() {
- @Override
- public void onClick(View view) {
- listener.notificationClicked(getContent());
- }
-
- @Override
- public void updateDrawState(TextPaint ds) {
- super.updateDrawState(ds);
- ds.setUnderlineText(false);
- ds.setColor(Color.BLACK);
- }
- };
-
- // Attach a ClickableSpan to the range (start:0, end:notificationText.length()) of the String
- ss.setSpan(clickableSpan, 0, notificationText.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
- title.setText(ss, TextView.BufferType.SPANNABLE);
+ title.setText(notificationText);
}
public interface NotificationClicked{
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java b/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java
index 5c5fe8877..7186a519f 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/DescriptionsAdapter.java
@@ -174,7 +174,10 @@ class DescriptionsAdapter extends RecyclerView.Adapter{
+ descriptions.get(position - 1).setDescriptionText(descriptionText);
+ }));
+
descItemEditText.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
ViewUtil.hideKeyboard(v);
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/FileProcessor.java b/app/src/main/java/fr/free/nrw/commons/upload/FileProcessor.java
index c5b6df227..85205f079 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/FileProcessor.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/FileProcessor.java
@@ -2,37 +2,31 @@ package fr.free.nrw.commons.upload;
import android.annotation.SuppressLint;
import android.content.ContentResolver;
-import android.content.Context;
import android.content.SharedPreferences;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
-import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.support.v7.app.AppCompatActivity;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
-import java.util.Date;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
+import javax.inject.Singleton;
import fr.free.nrw.commons.caching.CacheController;
-import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.mwapi.CategoryApi;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
-import static com.mapbox.mapboxsdk.Mapbox.getApplicationContext;
-
/**
* Processing of the image file that is about to be uploaded via ShareActivity is done here
*/
+@Singleton
public class FileProcessor implements SimilarImageDialogFragment.onResponse {
@Inject
@@ -47,24 +41,23 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
private String filePath;
private ContentResolver contentResolver;
private GPSExtractor imageObj;
- private Context context;
private String decimalCoords;
private ExifInterface exifInterface;
- private boolean useExtStorage;
private boolean haveCheckedForOtherImages = false;
private GPSExtractor tempImageObj;
- FileProcessor(@NonNull String filePath, ContentResolver contentResolver, Context context) {
+ @Inject
+ FileProcessor() {
+ }
+
+ void initFileDetails(@NonNull String filePath, ContentResolver contentResolver) {
this.filePath = filePath;
this.contentResolver = contentResolver;
- this.context = context;
- ApplicationlessInjection.getInstance(context.getApplicationContext()).getCommonsApplicationComponent().inject(this);
try {
- exifInterface=new ExifInterface(filePath);
+ exifInterface = new ExifInterface(filePath);
} catch (IOException e) {
Timber.e(e);
}
- useExtStorage = prefs.getBoolean("useExternalStorage", true);
}
/**
@@ -85,10 +78,6 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
return imageObj;
}
- String getDecimalCoords() {
- return decimalCoords;
- }
-
/**
* Find other images around the same location that were taken within the last 20 sec
* @param similarImageInterface
@@ -142,7 +131,7 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
* Then initiates the calls to MediaWiki API through an instance of CategoryApi.
*/
@SuppressLint("CheckResult")
- public void useImageCoords() {
+ private void useImageCoords() {
if (decimalCoords != null) {
Timber.d("Decimal coords of image: %s", decimalCoords);
Timber.d("is EXIF data present:" + imageObj.imageCoordsExists + " from findOther image");
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java
index 9401c941e..3d9e8442c 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/FileUtils.java
@@ -6,6 +6,7 @@ import android.content.ContentUris;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
+import android.media.ExifInterface;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
@@ -78,6 +79,25 @@ public class FileUtils {
}
}
+ /**
+ * Get Geolocation of file from input file path
+ */
+ static String getGeolocationOfFile(String filePath) {
+
+ try {
+ ExifInterface exifInterface=new ExifInterface(filePath);
+ GPSExtractor imageObj = new GPSExtractor(exifInterface);
+ if (imageObj.imageCoordsExists) { // If image has geolocation information in its EXIF
+ return imageObj.getCoords();
+ } else {
+ return "";
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ return "";
+ }
+ }
+
/**
* In older devices getPath() may fail depending on the source URI. Creating and using a copy of the file seems to work instead.
*
@@ -234,8 +254,8 @@ public class FileUtils {
* @return The value of the _data column, which is typically a file path.
*/
@Nullable
- public static String getDataColumn(Context context, Uri uri, String selection,
- String[] selectionArgs) {
+ private static String getDataColumn(Context context, Uri uri, String selection,
+ String[] selectionArgs) {
Cursor cursor = null;
final String column = MediaStore.Images.ImageColumns.DATA;
@@ -311,7 +331,7 @@ public class FileUtils {
* @param destination file path copied to
* @throws IOException thrown when failing to read source or opening destination file
*/
- public static void copy(@NonNull FileDescriptor source, @NonNull String destination)
+ private static void copy(@NonNull FileDescriptor source, @NonNull String destination)
throws IOException {
copy(new FileInputStream(source), new FileOutputStream(destination));
}
@@ -415,7 +435,7 @@ public class FileUtils {
return result;
}
- public static String getFileExt(String fileName){
+ static String getFileExt(String fileName){
//Default file extension
String extension=".jpg";
@@ -426,7 +446,11 @@ public class FileUtils {
return extension;
}
- public static String getFileExt(Uri uri, ContentResolver contentResolver) {
+ private static String getFileExt(Uri uri, ContentResolver contentResolver) {
return getFileExt(getFilename(uri, contentResolver));
}
+
+ public static FileInputStream getFileInputStream(String filePath) throws FileNotFoundException {
+ return new FileInputStream(filePath);
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/FileUtilsWrapper.java b/app/src/main/java/fr/free/nrw/commons/upload/FileUtilsWrapper.java
new file mode 100644
index 000000000..e5119c095
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/upload/FileUtilsWrapper.java
@@ -0,0 +1,46 @@
+package fr.free.nrw.commons.upload;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.Uri;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class FileUtilsWrapper {
+
+ @Inject
+ public FileUtilsWrapper() {
+
+ }
+
+ public String createExternalCopyPathAndCopy(Uri uri, ContentResolver contentResolver) throws IOException {
+ return FileUtils.createExternalCopyPathAndCopy(uri, contentResolver);
+ }
+
+ public String createCopyPathAndCopy(Uri uri, Context context) throws IOException {
+ return FileUtils.createCopyPathAndCopy(uri, context);
+ }
+
+ public String getFileExt(String fileName) {
+ return FileUtils.getFileExt(fileName);
+ }
+
+ public String getSHA1(InputStream is) {
+ return FileUtils.getSHA1(is);
+ }
+
+ public FileInputStream getFileInputStream(String filePath) throws FileNotFoundException {
+ return FileUtils.getFileInputStream(filePath);
+ }
+
+ public String getGeolocationOfFile(String filePath) {
+ return FileUtils.getGeolocationOfFile(filePath);
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java
index a6b150c42..4559375c6 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/GPSExtractor.java
@@ -14,12 +14,12 @@ import timber.log.Timber;
* Extracts geolocation to be passed to API for category suggestions. If a picture with geolocation
* is uploaded, extract latitude and longitude from EXIF data of image.
*/
-public class GPSExtractor {
+class GPSExtractor {
- public static final GPSExtractor DUMMY= new GPSExtractor();
+ static final GPSExtractor DUMMY= new GPSExtractor();
private double decLatitude;
private double decLongitude;
- public boolean imageCoordsExists;
+ boolean imageCoordsExists;
private String latitude;
private String longitude;
private String latitudeRef;
@@ -37,7 +37,7 @@ public class GPSExtractor {
* @param fileDescriptor the file descriptor of the image
*/
@RequiresApi(24)
- public GPSExtractor(@NonNull FileDescriptor fileDescriptor) {
+ GPSExtractor(@NonNull FileDescriptor fileDescriptor) {
try {
ExifInterface exif = new ExifInterface(fileDescriptor);
processCoords(exif);
@@ -51,7 +51,7 @@ public class GPSExtractor {
* @param path file path of the image
*
*/
- public GPSExtractor(@NonNull String path) {
+ GPSExtractor(@NonNull String path) {
try {
ExifInterface exif = new ExifInterface(path);
processCoords(exif);
@@ -65,7 +65,7 @@ public class GPSExtractor {
* @param exif exif interface of the image
*
*/
- public GPSExtractor(@NonNull ExifInterface exif){
+ GPSExtractor(@NonNull ExifInterface exif){
processCoords(exif);
}
@@ -89,7 +89,7 @@ public class GPSExtractor {
* @return coordinates as string (needs to be passed as a String in API query)
*/
@Nullable
- public String getCoords() {
+ String getCoords() {
if(decimalCoords!=null){
return decimalCoords;
}else if (latitude!=null && latitudeRef!=null && longitude!=null && longitudeRef!=null) {
@@ -103,11 +103,11 @@ public class GPSExtractor {
}
}
- public double getDecLatitude() {
+ double getDecLatitude() {
return decLatitude;
}
- public double getDecLongitude() {
+ double getDecLongitude() {
return decLongitude;
}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.java
index d71bc0985..647920dc3 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadActivity.java
@@ -65,6 +65,7 @@ import timber.log.Timber;
import static fr.free.nrw.commons.utils.ImageUtils.Result;
import static fr.free.nrw.commons.utils.ImageUtils.getErrorMessageForResult;
import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ENTITY_ID_PREF;
+import static fr.free.nrw.commons.wikidata.WikidataConstants.WIKIDATA_ITEM_LOCATION;
public class UploadActivity extends AuthenticatedActivity implements UploadView, SimilarImageInterface {
@Inject InputMethodManager inputMethodManager;
@@ -251,13 +252,14 @@ public class UploadActivity extends AuthenticatedActivity implements UploadView,
@SuppressLint("StringFormatInvalid")
@Override
- public void updateLicenseSummary(String selectedLicense) {
+ public void updateLicenseSummary(String selectedLicense, int imageCount) {
String licenseHyperLink = "" +
getString(Utils.licenseNameFor(selectedLicense)) + " ";
licenseSummary.setMovementMethod(LinkMovementMethod.getInstance());
licenseSummary.setText(
Html.fromHtml(
- getString(R.string.share_license_summary, licenseHyperLink)));
+ getResources().getQuantityString(R.plurals.share_license_summary,
+ imageCount, licenseHyperLink)));
}
@Override
@@ -350,6 +352,9 @@ public class UploadActivity extends AuthenticatedActivity implements UploadView,
@Override
public void showBadPicturePopup(@Result int result) {
+ if (result >= 8 ) { // If location of image and nearby does not match, then set shared preferences to disable wikidata edits
+ directPrefs.edit().putBoolean("Picture_Has_Correct_Location",false);
+ }
String errorMessageForResult = getErrorMessageForResult(this, result);
if (StringUtils.isNullOrWhiteSpace(errorMessageForResult)) {
return;
@@ -553,7 +558,8 @@ public class UploadActivity extends AuthenticatedActivity implements UploadView,
String imageDesc = directPrefs.getString("Desc", "");
Timber.i("Received direct upload with title %s and description %s", imageTitle, imageDesc);
String wikidataEntityIdPref = intent.getStringExtra(WIKIDATA_ENTITY_ID_PREF);
- presenter.receiveDirect(mediaUri, mimeType, source, wikidataEntityIdPref, imageTitle, imageDesc);
+ String wikidataItemLocation = intent.getStringExtra(WIKIDATA_ITEM_LOCATION);
+ presenter.receiveDirect(mediaUri, mimeType, source, wikidataEntityIdPref, imageTitle, imageDesc, wikidataItemLocation);
} else {
Timber.i("Received single upload");
presenter.receive(mediaUri, mimeType, source);
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java
index fd0563ab3..680a16714 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadController.java
@@ -51,7 +51,7 @@ public class UploadController {
}
private boolean isUploadServiceConnected;
- private ServiceConnection uploadServiceConnection = new ServiceConnection() {
+ public ServiceConnection uploadServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder binder) {
uploadService = (UploadService) ((HandlerService.HandlerServiceLocalBinder) binder).getService();
@@ -61,6 +61,7 @@ public class UploadController {
@Override
public void onServiceDisconnected(ComponentName componentName) {
// this should never happen
+ isUploadServiceConnected = false;
Timber.e(new RuntimeException("UploadService died but the rest of the process did not!"));
}
};
@@ -68,7 +69,7 @@ public class UploadController {
/**
* Prepares the upload service.
*/
- public void prepareService() {
+ void prepareService() {
Intent uploadServiceIntent = new Intent(context, UploadService.class);
uploadServiceIntent.setAction(UploadService.ACTION_START_SERVICE);
context.startService(uploadServiceIntent);
@@ -78,7 +79,7 @@ public class UploadController {
/**
* Disconnects the upload service.
*/
- public void cleanup() {
+ void cleanup() {
if (isUploadServiceConnected) {
context.unbindService(uploadServiceConnection);
}
@@ -89,7 +90,7 @@ public class UploadController {
*
* @param contribution the contribution object
*/
- public void startUpload(Contribution contribution) {
+ void startUpload(Contribution contribution) {
startUpload(contribution, c -> {});
}
@@ -100,7 +101,7 @@ public class UploadController {
* @param onComplete the progress tracker
*/
@SuppressLint("StaticFieldLeak")
- public void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) {
+ private void startUpload(final Contribution contribution, final ContributionUploadProgress onComplete) {
//Set creator, desc, and license
if (TextUtils.isEmpty(contribution.getCreator())) {
Account currentAccount = sessionManager.getCurrentAccount();
@@ -110,7 +111,7 @@ public class UploadController {
sessionManager.forceLogin(context);
return;
}
- contribution.setCreator(currentAccount.name);
+ contribution.setCreator(sessionManager.getAuthorName());
}
if (contribution.getDescription() == null) {
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java
index 46193e958..f4e17543e 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadModel.java
@@ -10,7 +10,6 @@ import android.net.Uri;
import android.support.annotation.Nullable;
import java.io.File;
-import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
@@ -25,7 +24,9 @@ import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.settings.Prefs;
+import fr.free.nrw.commons.utils.BitmapRegionDecoderWrapper;
import fr.free.nrw.commons.utils.ImageUtils;
+import fr.free.nrw.commons.utils.ImageUtilsWrapper;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.disposables.Disposable;
@@ -53,23 +54,36 @@ public class UploadModel {
private boolean useExtStorage;
private Disposable badImageSubscription;
- @Inject
- SessionManager sessionManager;
+ private SessionManager sessionManager;
private Uri currentMediaUri;
+ private FileUtilsWrapper fileUtilsWrapper;
+ private ImageUtilsWrapper imageUtilsWrapper;
+ private BitmapRegionDecoderWrapper bitmapRegionDecoderWrapper;
+ private FileProcessor fileProcessor;
@Inject
UploadModel(@Named("licenses") List licenses,
@Named("default_preferences") SharedPreferences prefs,
@Named("licenses_by_name") Map licensesByName,
Context context,
- MediaWikiApi mwApi) {
+ MediaWikiApi mwApi,
+ SessionManager sessionManager,
+ FileUtilsWrapper fileUtilsWrapper,
+ ImageUtilsWrapper imageUtilsWrapper,
+ BitmapRegionDecoderWrapper bitmapRegionDecoderWrapper,
+ FileProcessor fileProcessor) {
this.licenses = licenses;
this.prefs = prefs;
+ this.bitmapRegionDecoderWrapper = bitmapRegionDecoderWrapper;
this.license = Prefs.Licenses.CC_BY_SA_3;
this.licensesByName = licensesByName;
this.context = context;
this.mwApi = mwApi;
this.contentResolver = context.getContentResolver();
+ this.sessionManager = sessionManager;
+ this.fileUtilsWrapper = fileUtilsWrapper;
+ this.fileProcessor = fileProcessor;
+ this.imageUtilsWrapper = imageUtilsWrapper;
useExtStorage = this.prefs.getBoolean("useExternalStorage", false);
}
@@ -84,19 +98,19 @@ public class UploadModel {
.map(filePath -> {
long fileCreatedDate = getFileCreatedDate(currentMediaUri);
Uri uri = Uri.fromFile(new File(filePath));
- FileProcessor fp = new FileProcessor(filePath, context.getContentResolver(), context);
- UploadItem item = new UploadItem(uri, mimeType, source, fp.processFileCoordinates(similarImageInterface),
- FileUtils.getFileExt(filePath), null,fileCreatedDate);
+ fileProcessor.initFileDetails(filePath, context.getContentResolver());
+ UploadItem item = new UploadItem(uri, mimeType, source, fileProcessor.processFileCoordinates(similarImageInterface),
+ fileUtilsWrapper.getFileExt(filePath), null,fileCreatedDate);
Single.zip(
Single.fromCallable(() ->
- new FileInputStream(filePath))
- .map(FileUtils::getSHA1)
+ fileUtilsWrapper.getFileInputStream(filePath))
+ .map(fileUtilsWrapper::getSHA1)
.map(mwApi::existingFile)
.map(b -> b ? ImageUtils.IMAGE_DUPLICATE : ImageUtils.IMAGE_OK),
Single.fromCallable(() ->
- new FileInputStream(filePath))
- .map(file -> BitmapRegionDecoder.newInstance(file, false))
- .map(ImageUtils::checkIfImageIsTooDark), //Returns IMAGE_DARK or IMAGE_OK
+ fileUtilsWrapper.getFileInputStream(filePath))
+ .map(file -> bitmapRegionDecoderWrapper.newInstance(file, false))
+ .map(imageUtilsWrapper::checkIfImageIsTooDark), //Returns IMAGE_DARK or IMAGE_OK
(dupe, dark) -> dupe | dark)
.observeOn(Schedulers.io())
.subscribe(item.imageQuality::onNext, Timber::e);
@@ -108,29 +122,33 @@ public class UploadModel {
}
@SuppressLint("CheckResult")
- void receiveDirect(Uri media, String mimeType, String source, String wikidataEntityIdPref, String title, String desc, SimilarImageInterface similarImageInterface) {
+ void receiveDirect(Uri media, String mimeType, String source, String wikidataEntityIdPref, String title, String desc, SimilarImageInterface similarImageInterface, String wikidataItemLocation) {
initDefaultValues();
long fileCreatedDate = getFileCreatedDate(media);
String filePath = this.cacheFileUpload(media);
Uri uri = Uri.fromFile(new File(filePath));
- FileProcessor fp = new FileProcessor(filePath, context.getContentResolver(), context);
- UploadItem item = new UploadItem(uri, mimeType, source, fp.processFileCoordinates(similarImageInterface),
- FileUtils.getFileExt(filePath), wikidataEntityIdPref,fileCreatedDate);
+ fileProcessor.initFileDetails(filePath, context.getContentResolver());
+ UploadItem item = new UploadItem(uri, mimeType, source, fileProcessor.processFileCoordinates(similarImageInterface),
+ fileUtilsWrapper.getFileExt(filePath), wikidataEntityIdPref,fileCreatedDate);
item.title.setTitleText(title);
item.descriptions.get(0).setDescriptionText(desc);
//TODO figure out if default descriptions in other languages exist
item.descriptions.get(0).setLanguageCode("en");
Single.zip(
Single.fromCallable(() ->
- new FileInputStream(filePath))
- .map(FileUtils::getSHA1)
+ fileUtilsWrapper.getFileInputStream(filePath))
+ .map(fileUtilsWrapper::getSHA1)
.map(mwApi::existingFile)
.map(b -> b ? ImageUtils.IMAGE_DUPLICATE : ImageUtils.IMAGE_OK),
+ Single.fromCallable(() -> filePath)
+ .map(fileUtilsWrapper::getGeolocationOfFile)
+ .map(geoLocation -> imageUtilsWrapper.checkImageGeolocationIsDifferent(geoLocation,wikidataItemLocation))
+ .map(r -> r ? ImageUtils.IMAGE_GEOLOCATION_DIFFERENT : ImageUtils.IMAGE_OK),
Single.fromCallable(() ->
- new FileInputStream(filePath))
- .map(file -> BitmapRegionDecoder.newInstance(file, false))
- .map(ImageUtils::checkIfImageIsTooDark), //Returns IMAGE_DARK or IMAGE_OK
- (dupe, dark) -> dupe | dark).subscribe(item.imageQuality::onNext);
+ fileUtilsWrapper.getFileInputStream(filePath))
+ .map(file -> bitmapRegionDecoderWrapper.newInstance(file, false))
+ .map(imageUtilsWrapper::checkIfImageIsTooDark), //Returns IMAGE_DARK or IMAGE_OK
+ (dupe, wrongGeo, dark) -> dupe | wrongGeo | dark).subscribe(item.imageQuality::onNext);
items.add(item);
items.get(0).selected = true;
items.get(0).first = true;
@@ -239,7 +257,7 @@ public class UploadModel {
updateItemState();
}
- public void setCurrentTitleAndDescriptions(Title title, List descriptions) {
+ void setCurrentTitleAndDescriptions(Title title, List descriptions) {
setCurrentUploadTitle(title);
setCurrentUploadDescriptions(descriptions);
}
@@ -312,7 +330,7 @@ public class UploadModel {
{
Contribution contribution = new Contribution(item.mediaUri, null, item.title + "." + item.fileExt,
Description.formatList(item.descriptions), -1,
- null, null, sessionManager.getUserName(),
+ null, null, sessionManager.getAuthorName(),
CommonsApplication.DEFAULT_EDIT_SUMMARY, item.gpsCoords.getCoords());
contribution.setWikiDataEntityId(item.wikidataEntityId);
contribution.setCategories(categoryStringList);
@@ -337,9 +355,9 @@ public class UploadModel {
try {
String copyPath;
if (useExtStorage)
- copyPath = FileUtils.createExternalCopyPathAndCopy(media, contentResolver);
+ copyPath = fileUtilsWrapper.createExternalCopyPathAndCopy(media, contentResolver);
else
- copyPath = FileUtils.createCopyPathAndCopy(media, context);
+ copyPath = fileUtilsWrapper.createCopyPathAndCopy(media, context);
Timber.i("File path is " + copyPath);
return copyPath;
} catch (IOException e) {
@@ -362,6 +380,9 @@ public class UploadModel {
badImageSubscription = getCurrentItem().imageQuality.subscribe(consumer, Timber::e);
}
+ public List getItems() {
+ return items;
+ }
@SuppressWarnings("WeakerAccess")
static class UploadItem {
@@ -397,4 +418,4 @@ public class UploadModel {
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.java
index 74e3192bd..781c158bd 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadPresenter.java
@@ -2,6 +2,7 @@ package fr.free.nrw.commons.upload;
import android.annotation.SuppressLint;
import android.net.Uri;
+import android.util.Log;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
@@ -92,8 +93,8 @@ public class UploadPresenter {
* @param source File source from {@link Contribution.FileSource}
*/
@SuppressLint("CheckResult")
- void receiveDirect(Uri media, String mimeType, @Contribution.FileSource String source, String wikidataEntityIdPref, String title, String desc) {
- Completable.fromRunnable(() -> uploadModel.receiveDirect(media, mimeType, source, wikidataEntityIdPref, title, desc, similarImageInterface))
+ void receiveDirect(Uri media, String mimeType, @Contribution.FileSource String source, String wikidataEntityIdPref, String title, String desc, String wikidataItemLocation) {
+ Completable.fromRunnable(() -> uploadModel.receiveDirect(media, mimeType, source, wikidataEntityIdPref, title, desc, similarImageInterface, wikidataItemLocation))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> {
@@ -111,7 +112,7 @@ public class UploadPresenter {
*/
void selectLicense(String licenseName) {
uploadModel.setSelectedLicense(licenseName);
- view.updateLicenseSummary(uploadModel.getSelectedLicense());
+ view.updateLicenseSummary(uploadModel.getSelectedLicense(), uploadModel.getCount());
}
//region Wizard step management
@@ -356,7 +357,7 @@ public class UploadPresenter {
private void updateLicenses() {
String selectedLicense = uploadModel.getSelectedLicense();
view.updateLicenses(uploadModel.getLicenses(), selectedLicense);
- view.updateLicenseSummary(selectedLicense);
+ view.updateLicenseSummary(selectedLicense, uploadModel.getCount());
}
/**
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
index e7920f317..0873d46d8 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
@@ -88,7 +88,7 @@ public class UploadService extends HandlerService {
String notificationProgressTitle;
String notificationFinishingTitle;
- public NotificationUpdateProgressListener(String notificationTag, String notificationProgressTitle, String notificationFinishingTitle, Contribution contribution) {
+ NotificationUpdateProgressListener(String notificationTag, String notificationProgressTitle, String notificationFinishingTitle, Contribution contribution) {
this.notificationTag = notificationTag;
this.notificationProgressTitle = notificationProgressTitle;
this.notificationFinishingTitle = notificationFinishingTitle;
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadView.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadView.java
index 410914446..a91574004 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadView.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadView.java
@@ -60,7 +60,7 @@ public interface UploadView {
void updateLicenses(List licenses, String selectedLicense);
- void updateLicenseSummary(String selectedLicense);
+ void updateLicenseSummary(String selectedLicense, int imageCount);
void updateTopCardContent();
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UrlLicense.java b/app/src/main/java/fr/free/nrw/commons/upload/UrlLicense.java
deleted file mode 100644
index a28fde579..000000000
--- a/app/src/main/java/fr/free/nrw/commons/upload/UrlLicense.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package fr.free.nrw.commons.upload;
-
-import java.util.HashMap;
-
-/**
- * This is a Util class which provides the necessary token to open the Commons License
- * info in the user language
- */
-public class UrlLicense {
- public static HashMap urlLicense = new HashMap<>();
- static {
- urlLicense.put("en", "https://commons.wikimedia.org/wiki/Commons:Licensing");
- urlLicense.put("ar", "https://commons.wikimedia.org/wiki/Commons:Licensing/ar");
- urlLicense.put("ast", "https://commons.wikimedia.org/wiki/Commons:Licensing/ast");
- urlLicense.put("az", "https://commons.wikimedia.org/wiki/Commons:Licensing/az");
- urlLicense.put("be", "https://commons.wikimedia.org/wiki/Commons:Licensing/be");
- urlLicense.put("bg", "https://commons.wikimedia.org/wiki/Commons:Licensing/bg");
- urlLicense.put("bn", "https://commons.wikimedia.org/wiki/Commons:Licensing/bn");
- urlLicense.put("ca", "https://commons.wikimedia.org/wiki/Commons:Licensing/ca");
- urlLicense.put("cs", "https://commons.wikimedia.org/wiki/Commons:Licensing/cs");
- urlLicense.put("da", "https://commons.wikimedia.org/wiki/Commons:Licensing/da");
- urlLicense.put("de", "https://commons.wikimedia.org/wiki/Commons:Licensing/de");
- urlLicense.put("el", "https://commons.wikimedia.org/wiki/Commons:Licensing/el");
- urlLicense.put("eo", "https://commons.wikimedia.org/wiki/Commons:Licensing/eo");
- urlLicense.put("es", "https://commons.wikimedia.org/wiki/Commons:Licensing/es");
- urlLicense.put("eu", "https://commons.wikimedia.org/wiki/Commons:Licensing/eu");
- urlLicense.put("fa", "https://commons.wikimedia.org/wiki/Commons:Licensing/fa");
- urlLicense.put("fi", "https://commons.wikimedia.org/wiki/Commons:Licensing/fi");
- urlLicense.put("fr", "https://commons.wikimedia.org/wiki/Commons:Licensing/fr");
- urlLicense.put("gl", "https://commons.wikimedia.org/wiki/Commons:Licensing/gl");
- urlLicense.put("gsw", "https://commons.wikimedia.org/wiki/Commons:Licensing/gsw");
- urlLicense.put("he", "https://commons.wikimedia.org/wiki/Commons:Licensing/he");
- urlLicense.put("hi", "https://commons.wikimedia.org/wiki/Commons:Licensing/hi");
- urlLicense.put("hu", "https://commons.wikimedia.org/wiki/Commons:Licensing/hu");
- urlLicense.put("id", "https://commons.wikimedia.org/wiki/Commons:Licensing/id");
- urlLicense.put("is", "https://commons.wikimedia.org/wiki/Commons:Licensing/is");
- urlLicense.put("it", "https://commons.wikimedia.org/wiki/Commons:Licensing/it");
- urlLicense.put("ja", "https://commons.wikimedia.org/wiki/Commons:Licensing/ja");
- urlLicense.put("ka", "https://commons.wikimedia.org/wiki/Commons:Licensing/ka");
- urlLicense.put("km", "https://commons.wikimedia.org/wiki/Commons:Licensing/km");
- urlLicense.put("ko", "https://commons.wikimedia.org/wiki/Commons:Licensing/ko");
- urlLicense.put("ku", "https://commons.wikimedia.org/wiki/Commons:Licensing/ku");
- urlLicense.put("mk", "https://commons.wikimedia.org/wiki/Commons:Licensing/mk");
- urlLicense.put("mr", "https://commons.wikimedia.org/wiki/Commons:Licensing/mr");
- urlLicense.put("ms", "https://commons.wikimedia.org/wiki/Commons:Licensing/ms");
- urlLicense.put("my", "https://commons.wikimedia.org/wiki/Commons:Licensing/my");
- urlLicense.put("nl", "https://commons.wikimedia.org/wiki/Commons:Licensing/nl");
- urlLicense.put("oc", "https://commons.wikimedia.org/wiki/Commons:Licensing/oc");
- urlLicense.put("pl", "https://commons.wikimedia.org/wiki/Commons:Licensing/pl");
- urlLicense.put("pt", "https://commons.wikimedia.org/wiki/Commons:Licensing/pt");
- urlLicense.put("pt-br", "https://commons.wikimedia.org/wiki/Commons:Licensing/pt-br");
- urlLicense.put("ro", "https://commons.wikimedia.org/wiki/Commons:Licensing/ro");
- urlLicense.put("ru", "https://commons.wikimedia.org/wiki/Commons:Licensing/ru");
- urlLicense.put("scn", "https://commons.wikimedia.org/wiki/Commons:Licensing/scn");
- urlLicense.put("sk", "https://commons.wikimedia.org/wiki/Commons:Licensing/sk");
- urlLicense.put("sl", "https://commons.wikimedia.org/wiki/Commons:Licensing/sl");
- urlLicense.put("sv", "https://commons.wikimedia.org/wiki/Commons:Licensing/sv");
- urlLicense.put("tr", "https://commons.wikimedia.org/wiki/Commons:Licensing/tr");
- urlLicense.put("uk", "https://commons.wikimedia.org/wiki/Commons:Licensing/uk");
- urlLicense.put("ur", "https://commons.wikimedia.org/wiki/Commons:Licensing/ur");
- urlLicense.put("vi", "https://commons.wikimedia.org/wiki/Commons:Licensing/vi");
- urlLicense.put("zh", "https://commons.wikimedia.org/wiki/Commons:Licensing/zh");
- }
- public static String getLicenseUrl ( String language){
- if (urlLicense.containsKey(language)) {
- return urlLicense.get(language);
- } else {
- return urlLicense.get("en");
- }
- }
-}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/Zoom.java b/app/src/main/java/fr/free/nrw/commons/upload/Zoom.java
deleted file mode 100644
index 438c7f77b..000000000
--- a/app/src/main/java/fr/free/nrw/commons/upload/Zoom.java
+++ /dev/null
@@ -1,115 +0,0 @@
-package fr.free.nrw.commons.upload;
-
-import android.content.ContentResolver;
-import android.graphics.Bitmap;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.net.Uri;
-import android.provider.MediaStore;
-import android.support.v4.graphics.BitmapCompat;
-import android.view.View;
-import android.widget.FrameLayout;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import timber.log.Timber;
-
-/**
- * Contains utility methods for the Zoom function in ShareActivity.
- */
-public class Zoom {
-
- private View thumbView;
- private ContentResolver contentResolver;
- private FrameLayout flContainer;
-
- Zoom(View thumbView, FrameLayout flContainer, ContentResolver contentResolver) {
- this.thumbView = thumbView;
- this.contentResolver = contentResolver;
- this.flContainer = flContainer;
- }
-
- /**
- * Create a scaled bitmap to display the zoomed-in image
- * @param input the input stream corresponding to the uploaded image
- * @param imageUri the uploaded image's URI
- * @return a zoomable bitmap
- */
- Bitmap createScaledImage(InputStream input, Uri imageUri) {
-
- Bitmap scaled = null;
- BitmapRegionDecoder decoder = null;
- Bitmap bitmap = null;
-
- try {
- decoder = BitmapRegionDecoder.newInstance(input, false);
- bitmap = decoder.decodeRegion(new Rect(10, 10, 50, 50), null);
- } catch (IOException e) {
- Timber.e(e);
- } catch (NullPointerException e) {
- Timber.e(e);
- }
- try {
- //Compress the Image
- System.gc();
- Runtime rt = Runtime.getRuntime();
- long maxMemory = rt.freeMemory();
- bitmap = MediaStore.Images.Media.getBitmap(contentResolver, imageUri);
- int bitmapByteCount = BitmapCompat.getAllocationByteCount(bitmap);
- long height = bitmap.getHeight();
- long width = bitmap.getWidth();
- long calHeight = (long) ((height * maxMemory) / (bitmapByteCount * 1.1));
- long calWidth = (long) ((width * maxMemory) / (bitmapByteCount * 1.1));
- scaled = Bitmap.createScaledBitmap(bitmap, (int) Math.min(width, calWidth), (int) Math.min(height, calHeight), true);
- } catch (IOException e) {
- Timber.e(e);
- } catch (NullPointerException e) {
- Timber.e(e);
- scaled = bitmap;
- }
- return scaled;
- }
-
- /**
- * Calculate the starting and ending bounds for the zoomed-in image.
- * Also set the container view's offset as the origin for the
- * bounds, since that's the origin for the positioning animation
- * properties (X, Y).
- * @param startBounds the global visible rectangle of the thumbnail
- * @param finalBounds the global visible rectangle of the container view
- * @param globalOffset the container view's offset
- * @return scaled start bounds
- */
- float adjustStartEndBounds(Rect startBounds, Rect finalBounds, Point globalOffset) {
-
- thumbView.getGlobalVisibleRect(startBounds);
- flContainer.getGlobalVisibleRect(finalBounds, globalOffset);
- startBounds.offset(-globalOffset.x, -globalOffset.y);
- finalBounds.offset(-globalOffset.x, -globalOffset.y);
-
- // Adjust the start bounds to be the same aspect ratio as the final
- // bounds using the "center crop" technique. This prevents undesirable
- // stretching during the animation. Also calculate the start scaling
- // factor (the end scaling factor is always 1.0).
- float startScale;
- if ((float) finalBounds.width() / finalBounds.height()
- > (float) startBounds.width() / startBounds.height()) {
- // Extend start bounds horizontally
- startScale = (float) startBounds.height() / finalBounds.height();
- float startWidth = startScale * finalBounds.width();
- float deltaWidth = (startWidth - startBounds.width()) / 2;
- startBounds.left -= deltaWidth;
- startBounds.right += deltaWidth;
- } else {
- // Extend start bounds vertically
- startScale = (float) startBounds.width() / finalBounds.width();
- float startHeight = startScale * finalBounds.height();
- float deltaHeight = (startHeight - startBounds.height()) / 2;
- startBounds.top -= deltaHeight;
- startBounds.bottom += deltaHeight;
- }
- return startScale;
- }
-}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/BitmapRegionDecoderWrapper.java b/app/src/main/java/fr/free/nrw/commons/utils/BitmapRegionDecoderWrapper.java
new file mode 100644
index 000000000..21d411908
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/utils/BitmapRegionDecoderWrapper.java
@@ -0,0 +1,22 @@
+package fr.free.nrw.commons.utils;
+
+import android.graphics.BitmapRegionDecoder;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+public class BitmapRegionDecoderWrapper {
+
+ @Inject
+ public BitmapRegionDecoderWrapper() {
+
+ }
+
+ public BitmapRegionDecoder newInstance(FileInputStream file, boolean isSharable) throws IOException {
+ return BitmapRegionDecoder.newInstance(file, isSharable);
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/ContributionUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/ContributionUtils.java
index 35c30a8f7..7d080f4fc 100644
--- a/app/src/main/java/fr/free/nrw/commons/utils/ContributionUtils.java
+++ b/app/src/main/java/fr/free/nrw/commons/utils/ContributionUtils.java
@@ -4,6 +4,11 @@ import android.content.Context;
import android.net.Uri;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.util.Random;
import timber.log.Timber;
@@ -29,9 +34,9 @@ public class ContributionUtils {
// TODO add exceptions for Google Drive URİ is needed
Uri result = null;
- if (FileUtils.checkIfDirectoryExists(TEMP_EXTERNAL_DIRECTORY)) {
+ if (checkIfDirectoryExists(TEMP_EXTERNAL_DIRECTORY)) {
String destinationFilename = decideTempDestinationFileName();
- result = FileUtils.saveFileFromURI(context, URIfromContentProvider, destinationFilename);
+ result = saveFileFromURI(context, URIfromContentProvider, destinationFilename);
} else { // If directory doesn't exist, create it and recursive call current method to check again
File file = new File(TEMP_EXTERNAL_DIRECTORY);
@@ -53,29 +58,25 @@ public class ContributionUtils {
//TODO: do I have to notify file system about deletion?
File tempFile = new File(tempFileUri.getPath());
if (tempFile.exists()) {
- boolean isDeleted= tempFile.delete();
+ boolean isDeleted = tempFile.delete();
Timber.e("removeTemporaryFile() parameters: URI tempFileUri %s, deleted status %b", tempFileUri, isDeleted);
}
}
private static String decideTempDestinationFileName() {
int i = 0;
- while (true) {
- if (new File(TEMP_EXTERNAL_DIRECTORY +File.separatorChar+i+"_tmp").exists()) {
- // This file is in use, try enother file
- i++;
- } else {
- // Use time stamp for file name, so that two temporary file never has same file name
- // to prevent previous file reference bug
- Long tsLong = System.currentTimeMillis()/1000;
- String ts = tsLong.toString();
-
- // For multiple uploads, time randomisation should be combined with another random
- // parameter, since they created at same time
- int multipleUploadRandomParameter = new Random().nextInt(100);
- return TEMP_EXTERNAL_DIRECTORY +File.separatorChar+ts+multipleUploadRandomParameter+"_tmp";
- }
+ while (new File(TEMP_EXTERNAL_DIRECTORY + File.separatorChar + i + "_tmp").exists()) {
+ i++;
}
+
+ // Use time stamp for file name, so that two temporary file never has same file name
+ // to prevent previous file reference bug
+ String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
+
+ // For multiple uploads, time randomisation should be combined with another random
+ // parameter, since they created at same time
+ int multipleUploadRandomParameter = new Random().nextInt(100);
+ return TEMP_EXTERNAL_DIRECTORY + File.separatorChar + timeStamp + multipleUploadRandomParameter + "_tmp";
}
public static void emptyTemporaryDirectory() {
@@ -91,4 +92,58 @@ public class ContributionUtils {
}
}
}
+
+ /**
+ * Saves file from source URI to destination.
+ * @param sourceUri Uri which points to file to be saved
+ * @param destinationFilename where file will be located at
+ * @return Uri points to file saved
+ */
+ private static Uri saveFileFromURI(Context context, Uri sourceUri, String destinationFilename) {
+ File file = new File(destinationFilename);
+ if (file.exists()) {
+ file.delete();
+ }
+
+ InputStream in = null;
+ OutputStream out = null;
+ try {
+ in = context.getContentResolver().openInputStream(sourceUri);
+ out = new FileOutputStream(new File(destinationFilename));
+
+ byte[] buf = new byte[1024];
+ int length;
+ while ((length = in.read(buf)) > 0) {
+ out.write(buf, 0, length);
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ if (out != null) out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ try {
+ if (in != null) in.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ return Uri.parse("file://" + destinationFilename);
+ }
+
+ /**
+ * Checks if directory exists
+ * @param pathToCheck path of directory to check
+ * @return true if directory exists, false otherwise
+ */
+ private static boolean checkIfDirectoryExists(String pathToCheck) {
+ File dir = new File(pathToCheck);
+ return dir.exists() && dir.isDirectory();
+ }
}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/FileUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/FileUtils.java
deleted file mode 100644
index 26ab5b2ca..000000000
--- a/app/src/main/java/fr/free/nrw/commons/utils/FileUtils.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package fr.free.nrw.commons.utils;
-
-import android.content.Context;
-import android.net.Uri;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * Created for file operations
- */
-
-public class FileUtils {
-
- /**
- * Saves file from source URI to destination.
- * @param sourceUri Uri which points to file to be saved
- * @param destinationFilename where file will be located at
- * @return Uri points to file saved
- */
- public static Uri saveFileFromURI(Context context, Uri sourceUri, String destinationFilename) {
- File file = new File(destinationFilename);
- if (file.exists()) {
- file.delete();
- }
-
- InputStream in = null;
- OutputStream out = null;
- try {
- in = context.getContentResolver().openInputStream(sourceUri);
- out = new FileOutputStream(new File(destinationFilename));
-
- byte[] buf = new byte[1024];
- int len;
- while((len=in.read(buf))>0){
- out.write(buf,0,len);
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- } finally {
- try {
- if(out != null) {
- out.close();
- }
- if(in != null) {
- in.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- return Uri.parse("file://" + destinationFilename);
- }
-
- /**
- * Checks if directory exists
- * @param pathToCheck path of directory to check
- * @return true if directory exists, false otherwise
- */
- public static boolean checkIfDirectoryExists(String pathToCheck) {
- File director = new File(pathToCheck);
- if (director.exists() && director.isDirectory()) {
- return true;
- } else {
- return false;
- }
- }
-
- /**
- * Creates new directory.
- * @param pathToCreateAt where directory will be created at
- * @return true if directory is created, false if an error occured, or already exists.
- */
- public static boolean createDirectory(String pathToCreateAt) {
- File directory = new File(pathToCreateAt);
- if (!directory.exists()) {
- return directory.mkdirs(); //true if directory is created
- } else {
- return false; //false if file already exists
- }
- }
-}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.java
index e6cc2fc5d..64bf033e6 100644
--- a/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.java
+++ b/app/src/main/java/fr/free/nrw/commons/utils/ImageUtils.java
@@ -9,6 +9,7 @@ import android.graphics.Rect;
import android.net.Uri;
import android.support.annotation.IntDef;
import android.support.annotation.Nullable;
+import android.util.Log;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
@@ -25,6 +26,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import fr.free.nrw.commons.R;
+import fr.free.nrw.commons.location.LatLng;
import timber.log.Timber;
/**
@@ -36,6 +38,7 @@ public class ImageUtils {
public static final int IMAGE_DARK = 1;
public static final int IMAGE_BLURRY = 1 << 1;
public static final int IMAGE_DUPLICATE = 1 << 2;
+ public static final int IMAGE_GEOLOCATION_DIFFERENT = 1 << 3;
public static final int IMAGE_OK = 0;
public static final int IMAGE_KEEP = -1;
public static final int IMAGE_WAIT = -2;
@@ -54,7 +57,8 @@ public class ImageUtils {
IMAGE_WAIT,
EMPTY_TITLE,
FILE_NAME_EXISTS,
- NO_CATEGORY_SELECTED
+ NO_CATEGORY_SELECTED,
+ IMAGE_GEOLOCATION_DIFFERENT
}
)
@Retention(RetentionPolicy.SOURCE)
@@ -93,17 +97,30 @@ public class ImageUtils {
}
/**
- * 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".
- * Pixels with luminance greater than 40% are considered to be bright pixels while the ones with luminance
- * greater than 26% but less than 40% are considered to be pixels with medium brightness. The rest are
- * dark pixels.
- * If the number of bright pixels is more than 2.5% or the number of pixels with medium brightness is
- * more than 30% of the total number of pixels then the image is considered to be OK else dark.
- * @param bitmap The bitmap that needs to be checked.
- * @return true if bitmap is dark or null, false if bitmap is bright
+ * @param geolocationOfFileString Geolocation of image. If geotag doesn't exists, then this will be an empty string
+ * @param wikidataItemLocationString Location of wikidata item will be edited after upload
+ * @return false if image is neither dark nor blurry or if the input bitmapRegionDecoder provided is null
+ * true if geolocation of the image and wikidata item are different
*/
+ public static boolean checkImageGeolocationIsDifferent(String geolocationOfFileString, String wikidataItemLocationString) {
+ Timber.d("Comparing geolocation of file with nearby place location");
+ if (geolocationOfFileString == null || geolocationOfFileString == "") { // Means that geolocation for this image is not given
+ return false; // Since we don't know geolocation of file, we choose letting upload
+ }
+
+ String[] geolocationOfFile = geolocationOfFileString.split("\\|");
+ String[] wikidataItemLocation = wikidataItemLocationString.split("/");
+
+ Double distance = LengthUtils.computeDistanceBetween(
+ new LatLng(Double.parseDouble(geolocationOfFile[0]),Double.parseDouble(geolocationOfFile[1]),0)
+ , new LatLng(Double.parseDouble(wikidataItemLocation[0]), Double.parseDouble(wikidataItemLocation[1]),0));
+ if ( distance >= 1000 ) {// Distance is more than 1 km, means that geolocation is wrong
+ return true;
+ } else {
+ return false;
+ }
+ }
+
private static boolean checkIfImageIsDark(Bitmap bitmap) {
if (bitmap == null) {
Timber.e("Expected bitmap was null");
@@ -206,24 +223,37 @@ public class ImageUtils {
}
public static String getErrorMessageForResult(Context context, @Result int result) {
- String errorMessage;
- if (result == ImageUtils.IMAGE_DARK)
- errorMessage = context.getString(R.string.upload_image_problem_dark);
- else if (result == ImageUtils.IMAGE_BLURRY)
- errorMessage = context.getString(R.string.upload_image_problem_blurry);
- else if (result == ImageUtils.IMAGE_DUPLICATE)
- errorMessage = context.getString(R.string.upload_image_problem_duplicate);
- else if (result == (ImageUtils.IMAGE_DARK|ImageUtils.IMAGE_BLURRY))
- errorMessage = context.getString(R.string.upload_image_problem_dark_blurry);
- else if (result == (ImageUtils.IMAGE_DARK|ImageUtils.IMAGE_DUPLICATE))
- errorMessage = context.getString(R.string.upload_image_problem_dark_duplicate);
- else if (result == (ImageUtils.IMAGE_BLURRY|ImageUtils.IMAGE_DUPLICATE))
- errorMessage = context.getString(R.string.upload_image_problem_blurry_duplicate);
- else if (result == (ImageUtils.IMAGE_DARK|ImageUtils.IMAGE_BLURRY|ImageUtils.IMAGE_DUPLICATE))
- errorMessage = context.getString(R.string.upload_image_problem_dark_blurry_duplicate);
- else
- return "";
+ /**
+ * Result variable is a result of an or operation of all possbile problems. Ie. if result
+ * is 0001 means IMAGE_DARK, if result is 1100 IMAGE_DUPLICATE and IMAGE_GEOLOCATION_DIFFERENT
+ */
+ StringBuilder errorMessage = new StringBuilder();
+ if (((IMAGE_DARK | IMAGE_GEOLOCATION_DIFFERENT | IMAGE_BLURRY | IMAGE_DUPLICATE) & result) == 0 ) {
+ Timber.d("No issues to warn user is found");
+ } else {
+ Timber.d("Issues found to warn user");
- return errorMessage;
+ errorMessage.append(context.getResources().getString(R.string.upload_problem_exist));
+
+ if ((IMAGE_DARK & result) != 0 ) { // We are checking image dark bit to see if that bit is set or not
+ errorMessage.append("\n - ").append(context.getResources().getString(R.string.upload_problem_image_dark));
+ }
+
+ if ((IMAGE_BLURRY & result) != 0 ) {
+ errorMessage.append("\n - ").append(context.getResources().getString(R.string.upload_problem_image_blurry));
+ }
+
+ if ((IMAGE_DUPLICATE & result) != 0 ) {
+ errorMessage.append("\n - ").append(context.getResources().getString(R.string.upload_problem_image_duplicate));
+ }
+
+ if ((IMAGE_GEOLOCATION_DIFFERENT & result) != 0 ) {
+ errorMessage.append("\n - ").append(context.getResources().getString(R.string.upload_problem_different_geolocation));
+ }
+
+ errorMessage.append("\n\n").append(context.getResources().getString(R.string.upload_problem_do_you_continue));
+ }
+
+ return errorMessage.toString();
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/ImageUtilsWrapper.java b/app/src/main/java/fr/free/nrw/commons/utils/ImageUtilsWrapper.java
new file mode 100644
index 000000000..d5b905e9d
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/utils/ImageUtilsWrapper.java
@@ -0,0 +1,25 @@
+package fr.free.nrw.commons.utils;
+
+import android.graphics.BitmapRegionDecoder;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import static fr.free.nrw.commons.utils.ImageUtils.*;
+
+@Singleton
+public class ImageUtilsWrapper {
+
+ @Inject
+ public ImageUtilsWrapper() {
+
+ }
+
+ public @Result int checkIfImageIsTooDark(BitmapRegionDecoder bitmapRegionDecoder) {
+ return ImageUtils.checkIfImageIsTooDark(bitmapRegionDecoder);
+ }
+
+ public boolean checkImageGeolocationIsDifferent(String geolocationOfFileString, String wikidataItemLocationString) {
+ return ImageUtils.checkImageGeolocationIsDifferent(geolocationOfFileString, wikidataItemLocationString);
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/LocationUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/LocationUtils.java
new file mode 100644
index 000000000..58cd138a0
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/utils/LocationUtils.java
@@ -0,0 +1,13 @@
+package fr.free.nrw.commons.utils;
+
+import fr.free.nrw.commons.location.LatLng;
+
+public class LocationUtils {
+ public static LatLng mapBoxLatLngToCommonsLatLng(com.mapbox.mapboxsdk.geometry.LatLng mapBoxLatLng) {
+ return new LatLng(mapBoxLatLng.getLatitude(), mapBoxLatLng.getLongitude(), 0);
+ }
+
+ public static com.mapbox.mapboxsdk.geometry.LatLng comonsLatLngToMapBoxLatLng(LatLng commonsLatLng) {
+ return new com.mapbox.mapboxsdk.geometry.LatLng(commonsLatLng.getLatitude(), commonsLatLng.getLongitude());
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/PlaceUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/PlaceUtils.java
new file mode 100644
index 000000000..4a4e153db
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/utils/PlaceUtils.java
@@ -0,0 +1,25 @@
+package fr.free.nrw.commons.utils;
+
+import fr.free.nrw.commons.location.LatLng;
+
+public class PlaceUtils {
+
+ /**
+ * Converts our defined LatLng to string, to put as String
+ * @param latLng latlang will be converted to string
+ * @return latitude + "/" + longitude
+ */
+ public static String latLangToString(LatLng latLng) {
+ return latLng.getLatitude()+"/"+latLng.getLongitude();
+ }
+
+ /**
+ * Converts latitude + "/" + longitude string to commons LatLng
+ * @param latLngString latitude + "/" + longitude string
+ * @return commons LatLng
+ */
+ public static LatLng stringToLatLng(String latLngString) {
+ String[] parts = latLngString.split("/");
+ return new LatLng(Double.parseDouble(parts[0]), Double.parseDouble(parts[1]), 0);
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/utils/SwipableCardView.java b/app/src/main/java/fr/free/nrw/commons/utils/SwipableCardView.java
new file mode 100644
index 000000000..a65033d15
--- /dev/null
+++ b/app/src/main/java/fr/free/nrw/commons/utils/SwipableCardView.java
@@ -0,0 +1,72 @@
+package fr.free.nrw.commons.utils;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v7.widget.CardView;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+/**
+ * A card view which informs onSwipe events to its child
+ */
+public abstract class SwipableCardView extends CardView {
+ float x1, x2;
+ private static final float MINIMUM_THRESHOLD_FOR_SWIPE = 100;
+
+ public SwipableCardView(@NonNull Context context) {
+ super(context);
+ interceptOnTouchListener();
+ }
+
+ public SwipableCardView(@NonNull Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ interceptOnTouchListener();
+ }
+
+ public SwipableCardView(@NonNull Context context, @Nullable AttributeSet attrs,
+ int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ interceptOnTouchListener();
+ }
+
+ private void interceptOnTouchListener() {
+ this.setOnTouchListener((v, event) -> {
+ boolean isSwipe = false;
+ float deltaX = 0.0f;
+ Log.e("#SwipableCardView#", event.getAction() + "");
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ x1 = event.getX();
+ break;
+ case MotionEvent.ACTION_UP:
+ x2 = event.getX();
+ deltaX = x2 - x1;
+ if (deltaX < 0) {
+ //Right to left swipe
+ isSwipe = true;
+ } else if (deltaX > 0) {
+ //Left to right swipe
+ isSwipe = true;
+ }
+ break;
+ }
+ if (isSwipe && (pixelToDp(Math.abs(deltaX)) > MINIMUM_THRESHOLD_FOR_SWIPE)) {
+ return onSwipe(v);
+ }
+ return false;
+ });
+ }
+
+ /**
+ * abstract function which informs swipe events to those who have inherited from it
+ */
+ public abstract boolean onSwipe(View view);
+
+ private float pixelToDp(float pixels) {
+ return (pixels / Resources.getSystem().getDisplayMetrics().density);
+ }
+}
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/HeightLimitedRecyclerView.java b/app/src/main/java/fr/free/nrw/commons/widget/HeightLimitedRecyclerView.java
similarity index 97%
rename from app/src/main/java/fr/free/nrw/commons/upload/HeightLimitedRecyclerView.java
rename to app/src/main/java/fr/free/nrw/commons/widget/HeightLimitedRecyclerView.java
index ff100e16e..b1dc29736 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/HeightLimitedRecyclerView.java
+++ b/app/src/main/java/fr/free/nrw/commons/widget/HeightLimitedRecyclerView.java
@@ -1,4 +1,4 @@
-package fr.free.nrw.commons.upload;
+package fr.free.nrw.commons.widget;
import android.app.Activity;
import android.content.Context;
@@ -13,10 +13,7 @@ import android.view.Display;
* Created by Ilgaz Er on 8/7/2018.
*/
public class HeightLimitedRecyclerView extends RecyclerView {
-
int height;
-
-
public HeightLimitedRecyclerView(Context context) {
super(context);
DisplayMetrics displayMetrics = new DisplayMetrics();
diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataConstants.java b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataConstants.java
index e7e929dac..bbab18300 100644
--- a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataConstants.java
+++ b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataConstants.java
@@ -2,4 +2,5 @@ package fr.free.nrw.commons.wikidata;
public class WikidataConstants {
public static final String WIKIDATA_ENTITY_ID_PREF = "WikiDataEntityId";
+ public static final String WIKIDATA_ITEM_LOCATION = "WikiDataItemLocation";
}
diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java
index 6b0c52cb3..3d52cf85c 100644
--- a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java
+++ b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java
@@ -58,6 +58,11 @@ public class WikidataEditService {
return;
}
+ if (!(directPrefs.getBoolean("Picture_Has_Correct_Location",true))) {
+ Timber.d("Image location and nearby place location mismatched, so Wikidata item won't be edited");
+ return;
+ }
+
editWikidataProperty(wikidataEntityId, fileName);
}
diff --git a/app/src/main/res/drawable-hdpi/ic_campaign.png b/app/src/main/res/drawable-hdpi/ic_campaign.png
new file mode 100755
index 000000000..315ec45d3
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_campaign.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_campaign.png b/app/src/main/res/drawable-mdpi/ic_campaign.png
new file mode 100755
index 000000000..b60884dd6
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_campaign.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_campaign.png b/app/src/main/res/drawable-xhdpi/ic_campaign.png
new file mode 100755
index 000000000..8b93f7977
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_campaign.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_campaign.png b/app/src/main/res/drawable-xxhdpi/ic_campaign.png
new file mode 100755
index 000000000..069ad8e1e
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_campaign.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_campaign.png b/app/src/main/res/drawable-xxxhdpi/ic_campaign.png
new file mode 100755
index 000000000..cef03959d
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_campaign.png differ
diff --git a/app/src/main/res/drawable/ic_app_logo.xml b/app/src/main/res/drawable/ic_app_logo.xml
new file mode 100644
index 000000000..afbe0efda
--- /dev/null
+++ b/app/src/main/res/drawable/ic_app_logo.xml
@@ -0,0 +1,59 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_download_white_24dp.xml b/app/src/main/res/drawable/ic_download_white_24dp.xml
new file mode 100644
index 000000000..b8e836142
--- /dev/null
+++ b/app/src/main/res/drawable/ic_download_white_24dp.xml
@@ -0,0 +1,5 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 000000000..4c2e6cabf
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,62 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout-land/welcome_do_upload.xml b/app/src/main/res/layout-land/welcome_do_upload.xml
index 01e5c2af3..5baceecec 100644
--- a/app/src/main/res/layout-land/welcome_do_upload.xml
+++ b/app/src/main/res/layout-land/welcome_do_upload.xml
@@ -9,21 +9,6 @@
android:gravity="center"
android:orientation="horizontal">
-
-
-
-
-
-
-
-
+ app:actualImageScaleType="fitCenter" />
+ app:actualImageScaleType="fitCenter" />
-
+ android:text="@plurals/share_license_summary" />
+
+
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/fragment_contributions.xml b/app/src/main/res/layout/fragment_contributions.xml
index dd1959178..5fc1a74dc 100644
--- a/app/src/main/res/layout/fragment_contributions.xml
+++ b/app/src/main/res/layout/fragment_contributions.xml
@@ -12,11 +12,21 @@
app:cardBackgroundColor="?attr/mainCardBackground"
/>
+
+
+ android:id="@+id/root_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginTop="2dp"
+ android:background="#000"
+ >
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_nearby.xml b/app/src/main/res/layout/fragment_nearby.xml
index 4269f135b..8b50dfae5 100644
--- a/app/src/main/res/layout/fragment_nearby.xml
+++ b/app/src/main/res/layout/fragment_nearby.xml
@@ -19,7 +19,6 @@
android:gravity="center_vertical"
android:orientation="horizontal">
-
+
+
+
+ app:actualImageScaleType="fitCenter" />
+ app:actualImageScaleType="fitCenter" />
-
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_place.xml b/app/src/main/res/layout/item_place.xml
index 1e1e4eba1..eb64e8de0 100644
--- a/app/src/main/res/layout/item_place.xml
+++ b/app/src/main/res/layout/item_place.xml
@@ -14,7 +14,6 @@
android:layout_marginStart="@dimen/standard_gap"
android:layout_marginTop="@dimen/standard_gap"
android:background="@android:color/white"
- android:contentDescription="@string/no_image_found"
android:scaleType="centerCrop"
android:src="@drawable/empty_photo"
/>
@@ -29,7 +28,6 @@
android:layout_marginRight="@dimen/standard_gap"
android:layout_marginTop="@dimen/standard_gap"
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
- tools:text="@string/placeholder_place_distance"
/>
diff --git a/app/src/main/res/layout/item_recent_searches_dark_theme.xml b/app/src/main/res/layout/item_recent_searches_dark_theme.xml
new file mode 100644
index 000000000..1f8be3141
--- /dev/null
+++ b/app/src/main/res/layout/item_recent_searches_dark_theme.xml
@@ -0,0 +1,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_campagin.xml b/app/src/main/res/layout/layout_campagin.xml
new file mode 100644
index 000000000..47824f5a3
--- /dev/null
+++ b/app/src/main/res/layout/layout_campagin.xml
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/layout_contribution.xml b/app/src/main/res/layout/layout_contribution.xml
index 87e7fe9e3..b8237b1c2 100644
--- a/app/src/main/res/layout/layout_contribution.xml
+++ b/app/src/main/res/layout/layout_contribution.xml
@@ -22,7 +22,7 @@
android:id="@+id/contributionImage"
android:layout_width="match_parent"
android:layout_height="240dp"
- app:actualImageScaleType="centerCrop"
+ app:actualImageScaleType="fitCenter"
/>
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/welcome_do_upload.xml b/app/src/main/res/layout/welcome_do_upload.xml
index bf2401913..c24ade705 100644
--- a/app/src/main/res/layout/welcome_do_upload.xml
+++ b/app/src/main/res/layout/welcome_do_upload.xml
@@ -164,20 +164,5 @@
-
-
-
-
\ No newline at end of file
+
+
diff --git a/app/src/main/res/layout/welcome_dont_upload.xml b/app/src/main/res/layout/welcome_dont_upload.xml
index 3e244e1fa..4efed7d5a 100644
--- a/app/src/main/res/layout/welcome_dont_upload.xml
+++ b/app/src/main/res/layout/welcome_dont_upload.xml
@@ -138,20 +138,4 @@
-
-
-
-
\ No newline at end of file
+
diff --git a/app/src/main/res/layout/welcome_final.xml b/app/src/main/res/layout/welcome_final.xml
index 6a1d36c2a..786c48195 100644
--- a/app/src/main/res/layout/welcome_final.xml
+++ b/app/src/main/res/layout/welcome_final.xml
@@ -56,7 +56,7 @@
android:layout_height="@dimen/overflow_button_dimen"
android:layout_marginTop="@dimen/standard_gap"
android:text="@string/welcome_final_button_text"
- android:id="@+id/welcomeYesButton"
+ android:id="@+id/finishTutorialButton"
android:textSize="@dimen/normal_text"
android:layout_gravity="center"
android:background="@android:color/white"
diff --git a/app/src/main/res/layout/welcome_image_details.xml b/app/src/main/res/layout/welcome_image_details.xml
index 7202df4c0..6bea1044f 100644
--- a/app/src/main/res/layout/welcome_image_details.xml
+++ b/app/src/main/res/layout/welcome_image_details.xml
@@ -135,18 +135,5 @@
-
-
\ No newline at end of file
+
+
diff --git a/app/src/main/res/layout/welcome_wikipedia.xml b/app/src/main/res/layout/welcome_wikipedia.xml
index 0708b5ea9..9bc083d87 100644
--- a/app/src/main/res/layout/welcome_wikipedia.xml
+++ b/app/src/main/res/layout/welcome_wikipedia.xml
@@ -49,18 +49,5 @@
android:textColor="@android:color/white"
/>
-
-
\ No newline at end of file
+
+
diff --git a/app/src/main/res/menu/fragment_image_detail.xml b/app/src/main/res/menu/fragment_image_detail.xml
index 11b2c0e7b..3161bd155 100644
--- a/app/src/main/res/menu/fragment_image_detail.xml
+++ b/app/src/main/res/menu/fragment_image_detail.xml
@@ -12,14 +12,15 @@
android:icon="@drawable/ic_share_black_24dp"
android:title="@string/menu_share"
app:showAsAction="always" />
+
-
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..7353dbd1f
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..34e740987
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..a5667d3a2
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..07c7e8f0b
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..9c8561852
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..b29884c15
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..5209ac75a
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..5cd3cfcf3
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..92aaab15a
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..cdbbe057a
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..c771625af
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values-ab/strings.xml b/app/src/main/res/values-ab/strings.xml
index 2f91f2074..b936926c7 100644
--- a/app/src/main/res/values-ab/strings.xml
+++ b/app/src/main/res/values-ab/strings.xml
@@ -30,7 +30,7 @@
Афото ҭыхтәупСара сҭагаламҭақәаИаарттәуп абраузер аҟны
- Ахьӡ
+ АхьӡАхҳәааАсистемахь аҭалара агха!Аҭагалара
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 7a12bd3e9..dcf88a938 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -61,7 +61,7 @@
مرفوعاتيانشرهاافتح في المتصفح
- العنوان
+ العنوان (مطلوب)يُرجَى تقديم عنوان لهذا الملفالوصفلا يمكن تسجيل الدخول - فشل في شبكة الاتصال
@@ -84,8 +84,8 @@
لا مرفوعات بعد\@string/contributions_subtitle_zero
- %1$d رفع
- %1$d مرفوعات
+ (%1$d)
+ (%1$d)جارٍ بدء %1$d رفع
@@ -178,7 +178,7 @@
الأماكن القريبةالأماكن القريبة غير متوفرةتحذير
- هذا الملف موجود بالفعل في كومنز، هل أنت متأكد أنك تريد المتابعة؟
+ هذا الملف موجود بالفعل في كومنز، هل أنت متأكد أنك تريد المتابعة؟نعملاالعنوان
@@ -240,8 +240,8 @@
خطأ أثناء تخزين الصورعنوان وصفي فريد للملف، والذي سيكون بمثابة اسم الملف، يمكنك استخدام لغة واضحة مع مسافات، لا تقم بتضمين امتداد الملفيُرجَى وصف الوسائط قدر الإمكان: أين تم التقاطها؟ ما تظهر؟ ما هو السياق؟ يُرجَى وصف الأشياء أو الأشخاص، اكشف المعلومات التي لا يمكن تخمينها بسهولة، على سبيل المثال الوقت في اليوم إذا كان منظرا طبيعيا، إذا أظهرت الوسائط شيئا غير عادي، فيُرجَى توضيح ما يجعله غير عادي.
- هذه الصورة مظلمة للغاية، هل أنت متأكد من رغبتك في رفعها؟ ويكيميديا كومنز للصور ذات القيمة الموسوعية فقط.
- هذه الصورة ضبابية، هل أنت متأكد من رغبتك في رفعها؟ ويكيميديا كومنز للصور ذات القيمة الموسوعية فقط.
+ هذه الصورة مظلمة للغاية، هل أنت متأكد من رغبتك في رفعها؟ ويكيميديا كومنز للصور ذات القيمة الموسوعية فقط.
+ هذه الصورة ضبابية، هل أنت متأكد من رغبتك في رفعها؟ ويكيميديا كومنز للصور ذات القيمة الموسوعية فقط.إعطاء السماحاستخدم تخزينا خارجيااحفظ الصور الملتقطة بالكاميرا داخل التطبيق على جهازك
@@ -336,6 +336,7 @@
+ إضافة الوصفهل أنت متأكد من أنك تريد مسح سجل بحثك؟تم حذف سجل البحث
+ ترشيح للحذفالإنجازاتإحصاءاتتم تلقي الشكر
@@ -352,8 +353,27 @@
عدد الصور التي قمت برفعها إلى كومنز والتي تم استخدامها في مقالات ويكيميدياحدث خطأ!إشعار كومنز
+ مساهمات
+ مجاور
+ الإشعارات
+ عرض الإخطار القريب
+ انقر هنا لرؤية أقرب مكان يحتاج إلى صور
+ لم يتم العثور على أماكن قريبة بالقرب منك
+ قائمةسماح التخزيننحتاج إلى سماحك للوصول إلى التخزين الخارجي لجهازك من أجل رفع الصور.
+ لن ترى أقرب مكان يحتاج إلى صور بعد الآن، ومع ذلك، يمكنك إعادة تمكين هذا الإشعار في الإعدادات إذا كنت ترغب في ذلك.
+ الخطوة %1$d من %2$d
+ الصورة %1$d في المجموعة
+ التالي
+ السابق
+ إرسال
+ يوجد ملف باسم الملف %1$s، هل أنت متأكد أنك تريد المتابعة؟
+ لا يمكن العثور على تطبيق خرائط متوافق على جهازك; الرجاء تثبيت تطبيق خرائط لاستخدام هذه الميزة.
+
+ %1$d رفع
+ %1$d مرفوعات
+ العلاماتالعلاماتالصور
@@ -363,5 +383,25 @@
أنت لم تضف أي علاماتالعلاماتبدأ جمع السجل. من فضلك أعد تشغيل التطبيق، ونفذ الإجراء الذي ترغب في تسجيله، ثم اضغط على \'إرسال ملف السجل\' مرة أخرى
+ رفعته عن طريق الخطأ
+ لم أكن أعلم أنه سيكون مرئيا بشكل علني
+ أدركت أنه سيئ لخصوصيتي
+ لقد غيرت رأيي، ولا أريد أن يكون مرئيا للجميع بعد الآن
+ آسف هذه الصورة ليست مثيرة للاهتمام لموسوعة
+ رفعته بنفسي على
+ ،مستعمل في
+ مقالاتمرحبا بك في كومنز! \n\nارفع الوسائط الأولى عن طريق لمس أيقونة الكاميرا أو المعرض أعلاه.
+ في جميع أنحاء العالم
+ أمريكا
+ أوروبا
+ الشرق الأوسط
+ أفريقيا
+ آسيا
+ المحيط الهادئ
+ لا توجد تصنيفات مختارة
+ نادرًا ما تكون الصور بدون تصنيفات قابلة للاستخدام، هل أنت متأكد من أنك تريد الإرسال دون تحديد تصنيفات؟
+ نعم، ارسل
+ لا، العودة
+ (لجميع الصور في مجموعة)
diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml
index d8d36226c..23692ec90 100644
--- a/app/src/main/res/values-ast/strings.xml
+++ b/app/src/main/res/values-ast/strings.xml
@@ -48,7 +48,7 @@
Les mios xubesCompartirVer nel navegador
- Títulu
+ TítuluApurre un títulu pa esti ficheruDescripciónNun se pudo aniciar sesión – error de rede
@@ -69,7 +69,7 @@
El GPS ta desactiváu nel preséu. ¿Quiés activalu?Activar GPSInda nun hai xubes
-
+ \@string/contributions_subtitle_zero%1$d carga%1$d cargues
@@ -168,7 +168,6 @@
Llugares cercanosNun s\'alcontraron llugares cercanosAvisu
- Esti ficheru yá esiste\'n Commons. ¿Confirmes que quies siguir?SíNonTítulu
@@ -230,8 +229,6 @@
Error al poner les fotos na cachéUn títulu descriptivu únicu pal ficheru, que sirvirá para da-y nome al mesmu. Puede usase llinguaxe normal con espacios. Nun incluyas la estensión del ficheruPor 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.
- Esta imaxe ye escura enforma, ¿tas seguru de que quies xubila? Wikimedia Commons ye sólo pa imáxenes con valor enciclopédicu.
- Esta imaxe ta borrosa, ¿tas seguru de que quies xubila? Wikimedia Commons ye sólo pa imáxenes con valor enciclopédicu.Dar permisuUsar almacenamientu esternuGuardar nel preséu les imaxes tomaes cola cámara de la app
diff --git a/app/src/main/res/values-b+roa+tara/strings.xml b/app/src/main/res/values-b+roa+tara/strings.xml
new file mode 100644
index 000000000..d621b23df
--- /dev/null
+++ b/app/src/main/res/values-b+roa+tara/strings.xml
@@ -0,0 +1,109 @@
+
+
+
+ Esplore
+ Esplore
+ Aspette
+ Generale
+ Segnalazione
+ Luèche
+ Commons
+ •
+ \'Mbostaziune
+ Careche sus a Commons
+ Nome de l\'utende
+ Passuord
+ Tràse jndr\'à \'u cunde tune de Commons Beta
+ Tràse
+ Passuord scurdate?
+ Reggistrate
+ Stoche a tràse...
+ Aspitte...
+ E\' trasute!
+ Non g\'è trasute!
+ File non acchiate. Pruève \'n\'otre file.
+ Autenticazione sciute a male, tràse arrete
+ Carecamende accumenzate!
+ %1$s carecate!
+ Condivide
+ Titole (Cercate)
+ Careche
+ Careche
+ Reggìstre
+ Aggiorne
+ Elenghe
+ Categorije
+ \'Mbostaziune
+ Reggistrate
+ Immaggine dettagliate
+ Categorije
+ Sus a
+ Pruève arrete
+ Annulle
+ Attribbuzione-Condivide a \'u stesse mode 4.0
+ Attribbuzione 4.0
+ Attribbuzione-Condivide a \'u stesse mode 3.0
+ Attribbuzione 3.0
+ CC0
+ CC BY-SA 3.0
+ CC BY-SA 3.0 (Austrie)
+ CC BY-SA 3.0 (Germanie)
+ CC BY-SA 3.0 (Estonie)
+ CC BY-SA 3.0 (Spagne)
+ CC BY-SA 3.0 (Croazie)
+ CC BY-SA 3.0 (Lussemburghe)
+ CC BY-SA 3.0 (Olande)
+ CC BY-SA 3.0 (Norveggie)
+ CC BY-SA 3.0 (Pulonie)
+ CC BY-SA 3.0 (Romanie)
+ CC BY 3.0
+ CC BY-SA 4.0
+ CC BY 4.0
+ CC Zero
+ OK
+ Sìne
+ None
+ Titole
+ Titole d\'u file multimediale
+ Descrizione
+ Autore
+ Date de carecamende
+ Licenze
+ Coordinate
+ Tràse
+ Nisciuna recerche recende
+ Condrebbute
+ Vicine a
+ Notifeche
+ Elenghe
+ Passe %1$d de %2$d
+ Immaggine %1$d jndr\'à \'u \'nzieme
+ Prossime
+ Precedende
+ Conferme
+ Signalibbre
+ Signalibbre
+ Fote
+ Luèche
+ Aggiungi/Live le signalibbre
+ Signalibbre
+ Signalibbre
+ , ausate jndr\'à
+ vôsce
+ Bovègne jndr\'à Commons!\n\nCareche \'u prime media cazzanne l\'icone d\'a maghena fotografeche o d\'a gallerie, aqquà sus.
+ Tutte \'u munne
+ Americhe
+ Europe
+ Medie oriende
+ Afriche
+ Asie
+ Pacifeche
+ Nisicuna categorije scacchiate
+ Sìne, conferme
+ No, tuèrne rrete
+ (Pe tutte le immaggine jndr\'à \'u \'nzieme)
+ Cirche jndr\'à sta arèe
+ Permesse richieste
+
diff --git a/app/src/main/res/values-b+sr+Latn/strings.xml b/app/src/main/res/values-b+sr+Latn/strings.xml
index 83bdd49f9..593d797d0 100644
--- a/app/src/main/res/values-b+sr+Latn/strings.xml
+++ b/app/src/main/res/values-b+sr+Latn/strings.xml
@@ -50,7 +50,7 @@
Moja otpremanjaDeliPrikaži u pregledaču
- Naslov
+ NaslovPružite naslov za ovu datotekuOpisPrijava nije moguća — greška na mreži
@@ -169,7 +169,6 @@
Mesta u bliziniNisu pronađena obližnja mestaUpozorenje
- Ova datoteka je već dostupna na Ostavi. Da li ste sigurni da želite da nastavite?DaNeNaslov
diff --git a/app/src/main/res/values-ba/strings.xml b/app/src/main/res/values-ba/strings.xml
index 58ae9cd4b..f6d261f3c 100644
--- a/app/src/main/res/values-ba/strings.xml
+++ b/app/src/main/res/values-ba/strings.xml
@@ -46,7 +46,7 @@
Минең тейәүҙәремУртаҡлашырғаБраузерҙа асырға
- Исем
+ ИсемБыл файлдың атамаһын күрһәтТасуирламаИнеп булмай - интернет хатаһы
@@ -62,7 +62,7 @@
Ҡоролмағыҙҙа GPS һүнгән. Тоҡандырырғамы?GPS-ты тоҡандырыуТейәүҙәр әлегә юҡ
-
+ \@string/contributions_subtitle_zero%1$d тейәү%1$d тейәүҙәр
@@ -157,7 +157,6 @@
Мотлаҡ булмаған рөхсәт: категория тәҡдиме өсөн ошо урынды алыуЯҡындағы урындарЯҡындағы урындар табылманы
- Был файл Викискладта бар. Дауам итергә ризаһыңмы?АтамаМәғлүмәт йөрөтөүсенең атамаһыМәғлүмәт йөрөтөүсене һүрәтләү ошонда яҙыла.Уның ярайһы уҡ оҙон, хатта бер-нисә юлға һуҙылып китеүе лә бар. Шулай булһа ла ул бик матур күренер тип уйлайбыҙ.
@@ -204,8 +203,6 @@
Рәсемде кэшлағандағы хатаФайлдың исеме булараҡ һаҡланасаҡ үҙенсәлекле һәртәләү. Тәбиғи телегеҙҙе, һүҙҙәр араһын айырып, ҡулланырға була. Зинһар, файл киңәйтеүҙәрен күрһәтмәгеҙ.Зинһар, тейәләсәк файлды тәфсирләп һүрәтлә:ҡайҙа төшөрөлгән? нимә һәрәтләнә? һүрәт нимәне аңлата? Рәсемдәге кешеләр йәки объекттарҙы ла һүрәтлә. Һүрәткә ҡарап ҡына белеп булмаған мәғлүмәттәрҙе өҫтә: мәҫәлән, тәүлектең ниндәй мәлендә, ҡасан төшөрөлгән был файл. Әгәр ғәҙәти булмаған әйбер төшөрөлһә, уның нимәһе шаҡ ҡатырғанын аңлат.
- Был рәсем бик ҡараңғы күренә. Тейәргәме? Викискладта энциклопедик йәһәттән ҡиммәте булған фоторәсемдәр генә ҡәҙерле.
- Был рәсем асыҡ түгел. Тейәргәме? Викискладта энциклопедик йәһәттән ҡиммәте булған фоторәсемдәр генә ҡәҙерле.Рөхсәт бирәмТышҡы һаҡлағысты ҡулланҠулайламаның камераһы ярҙамында төшөрөлгән һүрәттәрҙе һаҡлау
diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml
index 76bdae2c6..d7f010607 100644
--- a/app/src/main/res/values-bn/strings.xml
+++ b/app/src/main/res/values-bn/strings.xml
@@ -58,7 +58,7 @@
আমার আপলোডবণ্টনব্রাউজারে দেখুন
- শিরোনাম
+ শিরোনাম (আবশ্যক)এই ফাইলটির জন্য একটি শিরোনাম প্রদান করুনবিবরণপ্রবেশ করা যাচ্ছে না - নেটওয়ার্ক ব্যর্থতা
@@ -81,8 +81,8 @@
এখনো কোন আপলোড নেই\@string/contributions_subtitle_zero
- %1$dটি আপলোড
- %1$dটি আপলোড
+ (%1$d)
+ (%1$d)%1$dটি আপলোড শুরু হয়েছে
@@ -178,7 +178,6 @@
কাছাকাছি স্থানকাছাকাছি কোন স্থান পাওয়া যায়নিসতর্কীকরণ
- এই ফাইলটি ইতিমধ্যে কমন্সে বিদ্যমান। আপনি কি নিশ্চিত আপনি সামনে এগুতে চান?হ্যাঁনাশিরোনাম
@@ -239,8 +238,6 @@
ছবি আনার সময় ত্রুটিফাইলের একটি স্বতন্ত্র বর্ণনামূলক নাম যা ফাইলের নাম হিসাবে কাজ করবে। অাপনি সাধারণ ভাষা ব্যবহার করতে পারেন শূন্যস্থানসহ। ফাইলের এক্সটেনশন যুক্ত করবেন না।যতটা সম্ভব মিডিয়াটি বর্ণনা করুন: এটি কোথায় ধারণ করা হয়েছিল? এটি কি প্রদর্শন করে? এটির প্রসঙ্গ কি? ধারণকৃত বস্তু অথবা ব্যক্তির বর্ণনা করুন। সহজে অনুমান করা যায়না সেরকম তথ্য উদঘাটন করুন, উদাহরণস্বরূপ, যদি ল্যান্ডস্কেপ হয় তাহলে দিবসকালের সময় দিন।
- এই ছবিটি খুবই অন্ধকারময়, আপনি কি এটি আপলোড করতে চান? উইকিমিডিয়া কমন্স শুধুমাত্র বিশ্বকোষীয় মানের ছবির জন্য।
- এই ছবিটি অস্পষ্ট, আপনি কি এটি আপলোড করতে চান? উইকিমিডিয়া কমন্স শুধুমাত্র বিশ্বকোষীয় মানের ছবির জন্য।অনুমতি দিনবাহ্যিক সঞ্চয়স্থান ব্যবহার করুনঅাপনার ডিভাইসের নিজস্ব ক্যামেরায় ধারণকৃত ছবি সংরক্ষণ করুন
@@ -289,15 +286,38 @@
ভুল উত্তরকাছাকাছি স্থানগুলি আনতে ত্রুটি।+ বিবরণ যোগ করুন
+ অপসারণের জন্য মনোনীত করুনকৃতিত্বগুলিপরিসংখ্যাননির্বাচিত ছবিস্তরকমন্স বিজ্ঞপ্তি
+ অবদান
+ কাছাকাছি
+ বিজ্ঞপ্তি
+ তালিকা
+ ধাপ %2$d এর %1$d
+ পরবর্তী
+ পূর্ববর্তী
+ জমা দিন
+
+ %1$dটি আপলোড
+ %1$dটি আপলোড
+ বুকমার্কবুকমার্কচিত্রঅবস্থানবুকমার্কবুকমার্ক
+ টি নিবন্ধ
+ বিশ্বব্যাপী
+ আমেরিকা
+ ইউরোপ
+ মধ্যপ্রাচ্য
+ আফ্রিকা
+ এশিয়া
+ প্রশান্ত মহাসাগরীয়
+ হ্যাঁ, জমা দিন
+ না, ফিরে যান
diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml
index 1acdd1a62..fac7cc1c9 100644
--- a/app/src/main/res/values-br/strings.xml
+++ b/app/src/main/res/values-br/strings.xml
@@ -8,8 +8,11 @@
* Y-M D
-->
+ Ergerzhout
+ ErgerzhoutNeuzHollek
+ SonjoùLec\'hiadurCommons•
@@ -25,7 +28,7 @@
Kevreet oc\'h !Kudenn gevreañ !N\'eo ket bet kavet ar restr. Klask gant unan all.
- Dilesadur c\'hwitet!
+ Dilesadur c\'hwitet, kevreit en-dro mar plijKroget da enporzhiañ!%1$s bet enporzhiet !Pouezit evit gwelet hoc\'h enporzhiadenn
@@ -49,10 +52,11 @@
Ma enporzhiadennoùRannañDiskwel er meerder
- Titl
+ TitlRoit un titl d\'ar restr-mañ, mar plijDeskrivadurNe c\'haller ket kevreañ - rouedad sac\'het
+ Ne c\'haller ket kevreañ - gwiriit hoc\'h anv implijer hag ho ker-tremen mar plijRe a daolioù-esae. Klaskit en-dro a-benn ur pennadig amzer.Hon digarezit, prennet eo bet an implijer-mañ e CommonsRankout a rit reiñ ho kod dilesa gant daou faktor.
@@ -64,10 +68,11 @@
Klask rummadoùEnrollañFreskaat
+ RollDiwerededkaet eo ar GPS war hoc\'h ardivink.\nHa c\'hoant ho peus da weredekaat anezhañ ?Gweredekaat ar GPSEnporzhiadenn ebet c\'hoazh !
-
+ Pellgardenn ebet c\'hoazh%1$d bellgargadenn%1$d Pellgargadennoù
@@ -85,6 +90,7 @@
RummadoùArventennoùEn em enskrivañ
+ RummadDiwar-bennMeziant frank a wirioù embannet dindan <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">an Aotre-implijout Apache v2</a>. Merkoù kenwerzhel eus Diazezadur Wikimedia eo Wikimedia Commons hag e logoioù. Gallout a reont bezañ implijet gant aotre an Diazezadur. N\'omp nag aprouet gant Diazezadur Wiikimedia na stag outañ.Krouiñ ur <a href=\"https://github.com/commons-app/apps-android-commons/issues\">gemennadenn GitHub nevez</a> evit kelaouiñ a-zivout un draen bennak pe bet kinnigoù.
@@ -146,26 +152,27 @@
Diarbenn an dafar gwarezet a vez kavet ganeoc\'h war ar Genrouedad, hag ivez ar skeudennoù skritelloù, ar goloioù levrioù ha kement zo…Ha soñjal a rit eo mat ?Ya !
+ <u>Gouzout hiroc\'h</u>RummadoùO kargañ…Hini ebet diuzetDeskrivadur ebetAotre-implijout dizanvFreskaat
- Aotre rekis : lenn ur stokañ diavaez. Hep se, n\'hall ket an arload mont en-dro.
- Aotre ret ; skrivañ war al lec\'h stokañ diavaez. Ne c\'hall ket an arload mont en-dro hep an dra-se.
+ Aotre rekis : lenn ur stokañ diavaez. N\'hall ket an arload tizhout ho palier hep an dra-se.
+ Aotre ret ; skrivañ war al lec\'h stokañ diavaez. Ne c\'hall ket an arload tizhout ho kamera hep an dra-se.Aotre diret : kaout al lec\'hiadur red evit kinnig rummadoùMat eoLec\'hioù nesN\'eus bet kavet netra tostikDiwallit
- Emañ ar restr-mañ war Commons c\'hoazh. Ha sur oc\'h e fell deoc\'h kenderc\'hel ?YaKetTitlTitl ar mediaDeskrivadurAmañ e lakaer titl ar media. Gallout a ra bezañ hir-mat ha mont dre meur a linenn. Spi hon eus e vo bravik an disoc\'h koulskoude.
+ AozerDeiziad enporzhiañAotre-implijoutDaveennoù
@@ -211,12 +218,40 @@
N\'eus bet kavet deskrivadur ebetPajennad restroù CommonsElfenn Wikidata
+ Pennad WikipediaReiñ ar gwirImplijout ar stokañ diavaezEnrollit ar skeudennoù tennet gant luc\'hskeudennerez ho penvegKevreit ouzh ho kont
+ Fazi ! N\'eo ket bet kavet an URL
+ Kinnig evit lemel
+ Meneget eo bet ar skeudenn evit lemel.
+ Diskwel er merdeer
+ Lezel a-gostez
+ KevreañN\'eo ket cheñchet al lec\'hiadur.Kaout urzhioùLenn ar pennad
+ WIKIDATA
+ WIKIPEDIA
+ <u>FAG</u>
+ Lezel an tutorial a-gostez
+ <u>Treiñ</u>
+ Yezhoù
+ Kenderc\'hel
+ Nullañ
+ Klask en-dro
+ Mat eo !
+ N\'eus bet kavet skeudenn ebet !
+ Ur fazi zo c\'hoarvezet p\'eo bet karget ar skeudennoù.
+ Enporzhiet gant:%1$s
+ Stanket oc\'h bet ha ne c\'hallit ket mui kemmañ war CommonsSkeudenn an deiz
+ Skeudenn an deiz
+ Klask
+ Klask e Commons
+ N\'eus bet kavet skeudenn ebet hag a sell ouzh 1$s
+ Klask
+ Enklaskoù nevez :
+ Rekedoù enklask diwezhañ
diff --git a/app/src/main/res/values-bs/strings.xml b/app/src/main/res/values-bs/strings.xml
index 1c456a749..f8c443c87 100644
--- a/app/src/main/res/values-bs/strings.xml
+++ b/app/src/main/res/values-bs/strings.xml
@@ -40,7 +40,7 @@
Moje postavljene datotekePodijeliVidi u pregledniku
- Naslov
+ NaslovOpisNe mogu Vas prijaviti – mreža ne radiNapravili ste previše grešaka u prijavi. Pokušajte ponovo za nekoliko minuta.
@@ -142,7 +142,6 @@
Mjesta u bliziniNema okolnih mjestaUpozorenje
- Ova datoteka već postoji na Commonsu. Jeste li sigurni da želite nastaviti?DaNeNaslov
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index 951fbce09..cc00f55f8 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -47,7 +47,7 @@
Les meves càrreguesComparteixMostra al navegador
- Títol
+ TítolDescripcióNo s\'ha pogut iniciar la sessió – error de xarxaMassa intents erronis – Proveu-ho de nou d\'aquí uns minuts.
@@ -64,7 +64,7 @@
El vostre dispositiu no té el GPS habilitat. El voleu habilitar?Habilita el GPSEncara no hi ha cap càrrega
-
+ \@string/contributions_subtitle_zero%1$d càrrega%1$d càrregues
@@ -139,7 +139,6 @@
Llocs propersNo s\'han trobat llocs propersAvís
- El fitxer ja existeix a Commons. Segur que voleu procedir?SíNoTítol
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index cecfce340..f2290372d 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -61,7 +61,7 @@
Moje obrázkySdíletZobrazit v prohlížeči
- Název
+ NázevVložte prosím název tohoto souboruPopisNelze se přihlásit - selhání sítě
@@ -82,7 +82,7 @@
GPS ve vašem zařízení není povoleno. Chtěli byste ho spustit?Spustit GPSŽádné nahrané soubory
-
+ \@string/contributions_subtitle_zero1 soubor%1$d souborů
@@ -181,7 +181,6 @@
Místa v okolíPoblíž nebylo nic nalezenoUpozornění
- Tento soubor již na Commons existuje. Jste si jist, že chcete pokračovat?AnoNeNázev
@@ -243,8 +242,6 @@
Chyba při meziukládání obrázků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.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.
- 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.
- Tento obrázek je rozmazaný, jste si jist/a, že ho chcete nahrát? Wikimedia Commons slouží jenom pro obrázky s encyklopedickou hodnotou.Dát povoleníPoužít externí úložištěUložit obrázky pořízené fotoaparátem, jenž je součástí této aplikace
diff --git a/app/src/main/res/values-csb/strings.xml b/app/src/main/res/values-csb/strings.xml
index 3fab9c6fb..8c1c21ea6 100644
--- a/app/src/main/res/values-csb/strings.xml
+++ b/app/src/main/res/values-csb/strings.xml
@@ -38,7 +38,7 @@
Mòjé wladëncziÙprzistãpniÒbôczë w przezérnikù
- Titel
+ TitelÒpisënkNi mòże sã wlogòwac - fela sécëZa wiele nieùdałich prób wlogòwaniô. Spróbùjë znowa za czile minut.
diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml
index 134c2f116..30d9cc3ba 100644
--- a/app/src/main/res/values-cy/strings.xml
+++ b/app/src/main/res/values-cy/strings.xml
@@ -47,7 +47,7 @@
Fy uwchlwythiadauRhannuAgor yn y Porwr
- Teitl
+ TeitlRhowch deitl i\'r ffeilDisgrifiadYn methu mewngofnodi - methodd y rhwydwaith
@@ -67,7 +67,7 @@
Ataliwyd GPS ar eich dyfais. Ydych chi am ei droi\'n weithredol?Gweithredu\'r GPSHeb uwchlwytho eto
-
+ \@string/contributions_subtitle_zero%1$d upload%1$d uwchlwythiad
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index af29073ab..20a85d0d5 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -54,7 +54,7 @@
Mine uploadsDelÅbn i browser
- Titel
+ Titel (Påkrævet)Angiv venligt en titel for denne filBeskrivelseKan ikke logge på - netværksfejl
@@ -75,7 +75,7 @@
GPS er deaktiveret i din enhed. Ønsker du at aktivere den?Aktiver GPSIngen overførelser endnu
-
+ \@string/contributions_subtitle_zero%1$d overførsel%1$d overførsler
@@ -174,7 +174,7 @@
Steder i nærhedenIngen steder i nærheden fundetAdvarsel
- Denne fil findes allerede på Commons. Er du sikker på, at du ønsker at fortsætte?
+ Denne fil findes allerede på Commons. Er du sikker på, at du ønsker at fortsætte?JaNejTitel
@@ -235,8 +235,6 @@
Fejl under mellemlagring af billederEn unik beskrivelse for filen, som vil fungere som et filnavn. Du kan bruge normalt sprog med mellemrum. Udelad filendelsen.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.
- 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.
- 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.Giv tilladelseBrug eksternt lagerGem billeder taget med din enheds program på kameraet
@@ -298,7 +296,9 @@
Er det i orden at lægge dette skærmbillede op?Del appen+ Tilføj en beskrivelse
+ Ingen seneste søgningerSøgehistorik slettet
+ Nominer til sletningPræstationerSTATISTIKKERTak modtaget
@@ -306,8 +306,17 @@
NIVEAUOplagte billederBilleder brugt
+ minimumskrav:Der opstod en fejl!
+ Bidrag
+ I nærheden
+ Ingen steder i nærheden fundet der var tæt på dig
+ ListeLagringstilladelse
+ Trin %1$d af %2$d
+ Næste
+ Forrige
+ IndsendBogmærkerBogmærkerBilleder
@@ -316,5 +325,24 @@
BogmærkerDu har ikke tilføjet nogen bogmærkerBogmærker
+ Jeg lagde dette op ved en fejl
+ Jeg vidste ikke, det ville være til offentligt skue
+ Jeg indså, det var skidt for mit privatliv
+ ,brugt i
+ artiklerVelkommen til Commons!\n\nOplæg dit første medie ved at trykke på kamera eller galleri ikonet foroven.
+ Verdensomspændende
+ Amerika
+ Europa
+ Mellemøsten
+ Afrika
+ Asien
+ Stillehavet
+ Ingen valgte kategorier
+ Ja, indsend
+ Nej, gå tilbage
+ Søg i dette område
+ Spørg aldrig om dette igen
+ Vis placeringstilladelse
+ Vis kampagner
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 77220b744..7f7f74152 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -6,6 +6,7 @@
* Kghbln
* Metalhead64
* Sujan
+* Sushi
-->
Entdecken
@@ -53,7 +54,7 @@
Meine hochgeladenen DateienTeilenIm Browser anzeigen
- Titel
+ Titel (erforderlich)Bitte gib einen Titel für diese Datei anBeschreibungAnmeldung fehlgeschlagen – Netzwerkfehler
@@ -173,7 +174,7 @@
Orte in der NäheKeine Orte in der Nähe gefundenWarnung
- Diese Datei ist bereits auf Commons vorhanden. Bist du sicher, dass du fortfahren möchtest?
+ Diese Datei ist bereits auf Commons vorhanden. Bist du sicher, dass du fortfahren möchtest?JaNeinTitel
@@ -235,8 +236,8 @@
Fehler beim Zwischenspeichern der BilderEin eindeutiger beschreibender Titel für die Datei, der als Dateiname dient. Du kannst Klartext mit Leerzeichen verwenden. Gib nicht die Dateierweiterung mit an.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.
- 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.
- 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.
+ 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.
+ 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.Berechtigung gebenExternen Speicher verwendenMit der In-App-Kamera aufgenommene Bilder auf deinem Gerät speichern
@@ -329,8 +330,10 @@
Während der Bildauswahl wurden keine Koordinaten angegebenFehler beim Abrufen der Orte in der Nähe.+ Beschreibung hinzufügen
+ Keine letzten SuchanfragenBist du sicher, dass du deinen Suchverlauf löschen möchtest?Suchverlauf gelöscht
+ Zur Löschung vorschlagenErrungenschaftenSTATISTIKENErhaltene Dankeschöns
@@ -347,8 +350,27 @@
Die Anzahl der Bilder, die du auf Commons hochgeladen hast und in Wikimedia-Artikeln verwendet werden.Fehler aufgetreten!Commons-Benachrichtigung
+ Beiträge
+ In der Nähe
+ Benachrichtigungen
+ Benachrichtigungen in der Nähe anzeigen
+ Hier tippen, um Orte in der Nähe anzusehen, die Bilder benötigen.
+ Keine Orte in deiner Umgebung gefunden.
+ ListeSpeicherberechtigungWir benötigen deine Berechtigung für den Zugriff auf den externen Speicher deines Geräts, um Bilder hochzuladen.
+ Du wirst nicht mehr den nähersten Ort sehen, der noch Bilder braucht. Du kannst jedoch diese Benachrichtigung in den Einstellungen erneut aktivieren, falls du das zu wünschen tust.
+ Schritt %1$d von %2$d
+ Bild %1$d im Satz
+ Nächste
+ Vorherige
+ Einreichen
+ Eine Datei mit dem Namen %1$s ist bereits vorhanden. Bist du sicher, dass du fortfahren möchtest?
+ Auf deinem Gerät konnte keine kompatible Karten-App gefunden werden. Bitte installiere eine Karten-App, um diese Funktion nutzen zu können.
+
+ Eine hochgeladene Datei
+ %1$d hochgeladene Dateien
+ LesezeichenLesezeichenBilder
@@ -358,5 +380,36 @@
Du hast keine Lesezeichen hinzugefügtLesezeichenProtokollsammlung gestartet. Bitte STARTE die App NEU, führe die zu protokollierende Aktion aus und tippe erneut auf „Logdatei senden“.
+ Ich habe es aus Versehen hochgeladen.
+ Ich wusste nicht, dass es öffentlich sichtbar sein würde.
+ Ich habe erkannt, dass es schlecht für meine Privatsphäre ist.
+ Ich habe meine Meinung geändert. Ich möchte nicht mehr, dass es öffentlich sichtbar ist.
+ Entschuldigung, aber dieses Bild ist nicht für eine Enzyklopädie relevant.
+ Von mir hochgeladen am
+ , verwendet in
+ ArtikelWillkommen bei Commons!\n\nLade deine erste Datei hoch, indem du oben auf das Kamera- oder Galeriesymbol tippst.
+ Weltweit
+ Amerika
+ Europa
+ Mittlerer Osten
+ Afrika
+ Asien
+ Pazifik
+ Keine Kategorien ausgewählt
+ Bilder ohne Kategorien sind selten nutzbar. Bist du sicher, dass du ohne die Auswahl von Kategorien hochladen möchtest?
+ Ja, einreichen
+ Nein, zurück gehen
+ (für alle Bilder im Satz)
+ Diesen Bereich durchsuchen
+ Berechtigungsanfrage
+ Dürfen wir deinen aktuellen Standort verwenden, um den nächsten Ort anzuzeigen, der Bilder benötigt?
+ Der nächste Ort, der Bilder benötigt, kann ohne Standortberechtigungen nicht angezeigt werden.
+ Nicht erneut fragen
+ Standortberechtigung anzeigen
+ Anfrage für eine Standortberechtigung, die für die Nachbarbenachrichtigungskartenansichtsfunktion erforderlich ist.
+ Endet am:
+ Kampagnen anzeigen
+ Hier tippen, um die laufenden Kampagnen anzusehen.
+ Du wirst die Kampagnen nicht mehr sehen. Du kannst dennoch diese Benachrichtigung in den Einstellungen erneut aktivieren, falls du dies möchtest.
diff --git a/app/src/main/res/values-diq/strings.xml b/app/src/main/res/values-diq/strings.xml
index a312fcc9d..22e1963cc 100644
--- a/app/src/main/res/values-diq/strings.xml
+++ b/app/src/main/res/values-diq/strings.xml
@@ -49,7 +49,7 @@
Barkerdışê mıVıla keRovıte dı akê
- Sername
+ Sername (lazımo)ŞınasnayışXırabiya kewten-network xetaŞıma xeylê rayi kerd ke cı kewê, a ser nêvıst. Şıma rê zehmet 2-3 deqey ra tepeya reyna bıcerrebnên.
@@ -63,7 +63,7 @@
Star keNewe keListe
-
+ \@string/contributions_subtitle_zeroYew barbiyayış%1$d barbiyayışi
@@ -81,6 +81,7 @@
KategoriyiSaziQeyd be
+ KategoriyeHeq te cıQandê yew <a href=\"https://github.com/commons-app/apps-android-commons/issues\">GitHub-cıkewtış</a>ê neweyi rê rapor û teklifan bıaferne.<u>Politikaya nımıtışi</u>
@@ -129,6 +130,7 @@
SernameŞınasnayışNuştekar
+ Tarixê barkerdışiLisansKoordinatiKorbıze
@@ -137,7 +139,22 @@
KeyeBar keVeciyayış
+ Cı kewe
+ ZıwaniBıtexelneAnciya bıcerrebneMı fehm kerd!
+ Cıgeyrayış
+ Cıgeyrayış
+ İştıraki
+ Liste
+ Verên
+ Bırışe
+ meqaleyi
+ Amerika
+ Ewropa
+ Afrika
+ Asya
+ Pasifik
+ Eya, bırışe
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 6228fff6b..5eb2d698a 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -5,6 +5,7 @@
* Geraki
* Glavkos
* KATRINE1992
+* KATRINE1993
* ManosHacker
* Nikosgranturismogt
* Nikosguard
@@ -56,7 +57,7 @@
Οι επιφορτώσεις μουΚοινοποίησηΠροβολή στον περιηγητή
- Τίτλος
+ Τίτλος (Υποχρεωτικό)Παρακαλώ παρέχετε ένα τίτλο για αυτό το αρχείοΠεριγραφήΔεν είναι δυνατή η σύνδεση - αποτυχία του δικτύου
@@ -78,9 +79,9 @@
Ενεργοποιήσετε το GPSΔεν έχουν ακόμη επιφορτωθεί αρχεία
- Δεν υπάρχουν επιφορτώσεις ακόμη
- %1$d επιφόρτωση
- %1$d επιφορτώσεις
+ Δεν υπάρχουν φορτώσεις ακόμη
+ %1$d φόρτωση
+ %1$d φορτώσειςΈναρξη %1$d επιφόρτωσης
@@ -176,7 +177,7 @@
Κοντινοί ΤόποιΔεν βρέθηκαν τόποι εδώ κοντάΠροειδοποίηση
- Αυτό το αρχείο υπάρχει ήδη στα Commons. Είστε σίγουρος ότι θέλετε να συνεχίσετε;
+ Αυτό το αρχείο υπάρχει ήδη στα Commons. Είστε σίγουρος ότι θέλετε να συνεχίσετε;ΝαιΌχιΤίτλος
@@ -238,8 +239,8 @@
Υπήρξε σφάλμα κατά την σκίαση εικόνωνΈνας μοναδικός τίτλος περιγραφής του φακέλλου, που θα χρησιμεύσει ως όνομα φακέλλου. Μπορείτε να χρησιμοποιήσετε τις ήδη υπάρχουσες γλώσσες με διαστήματα. Μην συμπεριλάβετε την επέκταση φακέλλου\nΠαρακαλώ περιγράψετε τα μέσα το δυνατό περισσότερο : Πού οδηγήθηκε αυτό; Τι δείχνει; Ποιο είναι το περιεχόμενο του; Παρακαλώ περιγράψετε τα αντικείμενα ή τα πρόσωπα. Αποκαλύψετε πληροφορίες που δεν μπορούν εύκολο να μαντέψει κανείς, για παράδειγμα την ώρα εντός της ημέρας αν πρόκειται για τοπίο. Αν τα μέσα δείξουν κάτι ασύνηθες, παρακαλώ εξηγήστε τι το καθιστά μη συνηθισμένα.
- Αυτή η εικόνα είναι πολύ σκοτεινή, είστε βέβαιοι ότι θέλετε να την ανεβάσετε; Το Wikimedia Commons είναι μόνο για εικόνες με εγκυκλοπαιδική αξία.
- Αυτή η εικόνα είναι θολή, είστε βέβαιοι ότι θέλετε να την ανεβάσετε; Το Wikimedia Commons είναι μόνο για εικόνες με εγκυκλοπαιδική αξία.
+ Αυτή η εικόνα είναι πολύ σκούρα, θέλετε πράγματι να την φορτώσετε? Το Wikipedia Commons είναι μόνο για εικόνες με εγκυκλοπαιδική αξία.
+ Αυτή η εικόνα είναι θολή , θέλετε όντως να την ανεβάσετε? \n Το Wikimedia Commons είναι μόνο για εικόνες εγκυκλοπαίδειας.Χορηγήστε άδειαΧρησιμοποιήσετε την εξωτερική αποθήκευσηΑποθηκεύσετε εικόνες που παίρνονται στην κάμερα εφαρμογής στην συσκευή σας
@@ -332,6 +333,7 @@
+ Προσθήκη περιγραφήςΕίστε σίγουρος ότι θέλετε να καθαρίσετε το ιστορικό αναζήτησης;Το ιστορικό αναζήτησης διεγράφη
+ Ορίστε για ΑφαίρεσηΚατορθώματαΣτατιστικάΕυχαριστίες που έχουν ληφθεί
@@ -348,10 +350,45 @@
Ο αριθμός εικόνων που ανεβάσατε στα Κοινά που χρησιμοποιήθηκαν σε λήμματα του WikimediaΣυνέβη σφάλμα!Ειδοποίηση Κοινών
+ Συνεισφορές
+ Κοντά σας
+ Ενημερώσεις
+ Πατήστε εδώ για να δείτε την πιο κοντινή θέση που χρειάζεται εικόνες
+ Δεν βρέθηκαν μέρη κοντά σας
+ Λίστα
+ Δεν θα δείτε την πιο κοντινή τοποθεσία που χρειάζεται επιπλέον εικόνες. Ωστόσο, μπορείτε να ενεργοποιήσετε ξανά αυτή την ειδοποίηση στις Ρυθμίσεις αν θέλετε.
+ Εγκατάσταση εικόνας %1$d
+ Επόμενο
+ Προηγούμενο
+ Υποβολή
+ Υπάρχει ήδη ένας φάκελλος με όνομα %1$s. Είστε σίγουρος πως θέλετε να προχωρήσετε ?
+ Καμία εφαρμογή χάρτη δεν βρέθηκε στον υπολογιστή. Παρακαλώ εγκαταστήστε εφαρμογή χάρτη για να χρησιμοποιήσετε αυτήν την ιδιότητα.
+
+ %1$d Ανέβασμα στον υπολογιστή
+ %1$d Ανεβάσματα στον υπολογιστή
+ ΣελιδοδείκτεςΣελιδοδείκτεςεικόνεςΤοποθεσίεςΣελιδοδείκτεςΣελιδοδείκτες
+ Το ανέβασα κατά λάθος
+ Δεν ήξερα ότι θα δημοσιευόταν
+ Κατάλαβα πως δεν προστατεύονται τα ατομικά μου στοιχεία
+ Άλλαξα γνώμη, δεν θέλω να προβάλλεται πλέον δημόσια
+ Λυπάμαι αυτή η εικόνα δεν έχει ενδιαφέρον για εγκυκλοπαίδεια
+ Φορτώθηκε από μένα σε
+ χρησιμοποιήθηκε στο
+ άρθρα
+ Παγκόσμιες
+ Αμερική
+ Ευρώπη
+ Μέση Ανατολή
+ Αφρική
+ Ασία
+ Ειρηνικός
+ Εικόνες χωρίς κατηγορίες χρησιμοποιούνται σπάνια. Θέλετε πράγματι να στείλετε δίχως να επιλέξετε κατηγορίες?
+ Ναι, υποβολή
+ Όχι, Επιστροφή
diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml
new file mode 100644
index 000000000..04d05b074
--- /dev/null
+++ b/app/src/main/res/values-eo/strings.xml
@@ -0,0 +1,214 @@
+
+
+
+ Esplori
+ Esplori
+ Aspekto
+ Ĝenerala
+ Prikomentado
+ Pozicio
+ Komunejo
+ •
+ Agordoj
+ Alŝuti al la Komunejo
+ Uzantnomo
+ Pasvorto
+ Ensaluti en via Komunejo beta-konto
+ Ensaluti
+ Ĉu pasvorto forgesita?
+ Registriĝi
+ Ensalutado
+ Bonvolu atendi...
+ Ensalutado sukcesis
+ Ensalutado malsukcesis
+ Dosiero ne trovita. Bonvolu provi alian dosieron.
+ Aŭtentigo malsukcesis, bonvolu denove ensaluti
+ La alŝutado komenciĝis!
+ %1$s alŝutita!
+ Tuŝetu por vidi vian alŝutadon
+ Komenciĝas la alŝutado de %1$s
+ Alŝutante %1$s
+ Finiĝis la alŝutado de %1$s
+ La alŝutado de %1$s malsukcesis
+ Tuŝetu por vidi
+
+ %1$d dosiero alŝutata
+ %1$d dosieroj alŝutataj
+
+ Miaj lastaj alŝutoj
+ Envicigita
+ Malsukcesis
+ %1$d%% kompleta
+ Alŝutante
+ De la galerio
+ Fari foton
+ Apuda
+ Miaj alŝutoj
+ Konigi
+ Vidi en retumilo
+ Titolo (deviga)
+ Bonvolu doni titolon al ĉi tiu dosiero
+ Priskribo
+ Ne eblas ensaluti. Estas problemo pri la loka reto.
+ Ne eblas ensaluti. Bonvolu kontroli viajn uzantnomon kaj pasvorton
+ Tro da,nesukcesaj provoj. Bonvolu provi denove post kelkaj minutoj.
+ Pardonon, ĉi tiu uzanto estas barita de la Vikimedia Komunejo
+ Vi devas provizi vian dupaŝan aŭtentigan kodon.
+ Ensalutado malsukcesis
+ Alŝuti
+ Nomu ĉi tiun aron
+ Bonvolu provizi nomon por ĉi tiu aro
+ Ŝanĝoj
+ Alŝuti
+ Serĉi tra kategorioj
+ Konservi
+ Aktualigi
+ Listo
+ GPS estas malŝaltita en via aparato. Ĉu vi volas ŝalti ĝin?
+ Ŝalti la GPS
+ Neniuj alŝutaĵoj ĝis nun!
+
+ \@string/contributions_subtitle_zero
+ (%1$d)
+ (%1$d)
+
+ Kategorioj
+ Agordoj
+ Registriĝi
+ Elstarigitaj bildoj
+ Kategorio
+ Pri
+ <u>Privateca politiko</u>
+ <u>Agnoskoj</u>
+ Pri
+ Sendi viajn komentojn (per retpoŝto)
+ Neniu retpoŝtilo instalita
+ Laste uzitaj kategorioj
+ Atendas la unuan Sinkronigado...
+ Vi ankoraŭ ne alŝutis fotojn.
+ Reprovi
+ Nuligi
+ Ĉi tiu bildo estos sub permesilo %1$s
+ Elŝuti
+ Defaŭlta permesilo
+ Uzi la antaŭan titolon/priskribon
+ Aŭtomate akiri la nunan pozicion
+ Nokta reĝimo
+ CC0
+ CC BY-SA 3.0
+ CC BY-SA 3.0 (Aŭstrio)
+ CC BY-SA 3.0 (Germanio)
+ CC BY-SA 3.0 (Estonio)
+ CC BY-SA 3.0 (Hispanio)
+ CC BY-SA 3.0 (Kroatio)
+ CC BY-SA 3.0 (Luksemburgo)
+ CC BY-SA 3.0 (Nederlando)
+ CC BY-SA 3.0 (Norvegio)
+ CC BY-SA 3.0 (Pollando)
+ CC BY-SA 3.0 (Rumanio)
+ CC BY 3.0
+ CC BY-SA 4.0
+ CC BY 4.0
+ CC Zero
+ La Vikimedia Komunejo gastigas plej multajn bildojn kiuj estas uzataj sur Vikipedio.
+ Viaj bildoj helpas klerigi homojn en la tuta mondo!
+ Bonvolu nur alŝuti bildojn kiujn vi mem fotis aŭ kreis.
+ Naturaj objektoj (floroj, bestoj, montoj)\n• Utilaj objektoj (bicikloj, fervojaj stacidomoj)\n• Famaj homoj (via urbestro, olimpikaj atletoj kiujn vi renkontis)
+ Naturaj objektoj (floroj, bestoj, montoj)
+ Utilaj objektoj (bicikloj, fervojaj stacidomoj)
+ Famaj homoj (via urbestro, olimpikaj atletoj kiujn vi renkontis)
+ Bonvolu NE alŝuti:
+ - memfotoj aŭ fotoj de viaj amikoj\n- fotoj kiujn vi elŝutis de interreto \n- ekrankopioj de komercaj aplikaĵoj
+ Memfotoj aŭ fotoj de viaj amikoj
+ Fotoj kiujn vi elŝutis de interreto
+ Ekrankopioj de komercaj aplikaĵoj
+ Ekzemplo de alŝutaĵo:
+ Jes!
+ <u>Ekscii pli</u>
+ Kategorioj
+ Ŝargado...
+ Neniu elektita
+ Sen priskribo
+ Nekonata permesilo
+ Aktualigi
+ Bone
+ Averto
+ Jes
+ Ne
+ Titolo
+ Titolo de la aŭdovidaĵo
+ Priskribo
+ Kreinto
+ Alŝutdato
+ Permesilo
+ Koordinatoj
+ Neniu provizita
+ Nuligi
+ Malfermi
+ Fermi
+ Ĉefpaĝo
+ Alŝuti
+ Apude
+ Pri
+ Agordoj
+ Prikomentado
+ Elsaluti
+ Lernilo
+ Sciigoj
+ Elstarigita
+ neniu priskribo trovita
+ Dosiera paĝo de la Komunejo
+ Vikidatumero
+ Vikipedia artikolo
+ La bildo estas tro malluma. Ĉu vi tamen volas alŝuti ĝin? La Komunejo (Wikimedia Commons) estas nur por bildoj kun enciklopedia valoro.
+ La bildo estas malklara. Ĉu vi tamen volas alŝuti ĝin? La Komunejo (Wikimedia Commons) estas nur por bildoj kun enciklopedia valoro.
+ Doni permeson
+ Ensaluti en vian konton
+ Sendi la protokolan dosieron
+ Neniu retumilo trovita por malfermi la URL
+ Eraro! URL ne trovita
+ Proponi forigon
+ Oni proponis ke ĉi tiu bildo estu forigota.
+ <u>Vidu la retpaĝon por pliaj detaloj</u>
+ Malfermi en retumilo
+ Preterpasi
+ Ensaluti
+ Ĉu vere vi volas transpasi la ensalutadon?
+ Vi tiam ne povos alŝuti bildojn.
+ Bonvolu ensaluti por uzi ĉi tiun eblon
+ La pozicio ne ŝanĝiĝis.
+ Pozicio ne havebla.
+ %1$s lasis mesaĝon sur via diskutpaĝo
+ Dankon pro tio ke vi faris redakton
+ %1$s menciis vin sur %2$s.
+ VIKIDATUMOJ
+ VIKIPEDIO
+ KOMUNEJO
+ <u>Oftaj demandoj</u>
+ <u>Traduki</u>
+ Lingvoj
+ Daŭrigi
+ Nuligi
+ Reprovi
+ Komprenite!
+ Neniuj bildoj trovitaj!
+ Okazis eraro ŝargante la bildojn.
+ Alŝutita de: %1$s
+ Kontribuoj
+ Tuŝetu ĉi tie por vidi apudan lokon kiu bezonas bildojn
+ Neniu proksima loko trovita ĉe vi.
+ %1$d en bildaro
+ Sekva
+ Antaŭa
+ Neniu kongrua aplikaĵo troveblas en via aparato. Bonvolu instali tian por uzo kun ĉi tiu funkcio.
+ Tutmonda
+ Eŭropo
+ Meza Oriento
+ Azio
+ Bildo sen kategorioj estas malofte uzebla. Ĉu vi nepre volas aldoni sen elekti kategoriojn?
+
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index d3d4388a1..7792c92b9 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -5,6 +5,7 @@
* Astroemi
* Benfutbol10
* Fitoschido
+* JO777
* Jduranboger
* Jelou
* Ktranz
@@ -19,7 +20,7 @@
ExplorarExplorarApariencia
- Generales
+ GeneralSugerenciasUbicaciónCommons
@@ -33,9 +34,9 @@
¿Olvidaste la contraseña?RegístrateAccediendo
- Espera un momento…
- Acceso correcto.
- Acceso fallido.
+ Espere un momento…
+ Inicio de sesión exitoso
+ Falló el inicio de sesión.No se encontró el archivo. Prueba con otro.Falló la autenticación; prueba a acceder otra vezHa comenzado la carga.
@@ -61,7 +62,7 @@
Mis subidasCompartirVer en el navegador
- Título
+ Título (Requerido)Proporciona un título para este archivoDescripciónNo se pudo iniciar sesión: falla de red
@@ -84,8 +85,8 @@
No hay subidas aún\@string/contributions_subtitle_zero
- %1$d carga
- %1$d cargas
+ (%1$d)
+ (%1$d)Iniciando %1$d carga
@@ -181,7 +182,7 @@
Lugares cercanosNo se encontraron lugares cercanosAtención
- Este archivo ya existe en Commons. ¿Confirmas que quieres continuar?
+ Este archivo ya existe en Commons. ¿Deseas continuar?SíNoTítulo
@@ -243,14 +244,14 @@
Error al almacenar imágenes en la antememoriaUn 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.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.
- Esta imagen es demasiado oscura. ¿Confirmas que quieres cargarla? Wikimedia Commons solo acepta imágenes con valor enciclopédico.
- Esta imagen se ve borrosa. ¿Confirmas que quieres cargarla? Wikimedia Commons solo acepta imágenes con valor enciclopédico.
+ La imagen está demasiado oscura, ¿seguro que quieres subirla? Wikimedia Commons solo acepta imágenes con valor enciclopédico.
+ La imagen está borrosa, ¿seguro que quieres subirla? Sube solo imágenes con valor enciclopédico.Otorgar permisoUtilizar almacenamiento externoGuardar en el dispositivo imágenes capturadas con la cámara de la aplicaciónAccede a tu cuentaEnviar archivo de registro
- Enviar archivo de registro a los desarrolladores por correo electrónico
+ Enviar archivo de registro a los desarrolladores por correo electrónico para ayudar a depurar problemas con la aplicación. Nota: los registros pueden potencialmente contener información que te identifiqueNo se encontró ningún navegador con el que abrir el URLError: no se encontró el URLNominar para borrado
@@ -262,8 +263,8 @@
¿Realmente querés omitir el inicio de sesión?No serás capaz de subir imágenes.Por favor inicia sesion para usar esta característica
- Copia el Wikicódigo al portapapeles
- Wikicódigo copiado al portapapeles
+ Copia el Wikicódigo al portapapeles
+ El Wikitexto fue copiado al portapapelesLa ubicación no ha cambiado.La ubicación no está disponible.Se necesita permiso para mostrar una lista de lugares cercanos
@@ -339,6 +340,7 @@
+ Añadir descripción¿Confirmas que quieres vaciar el historial de búsquedas?Historial de búsqueda eliminado
+ Nominar para borradoLogrosESTADÍSTICASAgradecimientos recibidos
@@ -355,6 +357,62 @@
El número de imágenes que has subido a Commons que fueron utilizadas en artículos de Wikimedia¡Ocurrió un error!Notificación de Commons
+ Contribuciones
+ Cercanos
+ Notificaciones
+ Mostrar notificaciones de cercanía
+ Toca aquí para ver el lugar más cercano que necesita fotos
+ No se encontraron lugares cercanos cerca de ti
+ ListaPermiso de almacenamientoNecesitamos tu permiso para acceder al almacenamiento externo de tu dispositivo para poder subir imágenes.
+ Ya no verás el lugar más cercano que necesita fotos. Sin embargo, puedes volver a habilitar esta notificación en la configuración.
+ Paso %1$d de %2$d
+ Imagen %1$d del conjunto
+ Siguiente
+ Anterior
+ Enviar
+ Ya existe un archivo con el nombre %1$. ¿Seguro que deseas continuar?
+ No se encontró una aplicación para mapas compatible en tu dispositivo. Instala una para usar esta característica.
+
+ %1$d Subida
+ %1$d Subidas
+
+ Marcadores
+ Marcadores
+ Imágenes
+ Ubicaciones
+ Añadir o quitar de marcadores
+ Marcadores
+ No has añadido ningún marcador
+ Marcadores
+ Se inició la recopilación de registros. Reinicie la aplicación, realice la acción que desea registrar y luego presione «Enviar archivo de registro» nuevamente
+ Lo subí por error
+ No sabía que sería visible públicamente
+ Me di cuenta que es malo para mi privacidad
+ Cambié de opinión, no quiero que siga siendo visible públicamente
+ Perdón esta imagen no es interesante para una enciclopedia
+ Subida por mí mismo el
+ ,usado en
+ artículos
+ ¡Bienvenido a Commons!\n\nSube tu primer archivo tocando el icono de la cámara o galería arriba.
+ Mundial
+ América
+ Europa
+ Medio Oriente
+ África
+ Asia
+ Pacífico
+ No hay categorías seleccionadas
+ Las imágenes sin categorías raramente se pueden usar. ¿Seguro que quieres enviar sin seleccionar ninguna categoría?
+ Sí, enviar
+ No, regresar
+ (Para todas las imágenes en el conjunto)
+ Buscar esta área
+ Solicitud de permiso
+ ¿Desea que usemos su ubicación actual para mostrar el lugar más cercano que necesita imágenes?
+ Incapaz de mostrar el sitio más cercano que necesitas fotos sin permisos de ubicación
+ Jamás mostrar esto de nuevo
+ Mostrar permiso de ubicación
+ Pida permiso de ubicación cuando sea necesario para ver la tarjeta de notificación cercana.
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index eb964e1a2..075f34a34 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -55,7 +55,7 @@
Nire igoerakPartekatuIkusi nabigatzailean
- Izenburua
+ IzenburuaMesedez, eman izenburu bat fitxategi honetarakoDeskribapenaEzin izan da sartu - sarean akatsa
@@ -76,7 +76,7 @@
GPSa desgaituta dago gailu honetan. Gaitu nahi duzu?GPSa gaituOraindik ez da ezer igo
-
+ \@string/contributions_subtitle_zeroigoera 1%1$d igoera
@@ -172,7 +172,6 @@
Gertuko lekuakEz da hurbileko lekurik aurkituOharra
- Fifxategia dagoeneko Commonsen existitzen da. Ziur zaude jarraitu nahi duzula?BaiEzIzenburua
@@ -229,8 +228,6 @@
Argazkiak hartzerakoan sortutako akatsaFitxategi izenburu deskribatzaile bakarra, fitxategi-izen gisa balioko duena. Hizkuntza arrunta erabil dezakezu espazioekin. Ez sartu fitxategiaren luzapena.Mesedez, deskribatu multimedia elementua ahal duzun gehien: non hartu zen? zer erakusten du? zein da bere testuingurua? Mesedez, objektuak eta pertsonak deskribatu. Eman asmatzeko erraza ez den informazioa, adibidez, paisaia bat izatekotan, eguneko zein orudtan hartu den. Multimediak zerbait berezia erakusten badu, mesedez azaldu zerk egiten duen berezia.
- Argazkia ilunegia da, ziur zaude kargatu nahi duzula? Wikimedia Commons-ek balio entziklopedikoa duten argazkiak bakarrik hartzen ditu.
- Argazkia lausoa da, ziur zaude kargatu nahi duzula? Wikimedia Commons-ek balio entziklopedikoa duten argazkiak bakarrik hartzen ditu.Baimena emanKanpo-biltegia erabiliAplikazioaren kamerarekin ateratako argazkiak zure gailuan gorde
@@ -336,4 +333,5 @@
Errorea gertatu da!Commons JakinarazpenaBiltegiratze baimena
+ Asia
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index c65b4903c..53e266ce2 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -2,7 +2,9 @@
+ Uppgötva
+ UppgötvaÚtlitAlmenntUmsagnirStaðsetningCommons
- •
+ • \Stillingar
+ Senda inn á CommonsNotandanafnLykilorðSkráðu inn á Beta-prófunaraðgang Commons
@@ -21,7 +24,7 @@
Innskráning tókst!Innskráning mistókst!Skráin fannst ekki. Prófaðu aðra skrá.
- Auðkenning tókst ekki!
+ Auðkenning mistókst, skráðu þig inn afturInnsending í gangi!%1$s var sent inn!Bankaðu til að skoða sem þú ert að senda inn
@@ -45,16 +48,18 @@
Innsendu skrárnar mínarDeilaSkoða í vafra
- Titill
+ Titill (krafist)Gefðu þessari skrá einhvern titilLýsingInnskráning mistókst - bilun í neti
+ Innskráning mistókst - athugaðu notandanafn og lykilorðið þittOf margar misteknar tilraunir. Reyndu aftur eftir nokkrar mínútur.Því miður, þessi notandi hefur verið bannaður á CommonsÞú verður að setja inn tveggja-þrepa auðkenningarkóðann þinn.Innskráning mistókstSenda inn skrárSettu nafn á þetta sett
+ Gefðu þessu setti eitthvað nafnBreytingarSenda innLeita í flokkum
@@ -66,8 +71,8 @@
Engar innsendingar ennþá\@string/contributions_subtitle_zero
- %1$d innsending
- %1$d innsendingar
+ (%1$d)
+ (%1$d)Byrja %1$d innsendingu
@@ -83,6 +88,7 @@
StillingarNýskráÁberandi myndir
+ FlokkurUmWikimedia Commons forritið er opinn og frjáls hugbúnaður sem gerður er og viðhaldið af stuðningsaðilum og sjálfboðaliðum Wikimedia samfélagsins. Wikimedia Foundation sjálfseignarstofnunin kemur ekki að gerð, forritun eða viðhaldi forritsins. \Útbúðu nýjar <a href=\"https://github.com/commons-app/apps-android-commons/issues\">GitHub tilkynningar (issue)</a> til að koma villum og uppástungum á framfæri.
@@ -102,7 +108,7 @@
Sjálfgefið notkunarleyfiNota fyrri titil/lýsinguNá sjálfvirkt í núverandi staðsetningu
- Lesa núverandi staðsetningu til að geta stungið upp á flokkum ef myndin er ekki með hnattstaðsetningarhnitum
+ Les núverandi staðsetningu til að geta stungið upp á flokkum ef myndin er ekki með hnattstaðsetningarhnitum. Aðvörun: þetta mun koma upp um staðsetninguna þína.NæturhamurNota dökkt þema Attribution-ShareAlike 4.0
@@ -148,6 +154,7 @@
Forðastu höfundaréttarvarið efni sem finnst á netinu eins og myndir af veggspjöldum, bókarkápum, o.s.frv.Heldurðu að þú hafir náð þessu?Já!
+ <u>Frekari upplýsingar</u>FlokkarHleð…Ekkert valið
@@ -161,7 +168,7 @@
Staðir í nágrenninuEngir staðir fundust í nágrenninuAðvörun
- Þessi skrá er þegar fyrirliggjandi á Commons. Ertu viss um að þú viljir halda áfram?
+ Þessi skrá er þegar fyrirliggjandi á Commons. Ertu viss um að þú viljir halda áfram?JáNeiTitill
@@ -190,6 +197,8 @@
BakgrunnsmyndMynd gagnamiðils brástEngin mynd fannst
+ Engir undirflokkar fundust
+ Engir yfirflokkar fundustSenda inn myndZao-fjallLamadýr
@@ -221,19 +230,27 @@
Villa kom upp í skyndiminni myndaEinstakur og lýsandi titill, sem mun verða skráarheiti. Þú mátt nota einfaldan texta með bilum. Ekki hafa með neina skráarendinguLý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.
- Þ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.
- Þ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.
+ Þ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.
+ Þ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.Gefa heimildNota ytri gagnageymsluVistaðu myndir sem teknar hafa verið með innbyggðu myndavélinni í tækinu þínuSkrá inn á aðganginn þinnSenda atvikaskrá
- Senda atvikaskrá til forritaranna með tölvupósti
+ Senda atvikaskrá til forritaranna með tölvupósti til að hjálpa við að aflúsa vandamál í forritinu. Athugaðu: atvikaskrár geta innihaldið persónugreinanleg gögnGat ekki ræst vefvafra til að opna slóðVilla: Slóð fannst ekkiTilnefna til eyðingarÞessi mynd hefur verið valin til eyðingar.
+ <u>Sjá nánar á vefsíðunni</u>Skoða í vafra
+ Sleppa
+ Skrá inn
+ Viltu í alvörunni sleppa innskráningu?
+ Þú munt ekki geta sent inn myndir
+ Skráðu þig inn til að nota þennan eiginleika
+ Afrita wiki-textann á klippispjaldið
+ Wiki-textinn var afritaður á klippispjaldiðStaðsetning hefur ekki breyst.Staðsetning ekki tiltæk.Heimild þarf til að birta lista yfir staði í nágrenninu
@@ -268,7 +285,119 @@
Engir myndir fundust!Villa kom upp við að hlaða inn myndum.Sent inn af: %1$s
+ Þú ert útilokaður frá breytingum á Commons
+ Mynd dagsins
+ Mynd dagsins
+ Leita
+ Leita á Commons
+ Engar myndir sem samsvara %1$s fundust
+ Leita
+ Nýlegar leitir:
+ Nýlegar leitarbeiðnir
+ Villa kom upp við að hlaða inn flokkum.
+ Villa kom upp við að hlaða inn undirflokkum.
+ Tókst að hlaða mynd inn í %1$s á Wikidata!
+ Mistókst að uppfæra samsvarandi Wikidata-einindi!
+ Setja sem bakgrunnsmynd
+ Tókst að stilla bakgrunnsmynd!
+ Spurningaleikur
+ Er í lagi að senda inn þessa mynd?
+ Spurning \
+ Niðurstaða
+ Ef þú heldur áfram að senda inn myndir sem krefjast að þeim sé eytt, er líklegt að aðgangurinn þinn verði bannaður. Ertu viss um að þú viljir hætta í spurningaleiknum?
+ Meira en %1$s myndanna sem þú hefur sent inn hefur verið eytt. Ef þú heldur áfram að senda inn myndir sem krefjast að þeim sé eytt, er líklegt að aðgangurinn þinn verði bannaður.\n\nMyndir þú vilja skða kennsluefnið aftur og taka síðan einn léttan spurningaleik til að hjálpa þér til að læra hvernig myndir þú ættir að senda inn og hverjar ekki?
+ Sjálfsmyndir hafa ekki mikið alfræðigildi. Ekki senda inn myndir af sjálfum þér nema ef þegar sé komin Wikipedia-grein um þig.
+ Myndir af náttúrulegum eða manngerðum fyrirbærum utanhúss er í flestum tilfellum í lagi að senda inn. Athugið að tímabundnar listrænar innsetningar utanhúss geta verið höfundarréttavarðar og því má ekki senda inn myndir af þeim án sérstaks leyfis.
+ Skjámyndir af vefsvæðum teljast vera afleidd verk og falla því undir höfundarréttarákvæði sjálfs vefsvæðisins. Slíkar skjámyndir mætti nota ef leyfi fæst til þess frá höfundinum. Án slíks leyfis myndi hvert það verk sem þú skapar, en sem byggist á þeirra verki, vera lagalega álitið óleyfilegt afrit í eigu upprunalegs höfundar.
+ Eitt af markmiðum Commons er að safna myndum í góðum gæðum. Þar af leiðandi ætti ekki að senda inn móskulegar eða of dökkar myndir. Alltaf ætti að velja greinargóðar, skýrar myndir með góðri lýsingu.
+ Myndir sem sýna tæknileg atriði eða menningarleg eru meira en vel þegnar á Commons.
+ Meira en %1$s myndanna sem þú hefur sent inn hefur verið eytt. Ef þú heldur áfram að senda inn myndir sem krefjast að þeim sé eytt, er líklegt að aðgangurinn þinn verði bannaður.
+ Þú varst með %1$s af svörunum rétt. Til hamingju!
+ Veldu annan af kostunum hér fyrir neðan til að svara spurningunni
+ Innskráningarsetan þín rann út, skráðu þig inn aftur.
+ Deildu spurningaleiknum með vinum þínum!
+ Halda áfram
+ Rétt svar
+ Rangt svar
+ Er í lagi að senda inn þessa skjámynd?Deila forritiHnit voru ekki tilgreind við val myndarVilla við að sækja nálæga staði.
+ + Bæta við lýsingu
+ Ertu viss um að þú viljir eyða leitarferlinum þínum?
+ Leitarferli eytt
+ Tilnefna til eyðingar
+ Frammistaða
+ TÖLFRÆÐI
+ Mótteknar þakkir
+ Áberandi myndir
+ STIG
+ Myndir sendar inn
+ Myndir ekki hafnað
+ Myndir notaðar
+ Deildu frammistöðu þinni með vinum þínum!
+ Stig þitt eykst eftir því sem þú uppfyllir betur þessar kröfur. Atriði í \"tölfræði\"-hlutanum teljast ekki með í stigaútreikningi þínum.
+ lágmarksfjöldi sem er krafist: \
+ Heildarfjöldi mynda sem þú hefur sent inn á Commons, með hverskyns innsendingarhugbúnaði
+ Prósentuhlutfall mynda sem þú hefur sent inn á Commons sem ekki hefur verið eytt
+ Heildarfjöldi mynda sem þú hefur sent inn á Commons sem hafa verið notaðar með Wikimedia-greinum
+ Villa kom upp!
+ Tilkynning frá Commons
+ Framlög
+ Nálægt
+ Tilkynningar
+ Birta tilkynningu um nágrenni
+ Ýttu hér til að sjá nálægasta staðinn sem þarfnast mynda
+ Engir staðir fundust í nágrenninu
+ Listi
+ Heimild á gagnageymslu
+ Við þurfum að fá heimild frá þér fyrir aðgang í gagnageymslu tækisins svo hægt sé að senda inn myndir.
+ Þú munt ekki lengur sjá nálægasta staðinn sem þarfnast mynda. Hinsvegar geturðu, ef þú vilt, endurvirkjað þessar tilkynningar í stillingunum.
+ Skref %1$d af %2$d
+ Mynd %1$d í setti
+ Næsta
+ Fyrri
+ Senda inn
+ Skrá með heitinu %1$s er til staðar. Ertu viss um að þú viljir halda áfram?
+ Ekkert samhæft landakortaforrit fannst á tækinu þínu. Settu kortaforrit til að nýta þennan möguleika.
+
+ %1$d innsending
+ %1$d innsendingar
+
+ Bókamerki
+ Bókamerki
+ Ljósmyndir
+ Staðsetningar
+ Bæta í/Fjarlægja úr bókamerki
+ Bókamerki
+ Þú hefur ekki bætt við neinum bókamerkjum
+ Bókamerki
+ Atvikaskráning er hafin. ENDURRÆSTU forritið, framkvæmdu aðgerðina sem þú vilt skrá og ýttu síðan aftur á \'Senda atvikaskrá\'
+ Ég sendi hana inn fyrir mistök
+ Ég vissi ekki að hún yrði öllum sýnileg
+ Ég áttaði mig á að þetta væri slæmt fyrir gagnaleynd mína
+ Ég skipti um skoðun, ég vil ekki að hún sé lengur öllum sýnileg
+ Afsakið, þessi mynd hefur ekkert gildi fyrir alfræðirit
+ Sent inn af mér sjálfum
+ , notað í
+ greinum
+ Velkomin í Commons!\n\nSendu inn fyrstu margmiðlunargögnin þín með því að ýta á myndavélina eða myndasafnstáknið hér fyrir ofan.
+ Á heimsvísu
+ Ameríka
+ Evrópa
+ Miðausturlönd
+ Afríka
+ Asía
+ Kyrrahaf
+ Engir flokkar valdir
+ Myndir án flokka eru sjaldnast nýtilegar. Ertu viss um að þú viljir senda þetta inn án þess að velja flokka?
+ Já, senda inn
+ Nei, fara til baka
+ (fyrir allar myndir í setti)
+ Beiðni um heimild
+ Viltu að við notum núverandi staðsetningu þína til að sjá nálægasta staðinn sem þarfnast mynda?
+ Get ekki birt nálægasta staðinn sem þarfnast mynda án þess að fá heimild til að sjá staðsetningu þína
+ Ekki spyrja þessa aftur
+ Birta heimild um staðsetningu
+ Biðja um heimild til að sjá staðsetningu þegar þess er þörf fyrir tilkynningaspjald um næsta nágrenni.
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 8518dc82f..40d8fefef 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -4,6 +4,7 @@
* Beta16
* Davio
* Gianfranco
+* Lorelai87
* Nemo bis
* S4b1nuz E.656
* Sarah Bernabei
@@ -56,7 +57,7 @@
I miei caricamentiCondividiVisualizza nel browser
- Titolo
+ Titolo (obbligatorio)Per favore, dai un titolo a questo fileDescrizioneImpossibile effettuare l\'accesso - errore di rete
@@ -79,8 +80,8 @@
Non è stato ancora caricato niente\@string/contributions_subtitle_zero
- %1$d caricamento
- %1$d caricamenti
+ (%1$d)
+ (%1$d)Iniziato %1$d caricamento
@@ -166,7 +167,7 @@
Luoghi nelle vicinanzeNessun luogo trovato nelle vicinanzeAttenzione
- Questo file esiste già su Commons. Sei sicuro di voler continuare?
+ Questo file esiste già su Commons. Sei sicuro di voler continuare?SìNoTitolo
@@ -257,8 +258,10 @@
Risposta correttaRisposta sbagliataCondividi applicazione
+ Nessuna ricerca recenteSei sicuro di voler cancellare la tua cronologia di ricerca?Cronologia di ricerca cancellata
+ Proponi per la cancellazioneRisultatiImmagini in evidenzaImmagini caricate
@@ -267,6 +270,17 @@
Il numero di immagini che hai caricato su Commons, tramite qualsiasi software di caricamentoLa percentuale di immagini che hai caricato su Commons che non sono state cancellateIl numero di immagini che hai caricato su Commons che sono state usate nelle voci di Wikimedia
+ Contributi
+ Notifiche
+ Elenco
+ Passo %1$d di %2$d
+ Successivo
+ Precedente
+ Invia
+
+ %1$d caricamento
+ %1$d caricamenti
+ SegnalibriSegnalibriImmagini
@@ -274,5 +288,21 @@
SegnalibriNon hai aggiunto alcun segnalibroSegnalibri
+ L\'ho caricata per errore
+ Non sapevo che sarebbe stata visibile pubblicamente
+ Ho cambiato idea, non voglio più che sia pubblicamente visibile
+ Spiacente, questa immagine non è interessante per un\'enciclopedia
+ Caricato da me stesso il
+ vociBenvenuto su Commons!\n\nCarica il tuo primo file multimediale toccando l\'icona della fotocamera o della galleria sopra.
+ Tutto il mondo
+ America
+ Europa
+ Medio oriente
+ Africa
+ Asia
+ Pacifico
+ Nessuna categoria selezionata
+ Sì, invia
+ Cerca in questa area
diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml
index a20b81fc5..81c939335 100644
--- a/app/src/main/res/values-iw/strings.xml
+++ b/app/src/main/res/values-iw/strings.xml
@@ -57,7 +57,7 @@
ההעלאות שלישיתוףהצגה בדפדפן
- כותרת
+ כותרת (נדרש)נא לתת כותרת לקובץ הזהתיאורלא ניתן להיכנס – כשל בתקשורת
@@ -80,8 +80,8 @@
לא הועלה עדיין שום דבר\@string/contributions_subtitle_zero
- העלאה אחת
- %1$d העלאות
+ (%1$d)
+ (%1$d)התחלת העלאה
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index c02ba7258..9e7d1df9e 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -55,7 +55,7 @@
自分のアップロード共有ブラウザーで表示
- タイトル
+ タイトル (必須)ファイル名をつけてください説明ログインできません - ネットワークのエラーです
@@ -77,7 +77,8 @@
まだ何もアップロードされていません。\@string/contributions_subtitle_zero
- pne=%1$d upload
+ (%1$d)
+ (%1$d件のアップロード)Starting %1$d upload
@@ -172,7 +173,6 @@
近くの場所付近の場所が見つかりません警告
- このファイルは既にコモンズにあります。本当にアップロードしますか?はいいいえタイトル
@@ -232,8 +232,6 @@
画像をキャッシュする際のエラーファイル固有の説明的な表題。ファイル名として使われます。平易な言葉を使い、空白を入れることができます。拡張子は含めないでください。可能な限りメディアを説明してください: 撮影地はどこですか? それは何を示していますか? どんな文脈がありますか? 被写体の物や人を説明してください。容易に推測できない情報、例えば風景であれば時刻を明示します。特筆すべき物事が映っている場合は、何が珍しいのかを説明してください。
- この画像は暗すぎますがアップロードしますか? ウィキメディア・コモンズは百科事典に適した画像のみ受け付けます。
- ピントが合っていませんが、アップロードしますか? ウィキメディア・コモンズは百科事典に適した画像のみ受け付けます。権限を付与外部ストレージを使用アプリ内のカメラで撮影した写真を端末に保存する
diff --git a/app/src/main/res/values-ji/strings.xml b/app/src/main/res/values-ji/strings.xml
index 9fa4b1d68..7ff432d7b 100644
--- a/app/src/main/res/values-ji/strings.xml
+++ b/app/src/main/res/values-ji/strings.xml
@@ -8,6 +8,7 @@
פֿידבעקלאקאציעקאמאנס
+ •איינשטעלונגעןבאַניצער־נאָמעןפאַסווארט
@@ -18,7 +19,7 @@
אריינלאגירט מיט הצלחה!ארײַנלאגירן אדורכגעפאלן!טעקע נישט געראפן. פרובירט אפשר אן אנדער טעקע.
- אויטענטיפֿיצירן דורכגעפֿאלן!
+ אויטענטיפֿיצירן דורכגעפֿאלן, ביטע אריינלאגירן נאכאמאלארויפלאדן אנגעהויבן!%1$s ארויפגעלאדן!!דרוקט צו זען אײַער ארויפֿלאד
@@ -42,7 +43,8 @@
מײַנע ארויפלאדןטיילןבאקוקן אין בלעטערער
- טיטל
+ טיטל (געפֿאדערט)
+ זייט אזוי גוט און פארזארג א טיטל פאר דער טעקעבאַשרײַבונגנישט מעגלעך אריינלאגירן – נעצווערק פֿעלערארײַנלאגירן אדורכגעפאלן!
@@ -54,17 +56,24 @@
דערפֿרישןליסטע
- \@string/contributions_subtitle_zero
- איין ארויפֿלאד
- %1$d ארויפֿלאדן
+ \@string/contributions_subtitle_zero
+ (%1$d)
+ (%1$d)אנהייבן %1$d ארויפֿלאד אנהייבן %1$d ארויפֿלאדן
+
+ %1$d ארויפֿלאד
+ %1$d ארויפֿלאדן
+
+ קיין קאטעגאריעס צוגעפאסט צו %1$s נישט געפֿונעןקאַטעגאריעסאיינשטעלונגען
+ איינשרייבןרעקאמענדירטע בילדער
+ קאַטעגאריעוועגןוועגןשיקן פֿידבעק (דורך בליצפאסט)
@@ -101,9 +110,12 @@
ווארענונגיאניין
+ טיטלמחברליצענץקאארדינאטן
+ איר ווילט טאקע ארויסלאגירן?
+ קאמאנס־לאגאטולפאןאַנולירןאפֿן
diff --git a/app/src/main/res/values-jv/strings.xml b/app/src/main/res/values-jv/strings.xml
index 28f68394b..6420ca068 100644
--- a/app/src/main/res/values-jv/strings.xml
+++ b/app/src/main/res/values-jv/strings.xml
@@ -49,7 +49,7 @@
UnggahankuDumDeleng ing Pangluru
- Sesirah
+ SesirahWènèhi barkas iki sesirahWedharanOra bisa mlebu log - jaringané gagal
@@ -70,7 +70,7 @@
GPS dipatèni ing pirantiné panjenengan. Panjenengan arep ngurubaké?Urubaké GPSDurung ana unggahan
-
+ \@string/contributions_subtitle_zero%1$d unggahan%1$d unggahan
@@ -145,7 +145,6 @@
Papan Cedhak KénéOra ana papan cedhak kénéPélik
- Barkasé wis ana ing Commons. Panjenengan yakin arep mbacutaké?IyaOraSesirah
diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml
index 31103028e..c7343e86d 100644
--- a/app/src/main/res/values-ka/strings.xml
+++ b/app/src/main/res/values-ka/strings.xml
@@ -39,7 +39,7 @@
ჩემი ატვირთვებიგაზიარებაბრაუზერში გახსნა
- სათაური
+ სათაურიაღწერაშესვლა ვერ ხერხდება - ქსელის შეცდომაძალიან ბევრი წარუმატებელი მცდელობა. გთხოვთ, რამდენიმე წუთში სცადეთ კვლავ.
diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml
index d72208b1c..dd1c1ee09 100644
--- a/app/src/main/res/values-kab/strings.xml
+++ b/app/src/main/res/values-kab/strings.xml
@@ -39,7 +39,7 @@
Ifuyla i suliɣBḍuSken deg yiminig
- Azwel
+ AzwelAglamUr izmir ara ad yeqqen - tuccḍa n uẓeṭṭaDdeq n uɛraḍ ur yeddin ara. Ɛreḍ akka di kra n tisdatin
@@ -56,7 +56,7 @@
GPS ur yermid ɣef yibenk-ik. Tebɣiḍ ad tremdeḍ-t?Rmed GPSUsla ayen yulin
-
+ \@string/contributions_subtitle_zero%1$d n usali%1$d n usali
@@ -143,7 +143,6 @@
Idigen iqeṛbenUlac ayen yettwafen s lqerbƔur-k
- Afaylu yella yakan di Commons. Tebɣiḍ ad tedduḍ ar zdat?IhUhuAzwel
diff --git a/app/src/main/res/values-kjp/error.xml b/app/src/main/res/values-kjp/error.xml
new file mode 100644
index 000000000..b471b3246
--- /dev/null
+++ b/app/src/main/res/values-kjp/error.xml
@@ -0,0 +1,7 @@
+
+
+
+ ဆ်ုဂုဏ်လှ်။
+
diff --git a/app/src/main/res/values-km/strings.xml b/app/src/main/res/values-km/strings.xml
index ba7a57655..24e820563 100644
--- a/app/src/main/res/values-km/strings.xml
+++ b/app/src/main/res/values-km/strings.xml
@@ -41,7 +41,7 @@
អ្វីដែលខ្ញុំផ្ទុកឡើងចែកចាយមើលក្នុងឧបករណ៍រាយរក
- ចំណងជើង
+ ចំណងជើងសូមដាក់ចំណងជើងអោយឯកសារនេះការពិពណ៌នាមិនអាចកត់ឈ្មោះចូលបានទេ ព្រោះបណ្ដាញកំពុងមានបញ្ហា។
diff --git a/app/src/main/res/values-ko-rKP/strings.xml b/app/src/main/res/values-ko-rKP/strings.xml
index 68bad03b0..74a5c871f 100644
--- a/app/src/main/res/values-ko-rKP/strings.xml
+++ b/app/src/main/res/values-ko-rKP/strings.xml
@@ -39,7 +39,7 @@
내 올리적재공유열람기로 보기
- 제목
+ 제목설명가입할수 없습니다 - 망 오유입니다실패한 시도가 너무 많습니다. 몇분후에 다시 시도하세요.
@@ -56,7 +56,7 @@
장치에서 GPS가 금지되여있습니다. 허가하시겠습니까?GPS 허가아직 올리적재가 없습니다
-
+ \@string/contributions_subtitle_zero%1$d개 올리적재
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index c2ef5622a..fb913a662 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -58,7 +58,7 @@
내 올린 파일공유브라우저로 보기
- 제목
+ 제목 (필수)이 파일의 제목을 지정해 주십시오설명로그인할 수 없습니다 - 네트워크 오류입니다
@@ -81,7 +81,8 @@
아직 올린 항목이 없습니다\@string/contributions_subtitle_zero
- %1$d개 업로드
+ (%1$d)
+ (%1$d)%1$d장의 업로드를 시작합니다
@@ -176,7 +177,7 @@
근처의 장소근처에 장소가 없습니다경고
- 이 파일은 이미 공용에 존재합니다. 계속하시겠습니까?
+ 이 파일은 이미 공용에 존재합니다. 계속하시겠습니까?예아니오제목
@@ -238,8 +239,8 @@
그림 캐시 처리 오류이 파일을 설명할 수 있는 제목으로, 파일 이름으로 사용됩니다. 띄어쓰기를 포함한 일반적인 단어를 사용할 수 있습니다. 파일 확장자는 포함하지 마세요미디어에 대해 가능한 많이 설명하십시오: 어디서 촬영한 것인가? 무엇을 보여주는가? 무슨 문맥을 가지는가? 물건이나 사람에 대해 설명하십시오. 풍경에서 시간을 알려주는 것처럼 쉽게 추측할 수 없는 정보를 제공합니다. 미디어가 평범하지 않다면 무엇이 이를 평범하지 않게 만들었는지 설명하십시오.
- 사진이 너무 어둡습니다. 정말 업로드하겠습니까? 위키미디어 공용은 사전적인 가치가 있는 사진을 위한 공간입니다.
- 사진이 흐릿합니다. 정말 업로드하겠습니까? 위키미디어 공용은 사전적인 가치가 있는 사진을 위한 공간입니다.
+ 이 사진은 너무 어둡습니다. 정말 업로드하시겠습니까? 위키미디어 공용은 백과사전적인 가치가 있는 사진을 위한 공간입니다.
+ 이 사진은 흐릿합니다. 정말 업로드하시겠습니까? 위키미디어 공용은 백과사전적인 가치가 있는 사진을 위한 공간입니다.권한 부여외부 저장소 사용하기장치의 인앱 카메라로 찍은 사진 저장하기
@@ -332,8 +333,10 @@
그림 선택 중에 좌표가 지정되지 않았습니다주변 장소를 가져오는데 오류가 있습니다.+ 설명 추가
+ 최근 검색 없음검색 기록을 지우겠습니까?검색 기록 삭제됨
+ 삭제 신청성과통계알찬 그림
@@ -346,8 +349,26 @@
위키미디어 문서에 사용된, 공용에 업로드한 그림 수오류가 발생했습니다!공용 알림
+ 기여
+ 근처
+ 알림
+ 주변 알림 표시
+ 사진이 필요한 주변 장소를 보려면 여기를 탭하세요
+ 당신에게 가까운 주변 장소를 찾지 못했습니다
+ 목록기억 장치 권한이미지를 업로드하려면 외부 기억 장치에 접근할 권한이 필요합니다.
+ 더 이상 사진이 필요한 주변 장소를 보지 못하게 됩니다. 그러나 원할 경우 설정에서 이 알림을 다시 활성화할 수 있습니다.
+ 단계 %2$d 중 %1$d
+ 다음
+ 이전
+ 제출
+ %1$s 이름의 파일이 존재합니다. 계속하시겠습니까?
+ 장치에서 호환되는 지도 애플리케이션을 찾지 못했습니다. 이 기능을 사용하려면 지도 애플리케이션을 설치해 주십시오.
+
+ %1$d개 업로드
+ %1$d개 업로드
+ 북마크북마크사진
@@ -357,5 +378,28 @@
북마크를 추가하지 않았습니다북마크로그 수집이 시작되었습니다. 이 앱을 다시 시작하고 기록을 원하는 동작을 수행한 다음 \'로그 파일 보내기\'를 다시 탭해 주십시오
+ 실수로 업로드했습니다
+ 공개가 되는 줄 몰랐습니다
+ 제 프라이버시에 부적절하다는 것을 인식했습니다
+ 생각이 바뀌어서 더 이상 공개하고 싶지 않습니다
+ 죄송합니다. 이 사진은 백과사전의 관심 대상이 아닙니다
+ 문서공용에 오신 것을 환영합니다!\n\n상단의 카메라나 갤러리 아이콘을 터치하여 당신의 첫 미디어를 올리십시오.
+ 전 세계
+ 아메리카
+ 유럽
+ 중동
+ 아프리카
+ 아시아
+ 태평양
+ 선택된 분류 없음
+ 분류가 없는 그림은 거의 유용하지 않습니다. 분류를 선택하지 않고 제출하시겠습니까?
+ 예. 제출합니다
+ 아니오, 뒤로 돌아갑니다
+ 여기를 검색
+ 권한 요청
+ 사진이 필요한 주변 장소를 표시하기 위해 현재 위치를 사용하시겠습니까?
+ 위치 권한 없이 사진이 필요한 주변 장소를 표시할 수 없습니다
+ 다시는 묻지 않음
+ 위치 권한 표시
diff --git a/app/src/main/res/values-lb/strings.xml b/app/src/main/res/values-lb/strings.xml
index 22b823d38..a76415670 100644
--- a/app/src/main/res/values-lb/strings.xml
+++ b/app/src/main/res/values-lb/strings.xml
@@ -50,7 +50,7 @@
Meng eropgeluede FichierenDeelenAm Browser kucken
- Titel
+ Titel (Obligatoresch)BeschreiwungAloggen huet net funktionéiert - Feeler mam ReseauZe dacks ouni Succès probéiert. Probéiert w.e.g. an e puer Minutten nach eng Kéier.
@@ -67,7 +67,7 @@
GPS ass op Ärem Apparat ausgeschalt. Wëllt Dir en aktivéieren?GPS aktivéierenNach keng eropgeluede Fichieren
-
+ N@string/contributions_subtitle_zeroEe Fichier eropgelueden%1$d Fichieren eropgelueden
@@ -161,7 +161,6 @@
Plazen nobäiKeng Plazen nobäi fonntWarnung
- Dëse Fichier gëtt et schonn op Commons. Sidd Dir sécher datt Dir virufuere wëllt?JoNeenTitel
@@ -267,6 +266,7 @@
Richteg ÄntwertFalsch Äntwert+ Beschreiwung derbäisetzen
+ Nominéiere fir ze LäschenRealisatiounenSTATISTIKENMerci\'e kritt
@@ -276,6 +276,14 @@
Biller net zréckgesatFeeler opgetrueden!Notifikatioun vu Commons
+ Kontributiounen
+ Nobäi
+ Notifikatiounen
+ Lëscht
+ Schrëtt %1$d vu(n) %2$d
+ Weider
+ Vireg
+ SpäicherenLieszeechenLieszeechenBiller
@@ -283,4 +291,19 @@
LieszeechenDir hutt keng Lieszeechen derbäigesatLieszeechen
+ Ech hunn et iertemlech eropgelueden
+ Ech wousst net datt et ëffentlech visibel wier
+ Pardon, dëst Bild ass net interessant fir eng Enzyklopedie
+ Artikelen
+ Weltwäit
+ Amerika
+ Europa
+ Mëttleren Osten
+ Afrika
+ Asien
+ Pazifik
+ Keng Kategorien erausgesicht
+ Jo, schécken
+ Neen, zréck goen
+ Dëst ni méi froen
diff --git a/app/src/main/res/values-li/strings.xml b/app/src/main/res/values-li/strings.xml
index 5f7f48100..caee992d9 100644
--- a/app/src/main/res/values-li/strings.xml
+++ b/app/src/main/res/values-li/strings.xml
@@ -46,7 +46,7 @@
Mien uploadsDeilTuin in browser
- Titel
+ TitelGaef estebleef \'ne naam veur dit bestandjBesjrievingKan zich neet aanmelde - netwirkfout
@@ -65,7 +65,7 @@
GPS steit oet op die toestèl. Wils se \'t aanzètte?Zèt GPS aanNag gein uploads
-
+ \@string/contributions_subtitle_zero%1$d upload%1$d uploads
@@ -159,7 +159,6 @@
Plaatse in de buurtGein plaatse in de buurt gevónjeWaorsjoewing
- Dit bestandj besteit al op Commons. Wèts se zeker det se door wils gaon?JaoNaeTitel
diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml
index 34b7d7ce8..b5d50c432 100644
--- a/app/src/main/res/values-lt/strings.xml
+++ b/app/src/main/res/values-lt/strings.xml
@@ -49,7 +49,7 @@
Mano įkėlimaiDalintisAtidaryti naršyklėje
- Pavadinimas
+ PavadinimasPrašome pateikti šiam failui pavadinimąAprašymasNegalima prisijungti - tinklo klaida
@@ -69,7 +69,7 @@
GPS išjungta jūsų įrenginyje. Ar norite įjungti?Išjungti GPSNėra įkėlimų kol kas
-
+ \@string/contributions_subtitle_zero1 įkėlimas%1$d įkėlimai
@@ -139,7 +139,6 @@
GeraiNetoliese Esančios VietosĮspėjimas
- Šis failas jau egzistuoja Commons. Ar tikrai norite tęsti?TaipNePavadinimas
diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml
index d3887ef84..8b8a1cd3c 100644
--- a/app/src/main/res/values-lv/strings.xml
+++ b/app/src/main/res/values-lv/strings.xml
@@ -33,7 +33,7 @@
Manas augsupieladesDalītiesSkatīt pārlūkprogrammā
- Nosaukums
+ NosaukumsAprakstsAtvainojiet, šis lietotājs tika bloķēts uz CommonsPieteikšanās neizdevās
@@ -113,8 +113,16 @@
Sapratu!Jautājums+ Pievienot aprakstu
+ IesniegtGrāmatzīmesGrāmatzīmesGrāmatzīmesGrāmatzīmes
+ raksti
+ Amerika
+ Vidējie Austrumi
+ Āzija
+ Jā, iesniegt
+ Atļaujas pieprasījums
+ Nekad vairs šo nejautāt
diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml
index a0019b1fa..03420c909 100644
--- a/app/src/main/res/values-mk/strings.xml
+++ b/app/src/main/res/values-mk/strings.xml
@@ -1,6 +1,7 @@
Истражи
@@ -48,7 +49,7 @@
Мои подигањаСподелиПогледај во прелистувач
- Наслов
+ Наслов (задолж.)Ставете ѝ наслов на податотекатаОписНе можам да Ве најавам — мрежата не работи
@@ -71,8 +72,8 @@
Сè уште нема подигања\@string/contributions_subtitle_zero
- %1$d подигање
- %1$d подигања
+ (%1$d)
+ (%1$d)Започнувам %1$d подигање
@@ -168,7 +169,7 @@
Околни местаНе најдов околни местаПредупредување
- Податотекава веќе постои на Ризницата. Дали сигурно сакате да продолжите?
+ Податотекава веќе постои на Ризницата. Дали сигурно сакате да продолжите?ДаНеНаслов
@@ -230,8 +231,8 @@
Грешка при меѓускладирање на сликитеКраток и единствен наслов на податотеката, кој ќе служи како нејзин назив. Можете да користите прост јазик со меѓупростор, но не пишувајте ја податотечната наставкаОбјаснете ја податотеката што подобро можете: Каде е направена? Што е прикажано на неа? Кој е контекстот? Опишете ги предметите, објектите и личностите. Дајте сознанија што не можат лесно да се погодат, како на пр. време од денот ако се работи за природен предел. Ако на неа е претставено нешто необично, објаснете зошто прикажаното е необично.
- Сликата ви е претемна. Дали сигурно сакате да ја подигнете? Ризницата е посветена само на слики со енциклопедиска вредност.
- Сликата ви е матна. Дали сигурно сакате да ја подигнете? Ризницата е посветена само на слики со енциклопедиска вредност.
+ Сликата ви е претемна. Дали сигурно сакате да ја подигнете? Ризницата е посветена само на слики со енциклопедиска вредност.
+ Сликата ви е матна. Дали сигурно сакате да ја подигнете? Ризницата е посветена само на слики со енциклопедиска вредност.Дај дозволаКористи надворешен складЗачувување на направените слики во прилогот со камерата на вашиот уред
@@ -326,6 +327,7 @@
+ Додај описДали сте сигурни дека сакате да ја избришете историјата на пребарувања?Историјата на пребарување е избришана
+ Предложи за бришењеДостигнувањаСТАТИСТИКАПримени благодарници
@@ -342,8 +344,27 @@
Бројот на слики што сте ги подигнале на Ризницата кои се користат во статииСе појави грешка!Известување од Ризницата
+ Придонеси
+ Во близина
+ Известувања
+ Известувај ме за места во близина
+ Допрете тука за да го видите најблиското место без слика
+ Не најдов места во ваша близина
+ СписокДозвола за складирањеНи треба ваша дозвола за пристап до надворешниот склад на вашиот уред за да се подигнат сликите.
+ Повеќе нема да ви се прикажува најблиското место без слика. Доколку се премислите, таа поставка ќе ја најдете во Нагодувањата.
+ Чекор %1$d од %2$d
+ Слика %1$d во збирот
+ Следно
+ Претходно
+ Поднеси
+ Веќе постои податотека со име %1$s. Дали сигурно сакате да продолжите?
+ Не пронајдов складен картографски прилог на вашиот уред. Преземете еден таков за да можете да ја користите оваа можност.
+
+ %1$d подигање
+ %1$d подигања
+ ОбележаниОбележаниСлики
@@ -353,5 +374,25 @@
Немате додадено ниеден бележникОбележаниЗаведувањето од дневникот започна. ПРЕВКЛУЧЕТЕ го прилогот, извршете го дејството што сакате да се заведе, а потоа повторно допрете на „Испрати дневничка податотека“
+ Ја подигнав по грешка
+ Не знаев дека ќе биде јавно видлива
+ Сфатив дека ќе ми ја наруши приватноста
+ Се премислив. Не сакам повеќе да биде видлива
+ За жал, сликава не е соодветна за енциклопедија
+ Подигната од мене на
+ , се користи во
+ статииДобре дојдовте на Ризницата!\n\nПодигнете ја вашата прва слика или снимка допирајќи ја иконката за камера или галерија.
+ Цел свет
+ Америка
+ Европа
+ Близок Исток
+ Африка
+ Азија
+ Океанија
+ Нема избрано категории
+ Некатегоризираните слики се слабо употребливи. Дали сигурно сакате да поднесете без да ставите категории?
+ Да, поднеси
+ Не, врати се
+ (За сите слики во збирот)
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index dbb598dd6..c9685308e 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -46,7 +46,7 @@
എന്റെ അപ്ലോഡുകൾപങ്ക് വെയ്ക്കുകബ്രൗസറിൽ കാണുക
- തലക്കെട്ട്
+ തലക്കെട്ട്ഈ പ്രമാണത്തിന് ഒരു തലക്കെട്ട് നൽകുക.വിവരണംപ്രവേശിക്കാനായില്ല - നെറ്റ്വർക്ക് പരാജയപ്പെട്ടു
@@ -133,7 +133,6 @@
ശരിസമീപ സ്ഥലങ്ങൾമുന്നറിയിപ്പ്
- ഈ പ്രമാണം കോമൺസിൽ നിലവിലുണ്ട്. തുടരണം എന്ന് താങ്കൾക്കുറപ്പാണോ?അതെഅല്ലശീർഷകം
diff --git a/app/src/main/res/values-mnw/strings.xml b/app/src/main/res/values-mnw/strings.xml
index bd1977f4a..1729a161d 100644
--- a/app/src/main/res/values-mnw/strings.xml
+++ b/app/src/main/res/values-mnw/strings.xml
@@ -27,7 +27,7 @@
ကေတ်ရုပ်ဗဒဲါဒၞာဲဏအ်ပါ်ပရအ်
- က္ဍိုပ်လိက်
+ က္ဍိုပ်လိက်မဗမံက်ထ္ၜးလံက်အေန် လီုပတိုန်
diff --git a/app/src/main/res/values-mr/strings.xml b/app/src/main/res/values-mr/strings.xml
index 18c081d38..09638f707 100644
--- a/app/src/main/res/values-mr/strings.xml
+++ b/app/src/main/res/values-mr/strings.xml
@@ -50,7 +50,7 @@
माझी अपभारणेसहभाग करान्याहाळकात उघडा
- शीर्षक
+ शीर्षककृपया या फाईलसाठी शीर्षक प्रदान करावर्णनसनोंद प्रवेश अशक्य - नेटवर्क नाही
@@ -68,7 +68,7 @@
आपल्या मोबाईलचे गिपीएस बंद आहे, तुम्हांला ते चालू करायचे आहे का?जिपीएस चालू कराअद्याप काहीही चढवलेले नाही
-
+ अद्याप अपभारणे नाहीतएक अपभारण%1$d अपभारणे
@@ -164,7 +164,6 @@
जवळपासची स्थानेआसपास काहीही सापडले नाहीइशारा
- ही संचिका पूर्वीच कॉमन्सवर उपलब्ध आहे. आपणास पुढे जायचे याची निश्चिती करता काय?होयनाहीशीर्षक
@@ -220,8 +219,6 @@
चित्र दाखवताना त्रुटी आढळलीफ़ाईलला असे नाव द्या जे सुयोग्य असेल,चित्राविषयी त्यामधून माहिती कळेल अशी साधी भाषा वापरा,नावामध्ये फ़ाईलचे एक्सटेन्शन लिहू नका.माध्यमांची शक्य तितकी जास्त माहिती द्या:छायाचित्र/चलचित्र/ध्वनिमुद्रण कोठे घेतले आहे? त्यात काय दाखवले आहे? त्या माध्यमांचा संदर्भ काय? त्यातील वस्तू,व्यक्ति व इतर माहिती द्या? अशी सगळी माहिती जी त्या माध्यमाकडे पाहून लक्षात येणार नाही पण ती महत्वाचे आहे ती सर्व पुरवा. जर त्या माध्यमामध्ये काहीही वेगळे दिसत असेल तर ते वेगळे का आहे याची माहिती पुरवा.
- हे छायाचित्र खुप अंधारलेले आहे, तुम्ही खरच हे छायाचित्र येथे चढवू इच्छीता का? विकीमिडीया कॉमन्सवर नेहमी विश्वकोषात महत्त्वाची असलेलीच चित्रे चढवली जाऊ शकतात.
- हे छायाचित्र खुप फ़िकट आलेले आहे, तुम्ही खरच हे छायाचित्र येथे चढवू इच्छीता का? विकीमिडीया कॉमन्सवर नेहमी विश्वकोषात महत्त्वाची असलेलीच चित्रे चढवली जाऊ शकतात.परवानगी द्याबाहेरील स्टोरेज वापराआपल्या डिव्हाइसवरील इन-अॅप्स कॅमेर्यासह घेतलेली चित्रे जतन करा
diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml
index 2a5ef72da..c4bd86003 100644
--- a/app/src/main/res/values-my/strings.xml
+++ b/app/src/main/res/values-my/strings.xml
@@ -46,7 +46,7 @@
မိမိ တင်ထားသည်များမျှဝေဘရောက်ဆာတွင် ကြည့်ရန်
- ခေါင်းစဉ်
+ ခေါင်းစဉ်ခေါင်းစဉ်ဖော်ပြချက်လော့အင် မဝင်နိုင်ပါ - ကွန်ရက် အမှား
@@ -134,7 +134,6 @@
အနီးအနား နေရာများအနီးအနား နေရာများ မတွေ့ပါသတိပေးချက်
- ဤဖိုင်သည် ကွန်မွန်းစ်ပေါ်တွင် ရှိနှင့်ပြီးဖြစ်သည်။ ဆက်လုပ်ရန် သေချာပါသလား။မှန်မလုပ်ပါခေါင်းစဉ်
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index ba3d826b3..da7d9608f 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -55,7 +55,7 @@
Mine opplastingerDelVis i nettleser
- Tittel
+ TittelAngi en tittel for denne filaBeskrivelseInnlogging feilet - nettverksproblem
@@ -76,7 +76,7 @@
GPS er slått av på denne enheten. Ønsker du å slå den på?Slå på GPSIngen opplastinger ennå
-
+ \@string/contributions_subtitle_zero%1$d opplasting%1$d opplastinger
@@ -175,7 +175,6 @@
Plasser i nærhetenIngen steder i nærheten funnetAdvarsel
- Denne filen eksisterer allerede på Commons. Er du sikker på at du vil fortsette?JaNeiTittel
@@ -237,8 +236,6 @@
Feil under mellomlagring av bilderEn unik beskrivende tittel for fila, som vil fungere som filnavn. Du kan bruke vanlig språk med mellomrom. Ikke ta med filendelsenBeskriv 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.
- 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.
- Dette bildet er uklart, er du sikker på at du ønsker å laste det opp? Wikimedia Commons er bare for bilder med ensyklopedisk verdi.Gi tillatelseBruk ekstern lagringLagre bilder som er tatt med kameraet i appen på enheten din
diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml
index f7a9558cc..6cfe622b5 100644
--- a/app/src/main/res/values-ne/strings.xml
+++ b/app/src/main/res/values-ne/strings.xml
@@ -44,7 +44,7 @@
मेरा अपलोडहरूबाड्नेब्राउजरमा हेर्ने
- शीर्षक
+ शीर्षकवर्णनप्रवेश गर्न असमर्थ - जडान खराबीधेरै असफल प्रयासहरू भए । कृपया केही मिनेट पछि पुन: प्रयास गर्नुहोस
@@ -128,4 +128,13 @@
टगल दृश्यभित्तेपत्र चयन गर्नुहोस्भित्तेपत्र सफलतापूर्वक चयन भयो!
+ सूची
+ बुझाउनुहोस्
+ लेखहरू
+ अमेरिका
+ युरोप
+ अफ्रिका
+ एसिया
+ हो, बुझाउनुहोस्
+ यस क्षेत्रमा खोज्नुहोस्
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 0a0d101d7..71d9e188f 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -1,5 +1,6 @@
+ Verkennen
+ Verkennen
+ Uiterlijk
+ Algemeen
+ Terugkoppeling
+ LocatieCommons
+ •Instellingen
+ Naar Commons versturenGebruikersnaamWachtwoord
+ Aanmelden bij je Commons Beta-profielAanmelden
+ Wachtwoord vergeten?RegistrerenBezig met aanmeldenEen ogenblik geduld…Aanmelden geslaagdAanmelden misluktBestand niet gevonden. Probeer een ander bestand.
- Verificatie is mislukt
+ Verifiëring is mislukt. Meld je opnieuw aan.Uploaden is begonnen%1$s geüploadWijs aan om uw upload te bekijken
@@ -46,7 +57,7 @@
Mijn uploadsDelenIn browser bekijken
- Naam
+ NaamBeschrijvingAanmelden niet mogelijk. Er is een probleem met het netwerkU hebt te vaak geprobeerd aan te melden. Probeer het over een aantal minuten opnieuw.
@@ -61,7 +72,7 @@
VernieuwenLijstNog geen uploads
-
+ \@string/contributions_subtitle_zero%1$d upload%1$d uploads
@@ -125,6 +136,7 @@
- Natuurlijke objecten (bloemen, dieren, bergen)\n- Nuttige objecten (fietsen, treinstations)\n- Beroemde mensen (uw burgemeester, Olympische atleten u hebt ontmoet)Gelieve NIET te uploaden:- Selfies of foto\'s van uw vrienden\n- Foto\'s die u hebt gedownload van het Internet\n- Screenshots van eigen apps
+ Schermfoto\'s van oorspronkelijke toepassingenVoorbeeld van een upload:- Titel: Sydney Opera House\n- Beschrijving: het Sydney Opera House gezien vanaf de overkant van de baai\n- Categorieën: Sydney Opera House, Sydney Opera House from the west, Sydney Opera House remote viewsDraag uw afbeelding bij. Help pagina\'s in Wikipedia tot leven te laten komen!
@@ -134,7 +146,7 @@
Begrijpt u het?Ja!Categorieën
- Bezig met laden…
+ Laden...Geen selectieGeen beschrijvingOnbekende licentie
@@ -144,40 +156,85 @@
OKPlaatsen in de buurtWaarschuwing
- Dit bestand bestaat al op Commons. Weet u zeker dat u wilt doorgaan?JaNeeTitelTitel van het bestandBeschrijving
+ AuteurUploaddatum2FA-code
+ Afbeelding plaatsenGeen selfiesAnnulerenOpenenSluiten
+ StartUploadenIn de buurtOverInstellingenTerugkoppelingAfmelden
+ Zelfstudie
+ Meldingen
+ Aanbevolen
+ geen beschrijving gevondenWikipedia-artikelError tijdens het laden van de afbeeldingen
+ Aanmelden bij je profiel
+ Logboekbestand verzendenNomineer voor VerwijderingDeze afbeelding is genomineerd voor verwijdering.Bekijk in Browser
+ Overslaan
+ Aanmelden
+ Weet je zeker dat je het aanmelden wilt overslaan?
+ Je kunt dan geen afbeeldingen plaatsen.
+ Meld je aan om deze functie te gebruikenVERWIJZINGENWIKIDATA
- Vaak gestelde vragen
+ WIKIPEDIA
+ COMMONS
+ <u>Waardeer ons</u>
+ <u>Vraag en antwoord</u>
+ Zelfstudie overslaanGeen internetInternet beschikbaarFout bij ophalen berichten.Geen berichten.
+ <u>Vertalen</u>TalenSelecteer de taal waarvoor u vertalingen wil indienenGa doorAnnuleren
+ Opnieuw proberen
+ Begrepen!
+ Zoeken
+ Commons doorzoeken
+ Vragenspel
+ Kan je afbeelding worden geplaatst?
+ Vraag
+ Uitslag
+ Doorgaan
+ Toepassing delen
+ + Beschrijving toevoegenFout opgetreden!
+ Bijdragen
+ Dichtbij
+ Meldingen
+ Meldingen dichtbij weergeven
+ LijstToestemming om op te slaan
+ Stap %1$d van %2$d
+ Volgende
+ Vorige
+ Verzenden
+ Wereldwijd
+ Amerika
+ Europa
+ Machtigingsverzoek
+ Niet meer vragen
+ Machtiging voor locatie weergeven
+ Naar machtiging voor locatie vragen als dat nodig is voor de functie meldingskaart dichtbij weergeven.
diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml
index e70e06816..8acf76a47 100644
--- a/app/src/main/res/values-oc/strings.xml
+++ b/app/src/main/res/values-oc/strings.xml
@@ -42,7 +42,7 @@
Mos telecargamentsPartejarAfichar dins lo navigador
- Títol
+ TítolDescripcionImpossible de se connectar — pana de retTròp de temptativas infructuosas. Ensajatz tornarmai dins qualques minutas.
diff --git a/app/src/main/res/values-pa/strings.xml b/app/src/main/res/values-pa/strings.xml
index 146576998..3b3824862 100644
--- a/app/src/main/res/values-pa/strings.xml
+++ b/app/src/main/res/values-pa/strings.xml
@@ -40,7 +40,7 @@
ਮੇਰੇ ਅੱਪਲੋਡਸਾਂਝਾ ਕਰੋਬਰਾਊਜ਼ਰ ਵਿਚ ਵੇਖੋ
- ਸਿਰਲੇਖ
+ ਸਿਰਲੇਖਵੇਰਵਾਦਾਖ਼ਲਾ ਨਹੀਂ ਹੋ ਰਿਹਾ - ਨੈੱਟਵਰਕ ਫੇਲ੍ਹ ਹੋਇਆ ਹੈਬਹੁਤ ਸਾਰੀਆਂ ਅਸਫ਼ਲ ਕੋਸ਼ਿਸ਼ਾਂ। ਥੋੜ੍ਹੀ ਦੇਰ ਬਾਅਦ ਕੋਸ਼ਿਸ਼ ਕਰੋ ਜੀ।
@@ -56,7 +56,7 @@
ਤੁਹਾਡੇ ਉਪਕਰਣ ਦਾ ਜੀਪੀਐੱਸ ਬੰਦ ਹੈ। ਇਸਨੂੰ ਚਲਾਉਣਾ ਚਾਹੋਂਗੇ?ਜੀਪੀਐੱਸ ਚਾਲੂ ਕਰੋਫ਼ਿਲਹਾਲ ਕੋਈ ਅੱਪਲੋਡ ਨਹੀਂ
-
+ \@string/contributions_subtitle_zero%1$d upload%1$d ਅੱਪਲੋਡ
@@ -140,7 +140,6 @@
ਨਜ਼ਦੀਕੀ ਥਾਵਾਂਕੋਈ ਨਜ਼ਦੀਕੀ ਥਾਵਾਂ ਨਹੀਂ ਮਿਲੀਆਂਖ਼ਬਰਦਾਰ
- ਇਹ ਤਸਵੀਰ ਕਾਮਨਜ਼ \'ਤੇ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। ਕੀ ਤੁਸੀਂ ਫਿਰ ਵੀ ਚਾਹੋਂਗੇ?ਹਾਂਨਹੀਂਸਿਰਲੇਖ
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 7b8feceac..baa82bbb7 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -2,6 +2,7 @@
+ Explorare
+ ExplorareAspectGeneral
+ FeedbackLocațieCommons•Setări
+ Încarcă la CommonsNume de utilizatorParolă
+ Intrați în contul dumneavoastră Commons BetaAutentificareV-aţi uitat parola?Înregistrare
@@ -47,7 +52,7 @@
Încărcările melePartajareAfișează în navigator
- Titlu
+ TitluDescriereAutentificare nereușită – defecțiune de rețeaPrea multe încercări nereușite. Încercați din nou peste câteva minute.
@@ -65,7 +70,7 @@
GPS-ul este dezactivat pe device-ul dumneavoastră. Doriți să-l activați?Activează GPSNiciun fișier încă!
-
+ \@string/contributions_subtitle_zero%1$d încărcare%1$d încărcări
@@ -86,11 +91,13 @@
CategoriiSetăriÎnregistrare
+ Imagini recomandateCategorieDespreAplicația Wikimedia Commons este un software cu sursă deschisă creat și menținut de bursieri și voluntari ai comunității Wikimedia. Fundația Wikimedia nu este implicată în crearea, dezvoltarea sau mentenanța aplicației.Creați un nou <a href=\"https://github.com/commons-app/apps-android-commons/issues\">tichet pe GitHub</a> pentru a raporta buguri sau sugestii.
- <a href=\"https://github.com/commons-app/apps-android-commons/wiki/Privacy-policy\">Politica de confidențialitate</a>
+ <u>Politica de confidențialitate</u>
+ <u>Autori</u>DespreTrimitere reacții (prin e-mail)Niciun client de email instalat
@@ -101,7 +108,8 @@
RevocareAceastă imagine va fi licențiată sub %1$sDescarcă
- Licență
+ Licență implicită
+ Folosiți titlul/descrierea anterioarăObține în mod automat locația curentăMod de noapteFolosește o temă întunecată
@@ -151,9 +159,16 @@
Titlul fișieruluiDescriereDescrierea fișierului vine aici. Aceasta poate fi destul de lungă și va trebuie distribuită pe mai multe linii. Sperăm totuși că arată bine.
+ Autor
+ Data încărcării
+ Licență
+ Coordonate
+ NefurnizatDeveniți beta-testerAbonați-vă la canalul nostru beta pe Google Play și a obține acces rapid la noi caracteristici și corecții de eroriCode 2FA
+ Limită maximă
+ Nu pot afișa mai mult de 500Logoul CommonsSite-ul CommonsPagina de Facebook a Commons
@@ -180,4 +195,36 @@
TutorialNotificăriElement Wikidata
+ Vizualizează cu navigatorul
+ Omite
+ Autentificare
+ <u>Dă-ne o notă</u>
+ <u>FAQ</u>
+ Sari peste tutorial
+ Nu aveți internet
+ Aveți internet
+ <u>Tranduceți</u>
+ Limbi
+ Încărcată de: %1$s
+ Imaginea zilei
+ Imaginea zilei
+ Căutare
+ Căutare pe Commons
+ Căutare
+ Căutări recente:
+ Quiz
+ Întrebare
+ Rezultat
+ Continuați
+ Răspuns corect
+ Răspuns greșit
+ +Adaugă descriere
+ Semne de carte
+ Semne de carte
+ Imagini
+ Locuri
+ Adaugă/scoate din semnele de carte
+ Semne de carte
+ Nu ați adăugat niciun semn de carte
+ Semne de carte
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 26e0285ba..040f269da 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -63,7 +63,7 @@
Мои загрузкиПоделитьсяОткрыть в браузере
- Название
+ Название (обязательно)Пожалуйста, укажите название этого файлаОписаниеНе удаётся войти — сбой сети
@@ -86,9 +86,9 @@
Загрузок пока нет\@string/contributions_subtitle_zero
- %1$d загрузка
- %1$d загрузки
- %1$d загрузок
+ (%1$d)
+ (%1$d)
+ (%1$d)Начинается %1$d загрузка
@@ -186,7 +186,7 @@
Места поблизостиМеста поблизости не найденыВнимание
- Этот файл уже существует на Викискладе. Вы уверены, что хотите продолжить?
+ Этот файл уже существует на Викискладе. Вы уверены, что хотите продолжить?ДаНетНазвание
@@ -248,8 +248,8 @@
Ошибка при кэшировании картинокУникальное описание, которое будет сохранено как имя файла. Вы можете использовать естественный язык, разделяя слова пробелами. Пожалуйста, не указывайте расширение файла.Пожалуйста, подробно опишите загружаемый файл: где он был снят? что на нём изображено? каков его контекст? Пожалуйста опишите изображённых персон или объекты. Добавьте информацию, о которой нельзя легко догадаться, например, время суток, когда снимался файл. Если снято что-то необычное, постарайтесь пояснить, что именно в этом необычного.
- Это изображение слишком тёмное. Вы уверены, что хотите его загрузить? Викисклад подходит только для фотографий, имеющих энциклопедическую ценность.
- Это изображение размыто. Вы уверены, что хотите его загрузить? Викисклад подходит только для фотографий, имеющих энциклопедическую ценность.
+ Это изображение слишком тёмное. Вы уверены, что хотите его загрузить? Викисклад подходит только для фотографий, имеющих энциклопедическую ценность.
+ Это изображение размыто. Вы уверены, что хотите его загрузить? Викисклад подходит только для фотографий, имеющих энциклопедическую ценность.РазрешитьИспользовать внешнее хранилищеСохранять изображения, сделанные с помощью встроенной камеры на устройстве
@@ -344,6 +344,7 @@
+ Добавление описанияВы уверены, что хотите очистить историю поисковых запросов?История поиска очищена
+ Номинировать к удалениюДостиженияСТАТИСТИКАПолучены благодарности
@@ -360,8 +361,28 @@
Число изображений, загруженных на Викисклад, которые используются в статьях ВикимедиаПроизошла ошибка!Уведомления Викисклада
+ Вклад
+ Поблизости
+ Уведомления
+ Уведомлять меня о местах поблизости
+ Нажмите здесь, чтобы увидеть ближайшее место без изображений
+ Не найдено мест поблизости
+ СписокРазрешение для хранилищаНам требуется разрешение доступа к внешнему хранилищу вашего устройства для того, чтобы загружать изображения.
+ Вы больше не сможете увидеть ближайшее место без изображений. Если вы передумаете, вы найдете этот параметр в настройках.
+ Шаг %1$d из %2$d
+ Изображение %1$d в наборе
+ Далее
+ Назад
+ Отправить
+ Уже существует файл с именем %1$s. Вы уверены, что хотите продолжить?
+ Не найдено совместимое картографическое приложение на вашем устройстве. Установите его, чтобы вы могли использовать эту возможность.
+
+ %1$d загрузка
+ %1$d загрузки
+ %1$d загрузок
+ ЗакладкиЗакладкиИзображения
@@ -371,5 +392,25 @@
Вы не добавили ни одной закладкиЗакладкиНачался процесс сбора журналов. ПЕРЕЗАПУСТИТЕ приложение, выполните действие, которое вы хотите запротоколировать, затем снова нажмите «Выслать лог-файл»
+ Загружено по ошибке
+ Я не знаю, что это станет доступным публично
+ Я понял, что это разглашает мою приватность
+ Я передумал. Больше не хочу чтобы было доступным публично
+ Извините, это изображение не для энциклопедии
+ Загружено мною на
+ ,использовано в
+ статьиДобро пожаловать на Викисклад!\n\nЗагрузите ваш первый файл, нажав на значок камеры или галереи.
+ Всемирные
+ Америка
+ Европа
+ Ближний Восток
+ Африка
+ Азия
+ Океания
+ Не выбраны категории
+ Некатегоризованные изображения редко используются. Вы уверены, что хотите это сделать без выбора категорий?
+ Да, отправить
+ Нет, вернуться
+ (Для всех изображений в наборе)
diff --git a/app/src/main/res/values-sd/strings.xml b/app/src/main/res/values-sd/strings.xml
index 5660a7c89..134c57ec5 100644
--- a/app/src/main/res/values-sd/strings.xml
+++ b/app/src/main/res/values-sd/strings.xml
@@ -50,7 +50,7 @@
منھنجا چاڙھونڊيوجھانگوءَ ۾ ڏسو
- عنوان
+ عنوانهن فائيل لاءِ ڪا سُرخي ڏيوتشريحناقابلِ داخل ٿيڻ - باھمڄار ناڪامي
@@ -71,7 +71,7 @@
اوهان جي ڊوائيس ۾ جي پي ايس بند آهي. ڇا اوهان ان کي کولڻ چاهيو ٿا؟جي پي ايس چالو ڪيو (اين ايبل جي پي ايس)اڃان تائين ڪو به ڄاڙهه (اَپلوڊ) نه ٿيو آهي
-
+ \@string/contributions_subtitle_zero%1$d چاڙھ%1$d چاڙھَ
@@ -161,7 +161,6 @@
ويجھڙائيءَ ۾ جڳھونآپاس وارو جڳهه نه لڌوچتاءُ
- فائل اڳ ئي العام ۾ موجود آھي. ڇا توھان کي پڪ آھي تہ توھان اڳتي وڌڻ ٿا چاھيو؟هانہعنوان
diff --git a/app/src/main/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml
index 3b2fde0fb..403f55714 100644
--- a/app/src/main/res/values-si/strings.xml
+++ b/app/src/main/res/values-si/strings.xml
@@ -41,7 +41,7 @@
මගේ උඩුගතකිරීම්හුවමාරු කරන්නගවේෂකයෙහි විවෘත කරන්න
- මාතෘකාව
+ මාතෘකාවවිස්තරයපිවිසීමට නොහැකිය-ජාලය ඇනහිටීමක්බොහෝ අසාර්ථක උත්සාහයන් කර ඇත. කරුණාකර මිනිත්තු කිහිපයකට පසුව උත්සාහ කරන්න
@@ -131,7 +131,6 @@
අවට ස්ථානළඟපාත තැන් කිසිවක් සොයා ගැනීමට නොහැකි වියඅනතුරු හැඟවීමයි
- මෙම ගොනුව දැනටමත් කොමන්ස් හි ඇත. ඔබට ඉදිරියට යෑම ගැන විශ්වාසද?ඔව්නැතමාතෘකාව
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 2b7190fa7..a4c7acb65 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -47,7 +47,7 @@
Moje obrázkyZdieľaťOtvoriť v prehliadači
- Názov
+ NázovProsím, dajte tomuto súboru názovOpisprihlásenie zlyhalo - zlyhanie siete
@@ -139,7 +139,6 @@
Miesta v okolíV okolí sa nenašli žiadne miestaUpozornenie
- Tento súbor už na Commons existuje. Ste si istí, že chcete pokračovať?ÁnoNieNázov
diff --git a/app/src/main/res/values-skr/strings.xml b/app/src/main/res/values-skr/strings.xml
index 70b31bc7c..1c9c95fea 100644
--- a/app/src/main/res/values-skr/strings.xml
+++ b/app/src/main/res/values-skr/strings.xml
@@ -41,7 +41,7 @@
میݙے اپ لوڈشیئربراؤزر وچ ݙیکھو
- عنوان
+ عنوانتفصیللاگ ان ناکاماپلوڈ
diff --git a/app/src/main/res/values-sr/error.xml b/app/src/main/res/values-sr/error.xml
index e5a8718ca..a68c4efb2 100644
--- a/app/src/main/res/values-sr/error.xml
+++ b/app/src/main/res/values-sr/error.xml
@@ -7,6 +7,6 @@
Остава је отказалаУпс! Нешто није у реду.
- Реците нам шта сте радили па то сазнање поделите са нама, путем имејла. Тиме ћете нам помоћи да решимо проблем.
+ Реците нам шта сте радили, па то сазнање поделите са нама путем е-поште. Тиме ћете нам помоћи да решимо проблем.Хвала вам!
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index 6e3c5811f..69f4b2bca 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -45,7 +45,7 @@
%1$d датотека се отпрема%1$d датотеке се отпремају
- Моја недавна отпремања
+ Ваша недавна отпремањаНа чекањуНије успело%1$d%% отпремљено
@@ -56,11 +56,11 @@
Моја отпремањаДелиПрикажи у прегледачу
- Наслов
+ Наслов (обавезно)Пружите наслов за ову датотекуОписПријава није могућа — грешка на мрежи
- Пријава није могућа — проверите своје корисничко име и лозинку
+ Пријава није могућа — проверите корисничко име и лозинкуПревише неуспешних покушаја. Покушајте поново за неколико минута.Овај корисник је блокиран на ОставиМорате да наведете свој двофакторски кôд за потврду идентитета.
@@ -103,8 +103,8 @@
<u>Политика приватности</u><u>Заслуге</u>О апликацији
- Пошаљите повратне информације (путем имејла)
- Није инсталиран имејл-клијент
+ Пошаљите повратне информације (путем е-поште)
+ Није инсталиран клијент за е-поштуНедавно коришћене категоријеЧека се прва синхронизација…Још увек нисте отпремили ниједну фотографију.
@@ -118,7 +118,7 @@
Аутоматски добави тренутну локацијуПрима тренутну локацију ако слика није геотагована и геотагује исту њоме. Упозорење: Овиме ће да се открије Ваша тренутна локација.Ноћни режим
- Користити тамну тему
+ Коришћење тамне темеАуторство-Делити под истим условима 4.0Ауторство 4.0Ауторство-Делити под истим условима 3.0
@@ -139,22 +139,22 @@
CC BY-SA 4.0CC BY 4.0CC Нула
- Викимедијина Остава садржи већину слика која се користи на Википедији.
+ Викимедијина остава садржи већину слика које се користе на Википедији.Ваше слике помажу у образовању људи широм света.
- Поставите слике које сте преузели или креирали у потпуности сами:
+ Отпремајте слике које сте снимили или направили у потпуности сами:Природне објекте (цвеће, животиње, планине)\n• Корисне објекте (бицикле, железничке станице)\n• Познате људе (ваш градоначелник, олимпијци које сте срели)
- Природни објекти (цвеће, животиње, планине)
- Корисни објекти (бицикли, железничке станице)
- Познати људи (ваш градоначелник, олимпијци које сте срели)
+ природне објекте (цвеће, животиње, планине);
+ корисне објекте (бицикле, железничке станице);
+ познате људе (ваш градоначелник, олимпијци које сте срели).НЕ отпремајте:
- - Селфије и слике Ваших пријатеља\n- Слике које Сте преузели са интернета\n- Скриншотове из сопствених апликација
- Селфији или слике ваших пријатеља
- Слике које сте преузели са интернета
- Снимци екрана са приказаним садржајем власничких апликација
+ — селфије и слике ваших пријатеља\n— слике које сте преузели са интернета\n— снимке екрана неслободних апликација
+ селфије или слике ваших пријатеља;
+ слике које сте преузели са интернета;
+ снимке екрана власничких апликација.Пример отпремања:— Наслов: Сиднејска опера\n— Опис: Сиднејска опера, поглед преко залива\n— Категорије: Сиднејска опера са запада, погледи на Сиднејксу оперу из даљинеНаслов: Сиднејска опера
- Опис: Сиднејска опера, поглед преко залива
+ Опис: Сиднејска опера гледана преко заливаКатегорије: Sydney Opera House from the west, Sydney Opera House remote viewsДелите ваше слике. Оживите чланке на Википедији.Слике на Википедији долазе из Оставе.
@@ -176,7 +176,7 @@
Места у близиниНису пронађена оближња местаУпозорење
- Ова датотека је већ доступна на Остави. Да ли сте сигурни да желите да наставите?
+ Ова датотека већ постоји на Остави. Заиста желите да наставите?ДаНеНаслов
@@ -189,13 +189,13 @@
ЛиценцаКоординатеНишта није унето
- Постани бета тестер!
- Прикључите се на наш бета канал на Гугл плеју и приступите новим информацијама и исправкама багова
+ Постаните бета-тестер
+ Прикључите се нашем каналу бета верзија на Google Play-у и раније приступајте новим функцијама и исправкама грешака2FA кодМој лимит за скорашња отпремањаМаксимални лимитНије могуће приказати више од 500
- Постави лимит за скорашња отпремања
+ Постави ограничење за недавна отпремањаДвофакторска аутентификација тренутно није подржана.Заиста желите да се одјавите?Лого Оставе
@@ -227,7 +227,7 @@
ПодешавањаПовратне информацијеОдјави ме
- Туторијал
+ УпутствоОбавештењаИзабранаОближња места не могу да се приказују без дозволе за локацију
@@ -238,14 +238,14 @@
Грешка при кеширању сликаЈединствен описни наслов за датотеку, који ће бити име датотеке. Можете да користите обични језик са размацима. Не треба уносити екстензију датотекеМолимо да опишете датотеку колико је то могуће: Где је направљена? Шта приказује? Шта је контекст? Опишите објекте и/или особе. Откријте информације које се не могу лако погодити, на пример доба дана ако је у питању пејзаж. Ако датотека приказује нешто необично, молимо да објасните шта је то чини необичном.
- Ова слика је претамна; да ли сте сигурни да је желите отпремити? Викимедијина остава је само за слике са енциклопедијском вредношћу.
- Ова слика је мутна; да ли сте сигурни да је желите отпремити? Викимедијина остава је само за слике са енциклопедијском вредношћу.
+ Ова слика је претамна; заиста желите да је отпремите? Викимедијина остава је само за слике са енциклопедијском вредношћу.
+ Ова слика је мутна; заиста желите да је отпремите? Викимедијина остава је само за слике са енциклопедијском вредношћу.Давање дозволе
- Употреба спољашње меморије
- Спремање слика направљених камером апликације на Вашем уређају
- Пријавите се на свој налог
- Пошаљи дневничку датотеку
- Пошаљите датотеку са евиденцијом програмерима путем имејла како бисте помогли у решавању проблема са апликацијом. Напомена: евиденције могу потенцијално садржавати идентификационе информације
+ Користи спољашње складиште
+ Чување слика снимљених камером у апликацији на вашем уређају
+ Пријава на налог
+ Пошаљи датотеку евиденције
+ Пошаљите датотеку евиденције програмерима путем е-поште да бисте помогли у решавању проблема са апликацијом. Напомена: евиденције могу потенцијално садржавати идентификационе информацијеНије пронађен веб-претраживач за отварање URL-аГрешка! URL није пронађенНоминовање за брисање
@@ -275,7 +275,7 @@
ОСТАВА<u>Оцените нас</u><u>ЧПП</u>
- Прескочи туторијал
+ Прескочи упутствоИнтернет није доступанИнтернет је доступанГрешка при добављању обавештења
@@ -328,6 +328,7 @@
+ Додај описДа ли сте сигурни да желите да очистите своју историју претраге?Историја претраге је избрисана
+ Номиновање за брисањеДостигнућаСТАТИСТИКЕПримљене захвале
@@ -344,8 +345,27 @@
Број слика које сте отпремили на Оставу а користе се у чланцима на ВикимедијиДошло је до грешке.Обавештења Оставе
+ Доприноси
+ У близини
+ Обавештења
+ Прикажи обавештење у близини
+ Притисните овде да бисте видели најближе место којем треба слика
+ Нису пронађена места у близини близу вас
+ СписакДозвола за складиштењеПотребна нам је ваша дозвола да бисмо приступили спољашњем складишту вашег уређаја како бисмо отпремали слике.
+ Више нећете видети најближе место којем требају слике. Међутим, ако желите, можете поново да омогућите ово обавештење у Подешавањима.
+ Корак %1$d од %2$d
+ Слика %1$d у скупу
+ Следеће
+ Претходно
+ Пошаљи
+ Већ постоји датотека са именом %1$s. Заиста желите да наставите?
+ Није могуће пронаћи апликацију компатибилне мапе на вашем уређају. Инсталирајте апликацију мапе да бисте користили ову функцију.
+
+ %1$d отпремање
+ %1$d отпремања
+ ОбележивачиОбележивачиСлике
@@ -354,5 +374,32 @@
ОбележивачиНисте додали ниједан обележивачОбележивачи
+ Грешком сам је отпремио/ла
+ Нисам знао/ла да ће бити јавно видљива
+ Схватио/ла сам да је лоша за моју приватност
+ Променио/ла сам мишљење, не желим да више јавно буду видљиве
+ Ова слика није занимљива за енциклопедију
+ Отпремио/ла сам на
+ , користи се у
+ чланциДобро дошли на Оставу!\n\nОтпремите прве медије додиром горенаведене иконице камере или галерије.
+ Светски
+ Америка
+ Европа
+ Средњи исток
+ Африка
+ Азија
+ Пацифик
+ Категорије нису изабране
+ Слике без категорија ретко су употребљиве. Заиста желите да пошаљете без избора категорија?
+ Да, пошаљи
+ Не, врати се
+ (За све слике у скупу)
+ Претражите ову област
+ Захтев за дозволу
+ Желите ли да користимо вашу тренутну локацију да би приказали најближе место којем требају слике?
+ Није могуће приказати најближе место којем требају слике без дозволе за локацију.
+ Не питај ово поново
+ Дозвола за приказ локације
+ Тражи дозволу за локацију када је то потребно за функцију приказа картице обавештења у близини.
diff --git a/app/src/main/res/values-su/strings.xml b/app/src/main/res/values-su/strings.xml
index 9d7720a4f..097ad20d3 100644
--- a/app/src/main/res/values-su/strings.xml
+++ b/app/src/main/res/values-su/strings.xml
@@ -50,7 +50,7 @@
Unjalan kamiBagikeunTęmbong dina panyungsi
- Judul
+ JudulBéré judul koropaknaPedaranTeu bisa login - gangguan jaringan
@@ -71,7 +71,7 @@
GPS dipareuman na parangkat anjeun. Rék dihurungkeun waé atuh?Hirupan GPSCan aya nu diunjal
-
+ \@string/contributions_subtitle_zero%1$d unjalan%1$d unjalan
@@ -169,7 +169,6 @@
Tempat SabudeureunTeu kapanggih tempat sabudeureunMangkahadé
- Ieu berkas geus aya di Commons. Rék diteruskeun baé ieu téh?NyaHenteuJudul
@@ -230,8 +229,6 @@
Kasalahan nalika muat gambarJudul déskriptif anu unik pikeun berkas, anu bakal miboga fungsi minangka ngaran berkas. Anjeun bisa maké basa basajan kalawan spasi. Ulah ngawuwuhkeun éksténsi berkasPék émbarkeun wincikan média saloba-lobabana: Dimana éta dicokot? Naon nu titojokeunna? Naon kontéksna? Pék jéntrékeun obyék atawa jalmana. Ébré informasi anu teu gampang kajudi, kawas wayah mun éta mangrupa pamandangan. Ari média nu némbongkeun perkara nu teu guyub, pék jéntrékeun naon nu ngabalukarkeun éta téh teu guyub.
- Ieu gambar poék teuing, rék diunggah waé? Wikimedia Commons téh ukur pikeun gambar anu boga ajén énsiklopédik.
- Potona teu cékas, rék diunggah waé? Wikimedia Commons mah ukur pikeun gambar anu boga ajén énsiklopédik.Béré idinPaké panyimpenan éksternalSimpen gambar nu nyomotna ku aplikasi kaména na parangkat anjeun
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index c60cf229b..d59026e8d 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -54,7 +54,7 @@
Mina uppladdningarDelaVisa i webbläsaren
- Titel
+ Titel (nödvändigt)Var god ange en titel för denna filBeskrivningDet gick inte att logga in - nätverksfel
@@ -77,8 +77,8 @@
Inga uppladdningar ännu\@string/contributions_subtitle_zero
- %1$d uppladdning
- %1$d uppladdningar
+ (%1$d)
+ (%1$d)Startar %1$d uppladdning
@@ -174,7 +174,7 @@
Platser i närhetenInga platser i närheten hittadesVarning
- Denna fil finns redan på Commons. Är du säker på att du vill fortsätta?
+ Denna fil finns redan på Commons. Är du säker på att du vill fortsätta?JaNejTitel
@@ -236,8 +236,8 @@
Fel uppstod när bilder cachelagrasEn 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ändelsenBeskriv 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.
- 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.
- 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.
+ 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.
+ 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.Ge behörighetAnvänd extern lagringSpara bilder som tas med kameran i appen på din enhet
@@ -332,6 +332,7 @@
+ Lägg till beskrivningÄr du säker på att du vill rensa din sökhistorik?Sökhistoriken raderades
+ Nominera för raderingPrestationerSTATISTIKMottagna tack
@@ -348,8 +349,27 @@
Antalet bilder du har laddat upp till Commons som användes i Wikimedia-artiklarEtt fel uppstod!Commons-aviseringar
+ Bidrag
+ I närheten
+ Aviseringar
+ Visa avisering för i närheten
+ Tryck här för att se den närmaste platsen som behöver bilder
+ Inga platser i närheten hittades som är nära dig
+ ListaLagringsbehörighetVi behöver ditt tillstånd för att komma åt externa lagringen för din enhet för att ladda upp bilder.
+ Du kommer inte längre se den närmaste platsen som behöver bilder. Om du vill kan du återaktivera denna avisering i inställningarna.
+ Steg %1$d av %2$d
+ Bild %1$d i uppsättningen
+ Nästa
+ Föregående
+ Skicka
+ En fil med filnamnet %1$s finns. Är du säker på att du vill fortsätta?
+ Ingen kompatibel kartapp hittades på din enhet. Installera en kartapp för att använda denna funktion.
+
+ %1$d uppladdning
+ %1$d uppladdningar
+ BokmärkenBokmärkenBilder
@@ -359,5 +379,32 @@
Du har inte lagt till några bokmärkenBokmärkenLogginsamling startades. STARTA OM appen, gör det du vill logga och tryck sedan på \"Skicka loggfil\" igen
+ Jag laddade upp den av misstag
+ Jag visste inte att den skulle visas offentligt
+ Jag insåg att den är dålig för mitt privatliv
+ Jag ändrade mig, jag vill inte längre att den ska vara synlig offentligt
+ Tyvärr, denna bild är inte intressant för en encyklopedi
+ Laddades upp av mig den
+ , används i
+ artiklarVälkommen till Commons!\n\nLadda upp din första mediafil genom att trycka på kameran eller galleriikonen ovan.
+ Världsomfattande
+ Amerika
+ Europa
+ Mellanöstern
+ Afrika
+ Asien
+ Stilla havet
+ Inga kategorier har valts
+ Bilder utan kategorier används sällan. Är du säker på att du vill skicka in den utan att välja kategorier?
+ Ja, skicka in
+ Nej, gå tillbaka
+ (För alla bilder i uppsättningen)
+ Sök i detta område
+ Begäran om behörighet
+ Vill du att vi ska använda din nuvarande plats för att visa den närmaste platsen som behöver bilder?
+ Kunde inte visa den närmaste platsen som behöver bilder utan platsbehörigheter
+ Fråga inte detta igen
+ Visa platsbehörighet
+ Fråga efter platsbehörighet vid behov för att visa aviseringskortet för i närheten.
diff --git a/app/src/main/res/values-tcy/strings.xml b/app/src/main/res/values-tcy/strings.xml
index 164d1da35..dbb1b3532 100644
--- a/app/src/main/res/values-tcy/strings.xml
+++ b/app/src/main/res/values-tcy/strings.xml
@@ -51,7 +51,7 @@
ಎನ್ನ ದಿಂಜಯೀನಾ ವಿಚಾರೊಲುಪಟ್ಟುಲೆಬ್ರೌಸರ್ಡ್ ತೂಲೆ
- ತರೆಬರವು
+ ತರೆಬರವುದಯ ಮಾಲ್ತ್ ಈ ಫೈಲ್ಗ್ ಶೀರ್ಷಿಕೆನ್ ಒದಗಾಲೆ.ವಿವರಣೆಲಾಗಿನ್ ಅತುಜಿ - ನೆಟ್ವರ್ಕ್ ತಿಕೊಂತಿಜ್ಜಿ
@@ -72,7 +72,7 @@
ಇರೇನಾ ಈ ಮೊಬೈಲ್ ಡ್ ಜಿಪಿಸ್ ವಜಾ ಅತುಂಡು. ಆಯಿನ್ ಬೇಲೆಜಿಪಿಎಸ್ ಸಕ್ರಿಯ ಮಾಲ್ಪುಲೆ.ಇಂದೆಟ್ ಒವೆ ಅಪ್ಲೋಡ್ ಇಜ್ಜಿ.
-
+ \@string/contributions_subtitle_zero%1$d upload%1$d uploads
@@ -171,7 +171,6 @@
ಕೈದಲ್ತಾ ಜಾಗೆಲುಮುಟ್ಟ ಇಪ್ಪುನ ಜಾಗೆ ತೋಜಾತ್ ಬರ್ಪುಜ್ಜಿ.ಎಚ್ಚರಿಕೆ
- ಕಾಮನ್ಸ್ಡ್ತ್ ಇಂಚಿಗ್ ಈ ಫೈಲ್ ಅಸ್ತಿತ್ವಟ್ ಇಜ್ಜಿ. ದುಂಬು ಪೊಯರ ಇರ್ ಖಚಿತವಾತ್ ಬಯಸುವರಾ?ಅಂದ್ಅತ್ತ್ತರೆಬರವು
@@ -233,8 +232,6 @@
ಚಿತ್ರೊಲೆನ್ ಕ್ಯಾಶಿಂಗ್ ಮಾಲ್ಪುನಗ ದೋಷೊ.ಫೈಲ್ಗಾತ್ ಒಂಜಿ ಬೇತೆ ವಿವರಣಾತ್ಮಕೊ ಪುದಾರ್, ಉಂದು ಫೈಲ್ ಪುದಾರ್ ಆತ್ ಕಾರ್ಯನಿರ್ವಹಣೆ ಅಪುಂಡು. ಇರೆನ ಜಾಗೆತೊಟ್ಟಗ್ ಸರಳ ಭಾಷೆನ್ ಬಲಕೆ ಮಾಪ್ಲೊಲಿ. ಫೈಲ್ ವಿಸ್ತರಣೆನ್ ಮಾಲ್ಪೊಲಿ.ದಯಮಾಲ್ತ್ ಸಾಧ್ಯವಾಯಿನ ಮಾಧ್ಯಮಟ್ ವಿವರಣೆ ಕೊರ್ಲೆ: ಒಲ್ಪಾ ಅಯಿನ್ ದೆಪ್ಪೊಲಿ? ಉಂದೆನ್ ಎಂಚ ತೋಜಾವೊಲಿ? ಸನ್ನಿವೇಶ ಪಂಡದಾದ? ದಯಮಾಲ್ತ್ ವಸ್ತುಲು ಅತ್ತಂದೆ ವ್ಯಕ್ತಿಲು ಸುಲಭವಾತ್ ಊಹಿಸಲು ಸಾದ್ಯ ಇಜ್ಜಿ ಮಾಹಿತಿನ್ ಬಹಿರಂಗ ಮಾಲ್ಪುಲೆ, ಉದಾಹರಣೆಗ್ ಉಂದು ಭೂದೃಶ್ಯವಾತ್ ಇತ್ತಂಡ್ ದಿನೊತ ಸಮಯ. ಮಾಧ್ಯಮೊ ಅಸಾಮಾನ್ಯವಾತ್ ಇಪ್ಪುನಯಿನ್ ತೋಜಾತ್, ಅವು ಅಸಾಮಾನ್ಯವಾತ್ ವಿವರಣೆ ಇಪ್ಪು.
- ಈ ಚಿತ್ರೊ ತೀರ ಗಾಢವಾತ್, ಅಯಿನ್ ಅಪ್ಲೋಡ್ ಮಾಲ್ಪಿಯರ ಇರ್ ಖಚಿತವಾತ್ ಉಪ್ಪುವರಾ? ವಿಕಿಮೀಡಿಯ ಕಾಮನ್ಸ್ ಮಾತ್ರೊ ವಿಶ್ವಕೋಶತ ಮೌಲ್ಯದೊಂಟ್ಟ್ಗ್ ಚಿತ್ರೊನ್ ಹೊಂದಾಣಿಕೆ ಮಾಲ್ಪುಲೆ.
- ಈ ಚಿತ್ರೊ ತೆಳುವಾಯಿನ, ಇರ್ ಅಯಿನ್ ಅಪ್ಲೋಡ್ ಮಾಲ್ಪಿಯರ ಖಚಿತವಾತ್ ಬಯಸುವರಾ? ವಿಕಿಮೀಡಿಯ ಕಾಮನ್ಸ್ ಮಾತ್ರೊ ವಿಶ್ವಕೋಶತ ಮೌಲ್ಯದೊಂಟ್ಟ್ಗ್ ಚಿತ್ರೊನ್ ಹೊಂದಾಣಿಕೆ ಮಾಲ್ಪುಲೆ.ಒಪ್ಪಿಗೆ ಪಡೆಲೆ.ಉಂದು ಎಕ್ಸ್ಟರ್ನಲ್ ಸ್ಟೊರೆಜ್.ಈ ಸಾಧನಟ್ ಅಪ್ಲಿಕೇಶನ್ ಕ್ಯಾಮೆರಾದೊಂಟ್ಟಗ್ ದೆತ್ತಿನ ಚಿತ್ರೊನ್ ಒರಿಪಾಲೆ.
diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml
index c8d05f346..ed0405a29 100644
--- a/app/src/main/res/values-te/strings.xml
+++ b/app/src/main/res/values-te/strings.xml
@@ -41,7 +41,7 @@
నా ఎక్కింపులుపంచుకోండివిహారిణిలో చూపు
- శీర్షిక
+ శీర్షికవివరణలాగిన్ చెయ్యలేకపోయాం - నెట్వర్కు విఫలంమరీ ఎక్కువ విఫల యత్నాలు చేసారు. కొద్ది నిముషాలాగి ప్రయత్నించండి
diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml
index 3206dcf4f..10449f996 100644
--- a/app/src/main/res/values-th/strings.xml
+++ b/app/src/main/res/values-th/strings.xml
@@ -44,7 +44,7 @@
การอัปโหลดของฉันแชร์ดูในเบราว์เซอร์
- ชื่อเรื่อง
+ ชื่อเรื่องกรุณาระบุชืิ่อเรื่องของไฟล์นี้คำอธิบายไม่สามารถเข้าสู่ระบบได้ - ความล้มเหลวของเครือข่าย
@@ -63,7 +63,7 @@
GPS ถูกปิดใช้งานในอุปกรณ์ของคุณอยู่ คุณต้องการเปิดใช้งานหรือไม่?เปิดใช้งาน GPSยังไม่มีการอัปโหลด
- การอัปโหลด %1$d รายการ
+ การอัปโหลด %1$d รายการกำลังเริ่มอัปโหลด %1$d รายการกำลังเริ่มอัปโหลด %1$d รายการ
@@ -155,7 +155,6 @@
สถานที่ใกล้เคียงไม่พบสถานที่ใกล้เคียงคำเตือน
- ไฟล์นี้มีอยู่แล้วบนคอมมอนส์ คุณแน่ใจหรือว่าคุณต้องการดำเนินการต่อ?ใช่ไม่ชื่อเรื่อง
@@ -213,8 +212,6 @@
ข้อผิดพลาดขณะแคชภาพชื่อเรื่องที่อธิบายลักษณะเฉพาะของไฟล์ ซึ่งจะใช้เป็นชื่อไฟล์ คุณอาจใช้ภาษาธรรมดาที่มีเว้นวรรคก็ได้ อย่ารวมนามสกุลไฟล์โปรดอธิบายสื่อดังกล่าวให้มากที่สุดเท่าที่จะได้: สื่อนี้ถูกถ่ายที่ไหน? สื่อนี้แสดงถึงอะไร? บริบทคืออะไร? โปรดอธิบายถึงวัตถุหรือบุคคล เปิดเผยข้อมูลที่ไม่อาจคาดเดาได้อย่างง่ายดาย เช่น เวลาที่ถ่าย หากเป็นภาพทิวทัศน์ หากสื่อแสดงถึงสิ่งที่ไม่ธรรมดา โปรดอธิบายว่าอะไรทำให้สื่อดังกล่าวไม่ธรรมดา
- ภาพนี้มืดเกินไป คุณแน่ใจหรือว่าคุณต้องการอัปโหลดภาพนี้? วิกิมีเดียคอมมอนส์นั้นมีไว้สำหรับรูปภาพที่มีคุณค่าในทางสารานุกรมเท่านั้น
- ภาพนี้มัว คุณแน่ใจหรือว่าคุณต้องการอัปโหลดภาพนี้? วิกิมีเดียคอมมอนส์นั้นมีไว้สำหรับรูปภาพที่มีคุณค่าในทางสารานุกรมเท่านั้นให้สิทธิ์ใช้ที่จัดเก็บข้อมูลภายนอกบันทึกรูปภาพที่ถ่ายด้วยกล้องในแอปบนอุปกรณ์ของคุณ
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 583619c1d..7fc85d059 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -10,6 +10,7 @@
* Neslihan Turan
* Rapsar
* Sayginer
+* Sucsuzz
* TmY e12
* Trockya
* VikipediBilgini
@@ -60,7 +61,7 @@
YüklemelerimPaylaşTarayıcıda görüntüle
- Başlık
+ Başlık (Zorunlu)Lütfen bu dosya için bir başlık ekleyinAçıklamaOturum açılamıyor - ağ hatası
@@ -83,8 +84,8 @@
Henüz yüklenmedi\@string/contributions_subtitle_zero
- %1$d yükleme
- %1$d yükleme
+ (%1$d
+ (%1$d)%1$d yüklenmeye başlanıyor
@@ -180,7 +181,7 @@
Yakındaki yerlerYakınlardaki yer bulunamadıUyarı
- Bu dosya zaten Commons\'da var. Devam etmek istediğinizden emin misiniz?
+ Bu dosya Commons\'ta zaten var. Devam etmek istediğine emin misin?EvetHayırBaşlık
@@ -242,8 +243,8 @@
Resimler önbelleğe alınırken hata oluştuDosya için dosya adı olarak kullanılacak benzersiz açıklayıcı bir başlık olmalıdır. Boşluk bırakarak sade bir dil kullanabilirsiniz. Dosya uzantısını dahil etmeyinLütfen medyayı mümkün olduğunca açıklayın: Nerede çekildi? Ne gösteriyor? Bağlam nedir? Lütfen nesneleri veya kişileri tanımlayın. Kolay tahmin edilemeyen bilgileri açıklayın, örneğin bir manzara ise günün saatini belirtin. Medya alışılmadık bir şey gösteriyorsa lütfen olağandışı yapan şeyleri açıklayın.
- Bu fotoğraf çok karanlık, yine de yüklemek istiyor musunuz? Wikimedia Commons yalnızca ansiklopedik değeri olan fotoğraflar içindir.
- Bu fotoğraf bulanık, yine de yüklemek istiyor musunuz? Wikimedia Commons yalnızca ansiklopedik değeri olan fotoğraflar içindir.
+ Bu fotoğraf çok karanlık, yine de yüklemek istiyor musunuz? Wikimedia Commons yalnızca ansiklopedik değeri olan fotoğraflar içindir.
+ Bu fotoğraf bulanık, yine de yüklemek istiyor musunuz? Wikimedia Commons yalnızca ansiklopedik değeri olan fotoğraflar içindir.İzin verHarici depolamayı kullanınUygulama kamerası kullanıldığında çekilen fotoğrafları cihazına kaydedin
@@ -336,8 +337,10 @@
Koordinatlar görüntü seçimi sırasında belirlenmediYakındaki yerler alınırken hata oluştu.+ Açıklama ekle
+ Son arama yokArama geçmişinizi silmek istediğinize emin misiniz?Arama geçmişi silindi
+ Silinmeye aday gösterBaşarılarİSTATİSTİKLERAlınan Teşekkürler
@@ -354,8 +357,27 @@
Wikimedia makalelerinde kullanılan Commons\'a yüklediğiniz görüntü sayısıHata oluştu!Commons Bildirimi
+ Katkılar
+ Yakınındakiler
+ Bildirimler
+ Yakındaki bildirimi görüntüle
+ Resimlere en yakın yeri görmek için buraya dokunun
+ Size yakın bir yer bulunamadı
+ ListeDepolama İzniGörüntüleri yüklemek için cihazınızın harici belleğine erişim iznine sahip olmamız gerekiyor.
+ Artık size en yakın yerleri görmeyeceksiniz. Ancak, isterseniz bu bildirimi Ayarlar\'da yeniden etkinleştirebilirsiniz.
+ Aşama %1$d/%2$d
+ Resim %1$d kayıtta
+ Sıradaki
+ Önceki
+ Gönder
+ %1$s adında zaten bir dosya var. Devam etmek istediğine emin misin?
+ Cihazınızda uyumlu bir harita uygulaması bulunamadı. Lütfen bu özelliği kullanmak için bir harita uygulaması yükleyin.
+
+ %1$d Yükleme
+ %1$d Yükleme
+ Yer imleriYer imleriResim
@@ -365,5 +387,36 @@
Henüz yer imlerine bir şey eklemedinizYer imleriGünlük koleksiyonu başlatıldı. Lütfen uygulamayı YENİDEN BAŞLATIN, günlüğe kaydetmek istediğiniz eylemi gerçekleştirin ve ardından \'Günlüğü Gönder\'e tekrar dokunun.
+ Yanlışlıkla yükledim
+ Bunun herkese görünür olacağını bilmiyordum
+ Gizliliğim açısından kötü olduğunu fark ettim
+ Fikrimi değiştirdim, bunun herkese görünür olmasını istemiyorum
+ Ansiklopedi için gerekli olmayan bir resim
+ Kendi tarafımdan yüklendi
+ ,kullanılan
+ maddelerCommons\'a Hoş Geldiniz!\n\nYukarıdaki kamera ya da galeri simgesine dokunarak ilk medyanızı yükleyin.
+ Dünya çapında
+ Amerika
+ Avrupa
+ Orta Doğu
+ Afrika
+ Asya
+ Pasifik
+ Kategori Seçilmedi
+ Kategorisiz görüntüler nadiren kullanılabilir. Kategorileri seçmeden göndermek istediğinizden emin misiniz?
+ Evet, Gönder
+ Hayır, Geri Dön
+ (Set içindeki tüm görüntüler için)
+ Bu alanı ara
+ Yetki İsteği
+ Resimlerinize en yakın yeri eklemek için mevcut konumunuzu kullanmamızı ister misiniz?
+ Konum izinleri olmadan resminize yakın yer eklenemiyor.
+ Bunu bir daha sorma
+ Yerleşim iznini görüntüle
+ Yakındaki bildirim kartı görünümü özelliği için gerektiğinde konum izni isteyin.
+ Bitiş:
+ Kampanyaları göster
+ Devam eden kampanyaları görmek için buraya dokunun
+ Artık kampanyaları görmeyeceksiniz. Ancak isterseniz bu bildirimi Ayarlar\'da yeniden etkinleştirebilirsiniz.
diff --git a/app/src/main/res/values-ug/strings.xml b/app/src/main/res/values-ug/strings.xml
index bf4db9078..802905019 100644
--- a/app/src/main/res/values-ug/strings.xml
+++ b/app/src/main/res/values-ug/strings.xml
@@ -45,7 +45,7 @@
يۈكلىگەنلىرىمئورتاقلىشىشتوركۆرگۈدە ئېچىڭ
- ماۋزۇ
+ ماۋزۇچۈشەندۈرۈشتىزىملىتىش - تور كاشىلىسىكىرەلمىدى، ئابۇنىت نامى ۋە پارولىڭىزنى تەكشۈرۈڭ.
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 42283caec..702cd18a4 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -59,7 +59,7 @@
Мої завантаженняПоділитисяВідкрити у браузері
- Назва
+ Назва (обов\'язково)Будь ласка, вкажіть назву цього файлуОписНеможливо увійти — збій у мережі
@@ -185,7 +185,6 @@
Місця поблизуНе знайдено місць поблизуПопередження
- Цей файл вже існує на Вікісховищі. Ви впевнені, що хочете продовжити?ТакНіНазва
@@ -247,8 +246,6 @@
Помилка кешування зображеньУнікальна описова назва файлу. Ви можете використовувати простий текст з пробілами. Не вказуйте розширення файлуБудь ласка, докладно опишіть файл: де його було зроблено? що на ньому зображено? який контекст? Будь ласка, опишіть об\'єкти чи осіб. Додайте інформацію, яку не можна легко здогадатися, наприклад, пору доби для фотографії пейзажу. Якщо зображено щось незвичайне, спробуйте пояснити, що робить його незвичайним.
- Це зображення надто темне. Ви упевнені, що хочете його завантажити? Вікісховище призначене лише для зображень, що мають енциклопедичну цінність.
- Це зображення розмите. Ви упевнені, що хочете його завантажити? Вікісховище призначене лише для зображень, що мають енциклопедичну цінність.Надати дозвілВикористовувати зовнішнє сховищеЗберігати зображення, виконані вбудованою камерою Вашого пристрою
diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml
index f7020ffae..c8d1e724e 100644
--- a/app/src/main/res/values-ur/strings.xml
+++ b/app/src/main/res/values-ur/strings.xml
@@ -49,7 +49,7 @@
میرے اپلوڈ کردہشیئربراؤزر میں کھولیں
- عنوان
+ عنوانوضاحتلاگ ان ہونے میں ناکام - نیٹ ورک ناکامیبے شمار ناکام کوششیں کچھ منٹوں میں دوبارہ کوشش کریں۔
@@ -157,4 +157,7 @@
انٹرنیٹ دستیاب نہیںانٹرنیٹ دستیابدوبارہ کوشش کریں
+ فہرست
+ مشرق وسطی
+ افریقا
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index aad679fe5..3aed0ec44 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -2,6 +2,7 @@