From 31bb1a73c0c6848c381ab2e769e074e849e71e3d Mon Sep 17 00:00:00 2001 From: djbloop <92338222+djbloop@users.noreply.github.com> Date: Sun, 25 Aug 2024 21:24:15 -0700 Subject: [PATCH 1/5] First of two fixes for bug #5726: hide nominate for deletion when logged out (#5773) --- .../commons/media/MediaDetailFragment.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) 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 e3fdf7dec..7336c1b40 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 @@ -73,18 +73,20 @@ import fr.free.nrw.commons.description.DescriptionEditHelper; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity; import fr.free.nrw.commons.kvstore.JsonKvStore; +import fr.free.nrw.commons.language.AppLanguageLookUpTable; import fr.free.nrw.commons.location.LocationServiceManager; import fr.free.nrw.commons.profile.ProfileActivity; import fr.free.nrw.commons.review.ReviewHelper; import fr.free.nrw.commons.settings.Prefs; -import fr.free.nrw.commons.ui.widget.HtmlTextView; +import fr.free.nrw.commons.upload.UploadMediaDetail; import fr.free.nrw.commons.upload.categories.UploadCategoriesFragment; import fr.free.nrw.commons.upload.depicts.DepictsFragment; -import fr.free.nrw.commons.upload.UploadMediaDetail; +import fr.free.nrw.commons.utils.DateUtil; import fr.free.nrw.commons.utils.DialogUtil; import fr.free.nrw.commons.utils.PermissionUtils; import fr.free.nrw.commons.utils.ViewUtil; import fr.free.nrw.commons.utils.ViewUtilWrapper; +import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage; import io.reactivex.Observable; import io.reactivex.ObservableSource; import io.reactivex.Single; @@ -105,9 +107,6 @@ import java.util.regex.Pattern; import javax.inject.Inject; import javax.inject.Named; import org.apache.commons.lang3.StringUtils; -import fr.free.nrw.commons.wikidata.mwapi.MwQueryPage; -import fr.free.nrw.commons.language.AppLanguageLookUpTable; -import fr.free.nrw.commons.utils.DateUtil; import timber.log.Timber; public class MediaDetailFragment extends CommonsDaggerSupportFragment implements @@ -487,12 +486,18 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements } private void onDeletionPageExists(Boolean deletionPageExists) { - if (deletionPageExists){ - if(applicationKvStore.getBoolean(String.format(NOMINATING_FOR_DELETION_MEDIA, media.getImageUrl()), false)) { - applicationKvStore.remove(String.format(NOMINATING_FOR_DELETION_MEDIA, media.getImageUrl())); + if (AccountUtil.getUserName(getContext()) == null && !AccountUtil.getUserName(getContext()).equals(media.getAuthor())) { + binding.nominateDeletion.setVisibility(GONE); + binding.nominatedDeletionBanner.setVisibility(GONE); + } else if (deletionPageExists) { + if (applicationKvStore.getBoolean( + String.format(NOMINATING_FOR_DELETION_MEDIA, media.getImageUrl()), false)) { + applicationKvStore.remove( + String.format(NOMINATING_FOR_DELETION_MEDIA, media.getImageUrl())); binding.progressBarDeletion.setVisibility(GONE); } binding.nominateDeletion.setVisibility(GONE); + binding.nominatedDeletionBanner.setVisibility(VISIBLE); } else if (!isCategoryImage) { binding.nominateDeletion.setVisibility(VISIBLE); @@ -1174,7 +1179,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements //Reviewer correct me if i have misunderstood something over here //But how does this if (delete.getVisibility() == View.VISIBLE) { // enableDeleteButton(true); makes sense ? - else { + else if (AccountUtil.getUserName(getContext()) != null) { final EditText input = new EditText(getActivity()); input.requestFocus(); AlertDialog d = DialogUtil.showAlertDialog(getActivity(), From 46df64d2084faad2b6f0c7af3ec19d0aff08a68e Mon Sep 17 00:00:00 2001 From: Rohit Verma <101377978+rohit9625@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:13:50 +0530 Subject: [PATCH 2/5] Prevent deletion of other structured data when editing depicts (#5741) * restructure : minor changes to comments to improve readability * api: remove clear flag to prevent deletion of structured data * WikiBaseInterface: add new api methods Get Method: to get claims for an entity Post method: to delete claims * WikiBaseClient: add methods to handle response for new APIs * typo: update call to method with updated typo * DepictEditHelper: call update property method with entity id * refactor: dismiss progress dialog on error * DepictsDao: remove usage of runBlocking as it was blocking main thread Refactor methods to perform well with coroutines * refactor: update usage of method to match changes in DepictsDao * refactor: use named parameters to improve readability * claims: add new data classes to represent remove claims * WikidataEditService: modify update depicts property method Performs deletion of old claims and creation of new claims * refactor: make methods more organized --- .../nrw/commons/upload/WikiBaseInterface.kt | 18 ++- .../free/nrw/commons/upload/depicts/Claims.kt | 9 ++ .../upload/depicts/DepictEditHelper.kt | 2 +- .../nrw/commons/upload/depicts/DepictsDao.kt | 119 ++++++++---------- .../upload/depicts/DepictsPresenter.kt | 19 +-- .../nrw/commons/wikidata/WikiBaseClient.kt | 20 ++- .../commons/wikidata/WikidataEditService.java | 71 ++++++----- .../nrw/commons/wikidata/model/EditClaim.kt | 18 +-- .../nrw/commons/wikidata/model/RemoveClaim.kt | 20 +++ .../commons/wikidata/model/Snak_partial.kt | 12 +- .../wikidata/model/Statement_partial.kt | 2 +- .../wikidata/WikiBaseClientUnitTest.kt | 2 +- 12 files changed, 188 insertions(+), 124 deletions(-) create mode 100644 app/src/main/java/fr/free/nrw/commons/upload/depicts/Claims.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/wikidata/model/RemoveClaim.kt diff --git a/app/src/main/java/fr/free/nrw/commons/upload/WikiBaseInterface.kt b/app/src/main/java/fr/free/nrw/commons/upload/WikiBaseInterface.kt index 62cf4bfbd..1bc5f84fc 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/WikiBaseInterface.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/WikiBaseInterface.kt @@ -1,5 +1,6 @@ package fr.free.nrw.commons.upload +import fr.free.nrw.commons.upload.depicts.Claims import fr.free.nrw.commons.wikidata.WikidataConstants import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse @@ -34,7 +35,7 @@ interface WikiBaseInterface { */ @Headers("Cache-Control: no-cache") @FormUrlEncoded - @POST(WikidataConstants.MW_API_PREFIX + "action=wbeditentity&site=commonswiki&clear=1") + @POST(WikidataConstants.MW_API_PREFIX + "action=wbeditentity&site=commonswiki") fun postEditEntityByFilename( @Field("title") filename: String, @Field("token") editToken: String, @@ -59,4 +60,19 @@ interface WikiBaseInterface { @Field("language") language: String?, @Field("value") captionValue: String? ): Observable + + @GET(WikidataConstants.MW_API_PREFIX + "action=wbgetclaims") + fun getClaimsByProperty( + @Query("entity") entityId: String, + @Query("property") property: String + ) : Observable + + @Headers("Cache-Control: no-cache") + @FormUrlEncoded + @POST(WikidataConstants.MW_API_PREFIX + "action=wbeditentity") + fun postDeleteClaims( + @Field("token") editToken: String, + @Field("id") entityId: String, + @Field("data") data: String + ): Observable } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/Claims.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/Claims.kt new file mode 100644 index 000000000..e0a3a8e8b --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/Claims.kt @@ -0,0 +1,9 @@ +package fr.free.nrw.commons.upload.depicts + +import com.google.gson.annotations.SerializedName +import fr.free.nrw.commons.wikidata.model.Statement_partial + +data class Claims( + @SerializedName(value = "claims") + val claims: Map> = emptyMap() +) \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictEditHelper.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictEditHelper.kt index 92cd29cbf..c681e5b7d 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictEditHelper.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictEditHelper.kt @@ -69,7 +69,7 @@ class DepictEditHelper @Inject constructor (notificationHelper: NotificationHelp */ private fun addDepiction(media: Media, depictions: List): Observable { Timber.d("thread is adding depiction %s", Thread.currentThread().name) - return wikidataEditService.updateDepictsProperty(media.filename, depictions) + return wikidataEditService.updateDepictsProperty(media.pageId, depictions) } /** diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsDao.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsDao.kt index 9b9d31ed2..d79240601 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsDao.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsDao.kt @@ -1,112 +1,99 @@ package fr.free.nrw.commons.upload.depicts -import androidx.room.* +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Deferred import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking -import java.util.* +import java.util.Date /** * Dao class for DepictsRoomDataBase */ @Dao abstract class DepictsDao { - - /** - * insert Depicts in DepictsRoomDataBase - */ + /** The maximum number of depicts allowed in the database. */ + private val maxItemsAllowed = 10 + @Insert(onConflict = OnConflictStrategy.REPLACE) abstract suspend fun insert(depictedItem: Depicts) - - /** - * get all Depicts from roomdatabase - */ + @Query("Select * From depicts_table order by lastUsed DESC") - abstract suspend fun getAllDepict(): List + abstract suspend fun getAllDepicts(): List - /** - * get all Depicts which need to delete from roomdatabase - */ @Query("Select * From depicts_table order by lastUsed DESC LIMIT :n OFFSET 10") - abstract suspend fun getItemToDelete(n: Int): List + abstract suspend fun getDepictsForDeletion(n: Int): List - /** - * Delete Depicts from roomdatabase - */ @Delete abstract suspend fun delete(depicts: Depicts) - lateinit var allDepict: List - lateinit var listOfDelete: List - /** - * get all depicts from DepictsRoomDatabase + * Gets all Depicts objects from the database, ordered by lastUsed in descending order. + * + * @return A list of Depicts objects. */ - fun depictsList(): List { - runBlocking { - launch(Dispatchers.IO) { - allDepict = getAllDepict() - } - } - return allDepict + fun depictsList(): Deferred> = CoroutineScope(Dispatchers.IO).async { + getAllDepicts() } /** - * insert Depicts in DepictsRoomDataBase + * Inserts a Depicts object into the database. + * + * @param depictedItem The Depicts object to insert. */ - fun insertDepict(depictes: Depicts) { - runBlocking { - launch(Dispatchers.IO) { - insert(depictes) - } - } + private fun insertDepict(depictedItem: Depicts) = CoroutineScope(Dispatchers.IO).launch { + insert(depictedItem) } /** - * get all Depicts item which need to delete + * Gets a list of Depicts objects that need to be deleted from the database. + * + * @param n The number of depicts to delete. + * @return A list of Depicts objects to delete. */ - fun getItemTodelete(number: Int): List { - runBlocking { - launch(Dispatchers.IO) { - listOfDelete = getItemToDelete(number) - } - } - return listOfDelete + private suspend fun depictsForDeletion(n: Int): Deferred> = CoroutineScope(Dispatchers.IO).async { + getDepictsForDeletion(n) } /** - * delete Depicts in DepictsRoomDataBase + * Deletes a Depicts object from the database. + * + * @param depicts The Depicts object to delete. */ - fun deleteDepicts(depictes: Depicts) { - runBlocking { - launch(Dispatchers.IO) { - delete(depictes) - } - } + private suspend fun deleteDepicts(depicts: Depicts) = CoroutineScope(Dispatchers.IO).launch { + delete(depicts) } /** - * save Depicts in DepictsRoomDataBase + * Saves a list of DepictedItems in the DepictsRoomDataBase. */ fun savingDepictsInRoomDataBase(listDepictedItem: List) { - var numberofItemInRoomDataBase: Int - val maxNumberOfItemSaveInRoom = 10 + CoroutineScope(Dispatchers.IO).launch { + for (depictsItem in listDepictedItem) { + depictsItem.isSelected = false + insertDepict(Depicts(depictsItem, Date())) + } - for (depictsItem in listDepictedItem) { - depictsItem.isSelected = false - insertDepict(Depicts(depictsItem, Date())) + // Deletes old Depicts objects from the database if + // the number of depicts exceeds the maximum allowed. + deleteOldDepictions(depictsList().await().size) } + } - numberofItemInRoomDataBase = depictsList().size - // delete the depictItem from depictsroomdataBase when number of element in depictsroomdataBase is greater than 10 - if (numberofItemInRoomDataBase > maxNumberOfItemSaveInRoom) { + private suspend fun deleteOldDepictions(depictsListSize: Int) { + if(depictsListSize > maxItemsAllowed) { + val depictsForDeletion = depictsForDeletion(depictsListSize).await() - val listOfDepictsToDelete: List = - getItemTodelete(numberofItemInRoomDataBase) - for (i in listOfDepictsToDelete) { - deleteDepicts(i) + for(depicts in depictsForDeletion) { + deleteDepicts(depicts) } } } -} \ No newline at end of file +} + diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt index edcda24f0..cd0033e08 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt @@ -16,6 +16,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.processors.PublishProcessor import io.reactivex.schedulers.Schedulers +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import timber.log.Timber import java.lang.reflect.Proxy import java.util.* @@ -223,9 +226,8 @@ class DepictsPresenter @Inject constructor( if (error is InvalidLoginTokenException) { view.navigateToLoginScreen(); } else { - Timber.e( - "Failed to update depictions" - ) + view.dismissProgressDialog() + Timber.e("Failed to update depictions") } }) ) @@ -268,10 +270,13 @@ class DepictsPresenter @Inject constructor( */ fun getRecentDepictedItems(): MutableList { val depictedItemList: MutableList = ArrayList() - val depictsList = depictsDao.depictsList() - for (i in depictsList.indices) { - val depictedItem = depictsList[i].item - depictedItemList.add(depictedItem) + CoroutineScope(Dispatchers.IO).launch { + val depictsList = depictsDao.depictsList().await() + + for (i in depictsList.indices) { + val depictedItem = depictsList[i].item + depictedItemList.add(depictedItem) + } } return depictedItemList } diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt b/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt index f6f8b9ade..70a976164 100644 --- a/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt +++ b/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt @@ -8,7 +8,6 @@ import fr.free.nrw.commons.upload.WikiBaseInterface import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse import fr.free.nrw.commons.wikidata.mwapi.MwQueryResponse import io.reactivex.Observable -import timber.log.Timber import javax.inject.Inject import javax.inject.Named import javax.inject.Singleton @@ -42,12 +41,29 @@ class WikiBaseClient @Inject constructor( } } + fun getClaimIdsByProperty(fileEntityId: String, property: String ): Observable> { + return wikiBaseInterface.getClaimsByProperty(fileEntityId, property).map { claimsResponse -> + claimsResponse.claims[property]?.mapNotNull { claim -> claim.id } ?: emptyList() + } + } + + fun postDeleteClaims(entityId: String, data: String): Observable { + return csrfToken().switchMap { editToken -> + wikiBaseInterface.postDeleteClaims(editToken, entityId, data) + .map { response: MwPostResponse -> response.successVal == 1 } + } + } + fun getFileEntityId(uploadResult: UploadResult): Observable { return wikiBaseInterface.getFileEntityId(uploadResult.createCanonicalFileName()) .map { response: MwQueryResponse -> response.query()!!.pages()!![0].pageId().toLong() } } - fun addLabelstoWikidata(fileEntityId: Long, languageCode: String?, captionValue: String?): Observable { + fun addLabelsToWikidata( + fileEntityId: Long, + languageCode: String?, + captionValue: String? + ): Observable { return csrfToken().switchMap { editToken -> wikiBaseInterface.addLabelstoWikidata( PAGE_ID_PREFIX + fileEntityId, 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 ca2093e26..8e298cc9a 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 @@ -8,7 +8,6 @@ import android.content.Context; import androidx.annotation.Nullable; import com.google.gson.Gson; import fr.free.nrw.commons.R; -import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.upload.UploadResult; @@ -19,9 +18,11 @@ import fr.free.nrw.commons.utils.ViewUtil; import fr.free.nrw.commons.wikidata.model.DataValue; import fr.free.nrw.commons.wikidata.model.DataValue.ValueString; import fr.free.nrw.commons.wikidata.model.EditClaim; +import fr.free.nrw.commons.wikidata.model.RemoveClaim; import fr.free.nrw.commons.wikidata.model.Snak_partial; import fr.free.nrw.commons.wikidata.model.Statement_partial; import fr.free.nrw.commons.wikidata.model.WikiBaseMonolingualTextValue; +import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse; import io.reactivex.Observable; import io.reactivex.schedulers.Schedulers; import java.util.ArrayList; @@ -34,7 +35,6 @@ import java.util.UUID; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; -import fr.free.nrw.commons.wikidata.mwapi.MwPostResponse; import timber.log.Timber; /** @@ -72,9 +72,10 @@ public class WikidataEditService { * to the wikibase API to set tag against the entity. */ @SuppressLint("CheckResult") - private Observable addDepictsProperty(final String fileEntityId, - final List depictedItems) { - + private Observable addDepictsProperty( + final String fileEntityId, + final List depictedItems + ) { final EditClaim data = editClaim( ConfigUtils.isBetaFlavour() ? Collections.singletonList("Q10") // Wikipedia:Sandbox (Q10) @@ -100,45 +101,54 @@ public class WikidataEditService { * Takes depicts ID as a parameter and create a uploadable data with the Id * and send the data for POST operation * - * @param filename name of the file - * @param depictedItems ID of the selected depict item + * @param fileEntityId ID of the file + * @param depictedItems IDs of the selected depict item * @return Observable */ @SuppressLint("CheckResult") - public Observable updateDepictsProperty(final String filename, - final List depictedItems) { + public Observable updateDepictsProperty( + final String fileEntityId, + final List depictedItems + ) { + final String entityId = PAGE_ID_PREFIX + fileEntityId; + final List claimIds = getDepictionsClaimIds(entityId); - final EditClaim data = editClaim( + final RemoveClaim data = removeClaim( /* Please consider removeClaim scenario for BetaDebug */ ConfigUtils.isBetaFlavour() ? Collections.singletonList("Q10") // Wikipedia:Sandbox (Q10) - : depictedItems + : claimIds ); - return wikiBaseClient.postEditEntityByFilename(filename, - gson.toJson(data)) - .doOnNext(success -> { - if (success) { - Timber.d("DEPICTS property was set successfully for %s", filename); - } else { - Timber.d("Unable to set DEPICTS property for %s", filename); - } - }) + return wikiBaseClient.postDeleteClaims(entityId, gson.toJson(data)) .doOnError(throwable -> { - if (throwable instanceof InvalidLoginTokenException) { - Observable.error(throwable); + Timber.e(throwable, "Error occurred while removing existing claims for DEPICTS property"); + ViewUtil.showLongToast(context, context.getString(R.string.wikidata_edit_failure)); + }).switchMap(success-> { + if(success) { + Timber.d("DEPICTS property was deleted successfully"); + return addDepictsProperty(fileEntityId, depictedItems); } else { - Timber.e(throwable, "Error occurred while setting DEPICTS property"); - ViewUtil.showLongToast(context, throwable.toString()); + Timber.d("Unable to delete DEPICTS property"); + return Observable.empty(); } + }); + } - }) - .subscribeOn(Schedulers.io()); + @SuppressLint("CheckResult") + private List getDepictionsClaimIds(final String entityId) { + return wikiBaseClient.getClaimIdsByProperty(entityId, WikidataProperties.DEPICTS.getPropertyName()) + .subscribeOn(Schedulers.io()) + .blockingFirst(); } private EditClaim editClaim(final List entityIds) { return EditClaim.from(entityIds, WikidataProperties.DEPICTS.getPropertyName()); } + private RemoveClaim removeClaim(final List claimIds) { + return RemoveClaim.from(claimIds); + } + /** * Show a success toast when the edit is made successfully */ @@ -156,11 +166,10 @@ public class WikidataEditService { * @param fileEntityId * @return */ - @SuppressLint("CheckResult") private Observable addCaption(final long fileEntityId, final String languageCode, final String captionValue) { - return wikiBaseClient.addLabelstoWikidata(fileEntityId, languageCode, captionValue) + return wikiBaseClient.addLabelsToWikidata(fileEntityId, languageCode, captionValue) .doOnNext(mwPostResponse -> onAddCaptionResponse(fileEntityId, mwPostResponse)) .doOnError(throwable -> { Timber.e(throwable, "Error occurred while setting Captions"); @@ -220,8 +229,10 @@ public class WikidataEditService { } } - public Observable addDepictionsAndCaptions(final UploadResult uploadResult, - final Contribution contribution) { + public Observable addDepictionsAndCaptions( + final UploadResult uploadResult, + final Contribution contribution + ) { return wikiBaseClient.getFileEntityId(uploadResult) .doOnError(throwable -> { Timber diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/model/EditClaim.kt b/app/src/main/java/fr/free/nrw/commons/wikidata/model/EditClaim.kt index 5bc7eecc0..5d2ab7e38 100644 --- a/app/src/main/java/fr/free/nrw/commons/wikidata/model/EditClaim.kt +++ b/app/src/main/java/fr/free/nrw/commons/wikidata/model/EditClaim.kt @@ -11,19 +11,19 @@ data class EditClaim(val claims: List) { entityIds.forEach { list.add( Statement_partial( - Snak_partial( - "value", - propertyName, - DataValue.EntityId( + mainSnak = Snak_partial( + snakType = "value", + property = propertyName, + dataValue = DataValue.EntityId( WikiBaseEntityValue( - "item", - it, - it.removePrefix("Q").toLong() + entityType = "item", + id = it, + numericId = it.removePrefix("Q").toLong() ) ) ), - "statement", - "preferred" + type = "statement", + rank = "preferred" ) ) } diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/model/RemoveClaim.kt b/app/src/main/java/fr/free/nrw/commons/wikidata/model/RemoveClaim.kt new file mode 100644 index 000000000..1e553ae3e --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/wikidata/model/RemoveClaim.kt @@ -0,0 +1,20 @@ +package fr.free.nrw.commons.wikidata.model + +data class RemoveClaim(val claims: List) { + companion object { + @JvmStatic + fun from(claimIds: List): RemoveClaim { + val claimsToRemove = mutableListOf() + + claimIds.forEach { + claimsToRemove.add( + ClaimRemoveRequest(id = it, remove = "") + ) + } + + return RemoveClaim(claimsToRemove) + } + } +} + +data class ClaimRemoveRequest(val id: String, val remove: String) \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/model/Snak_partial.kt b/app/src/main/java/fr/free/nrw/commons/wikidata/model/Snak_partial.kt index eb1412cf5..9ffe05434 100644 --- a/app/src/main/java/fr/free/nrw/commons/wikidata/model/Snak_partial.kt +++ b/app/src/main/java/fr/free/nrw/commons/wikidata/model/Snak_partial.kt @@ -5,15 +5,15 @@ import com.google.gson.annotations.SerializedName /*"mainsnak": { "snaktype": "value", "property": "P17", - "datatype": "wikibase-item", "datavalue": { "value": { - "entity-type": "item", - "id": "Q30", - "numeric-id": 30 - }, + "entity-type": "item", + "numeric-id": 30, + "id": "Q30" + }, "type": "wikibase-entityid" - } + }, + "datatype": "wikibase-item", }*/ data class Snak_partial( @SerializedName("snaktype") val snakType: String, diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/model/Statement_partial.kt b/app/src/main/java/fr/free/nrw/commons/wikidata/model/Statement_partial.kt index aecd49b48..5bfb33e19 100644 --- a/app/src/main/java/fr/free/nrw/commons/wikidata/model/Statement_partial.kt +++ b/app/src/main/java/fr/free/nrw/commons/wikidata/model/Statement_partial.kt @@ -3,9 +3,9 @@ package fr.free.nrw.commons.wikidata.model import com.google.gson.annotations.SerializedName /*{ - "id": "q60$5083E43C-228B-4E3E-B82A-4CB20A22A3FB", "mainsnak": {}, "type": "statement", + "id": "q60$5083E43C-228B-4E3E-B82A-4CB20A22A3FB", "rank": "normal", "qualifiers": { "P580": [], diff --git a/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikiBaseClientUnitTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikiBaseClientUnitTest.kt index 956b5d4a0..9e9b2117d 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikiBaseClientUnitTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/wikidata/WikiBaseClientUnitTest.kt @@ -77,7 +77,7 @@ class WikiBaseClientUnitTest { "M123", "test", "en", "caption" )).thenReturn(Observable.just(mwPostResponse)) - val result = wikiBaseClient.addLabelstoWikidata(123L, "en", "caption").blockingFirst() + val result = wikiBaseClient.addLabelsToWikidata(123L, "en", "caption").blockingFirst() assertSame(mwPostResponse, result) } From 39a0b88e3a87abad29f130f4a194d60c38e9b93c Mon Sep 17 00:00:00 2001 From: "translatewiki.net" Date: Mon, 26 Aug 2024 14:02:06 +0200 Subject: [PATCH 3/5] Localisation updates from https://translatewiki.net. --- app/src/main/res/values-el/strings.xml | 344 +++++++++++++------------ app/src/main/res/values-pl/strings.xml | 5 +- 2 files changed, 181 insertions(+), 168 deletions(-) diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 64c6ba694..783479f42 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -1,5 +1,6 @@ - Σελίδα των Κοινών στο Facebook - Κώδικας πηγής των Κοινών στο GitHub + Σελίδα Commons στο Facebook + Πηγαίος κώδικας των Commons στο GitHub Λογότυπο Commons - Ιστοσελίδα των Κοινών + Ιστοσελίδα Commons Έξοδος από το εργαλείο επιλογής τοποθεσίας Υποβολή - Επιλέξτε άλλη περιγραφή + Προσθέστε άλλη περιγραφή Προσθέστε νέα συνεισφορά Προσθέστε συνεισφορά από την κάμερα Προσθέστε συνεισφορά από τις Φωτογραφίες - Προσθέστε συνεισφορά από προηγούμενη συλλογή συνεισφορών + Προσθήκη συνεισφοράς από προηγούμενη συλλογή συνεισφορών Λεζάντες - Περιγραφή Γλώσσας + Περιγραφή γλώσσας Λεζάντα Περιγραφή Εικόνα Όλα - Ενεργοποιήστε + Εναλλαγή προς τα επάνω Προβολή αναζήτησης Κατάσταση τοποθεσίας - Φωτογραφία της Ημέρας + Φωτογραφία της ημέρας - 1 αρχείο επιφορτώνεται - %1$d αρχεία επιφορτώνονται + %1$d μεταφόρτωση αρχείου + %1$d μεταφόρτωση αρχείων (%1$d) (%1$d) - Έναρξη Μεταφορτώσεων + Έναρξη μεταφορτώσεων Επεξεργασία %d μεταφόρτωσης Επεξεργασία %d μεταφορτώσεων - %d μεταφορτώνεται - %d μεταφορτώνονται + %d μεταφόρτωση + %d μεταφορτώσεις Αυτή η εικόνα θα αδειοδοτηθεί υπό την %1$s Αυτές οι εικόνες θα αδειοδοτηθούν υπό την %1$s - %1$d Ανέβασμα στον υπολογιστή - %1$d Ανεβάσματα στον υπολογιστή + %1$d Μεταφόρτωση + %1$d Μεταφορτώσεις Λήψη κοινόχρηστου περιεχομένου. Η επεξεργασία της εικόνας μπορεί να πάρει κάποιο χρόνο ανάλογα με το μέγεθος της εικόνας και τη συσκευή σας @@ -78,142 +79,142 @@ Εμφάνιση Γενικά Ανατροφοδότηση - Ιδιωτικότητα + Απόρρητο Commons Ρυθμίσεις - Ανέβασμα στα Κοινά - Ανέβασμα σε εξέλιξη... + Μεταφόρτωση στα Commons + Μεταφόρτωση σε εξέλιξη Όνομα χρήστη Κωδικός πρόσβασης - Συνδεθείτε στο λογαριασμό σας στο Commons Beta + Συνδεθείτε στον λογαριασμό σας στο Commons Beta Σύνδεση - Ξεχάσατε τον κωδικό σας; + Ξεχάσατε τον κωδικό πρόσβασης σας; Εγγραφή - Γίνεται σύνδεση… - Παρακαλούμε περιμένετε… + Γίνεται σύνδεση... + Παρακαλούμε αναμείνετε… Ενημέρωση λεζάντων και περιγραφών - Παρακαλούμε περιμένετε… + Παρακαλούμε αναμείνετε… Επιτυχής σύνδεση! Η είσοδος απέτυχε! - Το αρχείο δεν βρέθηκε. Παρακαλώ δοκιμάστε ένα άλλο αρχείο. - Συμπληρώθηκε το μέγιστο όριο επανάληψης! Ακυρώστε τη μεταφόρτωση και προσπαθήστε ξανά - Απενεργοποίηση βελτιστοποίησης μπαταρίας; - Η μεταφόρτωση περισσότερων από 3 εικόνων λειτουργεί πιο αξιόπιστα όταν η βελτιστοποίηση μπαταρίας είναι απενεργοποιημένη. Απενεργοποιήστε τη βελτιστοποίηση μπαταρίας για την εφαρμογή Commons από τις ρυθμίσεις για μια ομαλή εμπειρία μεταφόρτωσης. \n\nΠιθανά βήματα για να απενεργοποιήσετε τη βελτιστοποίηση μπαταρίας:\n\nΒήμα 1: Πατήστε στο κουμπί \"Ρυθμίσεις\" παρακάτω.\n\nΒήμα 2: Εναλλαγή από \"Μη βελτιστοποιημένη\" σε \"Σε όλες τις εφαρμογές\".\n\nΒήμα 3: Αναζήτηση για \"Commons\" ή \"fr.free.nrw.commons\".\n\nΒήμα 4: Πατήστε το και επιλέξτε \"Να μην γίνει βελτιστοποίηση\".\n\nΒήμα 5: Πατήστε \'Τέλος\'. - Απέτυχε ο έλεγχος ταυτότητας, παρακαλώ συνδεθείτε ξανά. - Η αποστολή ξεκίνησε! + Το αρχείο δε βρέθηκε. Παρακαλούμε δοκιμάστε άλλο αρχείο. + Συμπληρώθηκε το μέγιστο όριο επανάληψης! Παρακαλούμε ακυρώστε τη μεταφόρτωση και προσπαθήστε ξανά + Απενεργοποίηση της βελτιστοποίησης μπαταρίας; + Η μεταφόρτωση περισσότερων από 3 εικόνων λειτουργεί πιο αξιόπιστα όταν η βελτιστοποίηση μπαταρίας είναι απενεργοποιημένη. Παρακαλούμε απενεργοποιήστε τη βελτιστοποίηση μπαταρίας για την εφαρμογή Commons από τις ρυθμίσεις για μια ομαλή εμπειρία μεταφόρτωσης. \n\nΠιθανά βήματα για να απενεργοποιήσετε τη βελτιστοποίηση μπαταρίας:\n\nΒήμα 1: Πατήστε στο κουμπί «Ρυθμίσεις» παρακάτω.\n\nΒήμα 2: Εναλλάξτε από «Μη βελτιστοποιημένη» σε «Σε όλες τις εφαρμογές».\n\nΒήμα 3: Αναζητήστε το «Commons» ή «fr.free.nrw.commons».\n\nΒήμα 4: Πατήστε το και επιλέξτε «Να μη γίνει βελτιστοποίηση».\n\nΒήμα 5: Πατήστε «Τέλος». + Η ταυτοποίηση απέτυχε. Παρακαλούμε, συνδεθείτε ξανά. + Η μεταφόρτωση ξεκίνησε! Η μεταφόρτωση βρίσκεται σε ουρά (ενεργοποιημένη λειτουργία περιορισμένης σύνδεσης) - %1$s επιφορτώθηκε! - Πατήστε για να προβάλλετε την αποστολή + %1$s μεταφορτώθηκε! + Πατήστε για να δείτε τη μεταφόρτωσή σας Μεταφόρτωση αρχείου: %s - %1$s επιφορτώνεται - Ολοκλήρωση επιφόρτωσης %1$s - Απέτυχε η μεταφόρτωση του %1$s + %1$s μεταφορτώθηκε! + Ολοκληρώνεται η μεταφόρτωση %1$s + Η μεταφόρτωση του %1$s απέτυχε Η μεταφόρτωση %1$s τέθηκε σε παύση - Πατήστε για να δείτε + Πατήστε για προβολή Πατήστε για προβολή Οι Πρόσφατες Μεταφορτώσεις μου Στην ουρά Απέτυχε %1$d%% ολοκληρώθηκε - Επιφορτώνει… + Πραγματοποιείται μεταφόρτωση Από τη Συλλογή Τραβήξτε φωτογραφία Κοντά - Οι επιφορτώσεις μου + Οι μεταφορτώσεις μου Κοινοποίηση Προβολή σελίδας αρχείου Λεζάντα (Απαιτείται) - Παρακαλούμε προσθέστε περιγραφή για αυτό το αρχείο + Παρακαλούμε προσθέστε λεζάντα σε αυτό το αρχείο Περιγραφή Λεζάντα - Δεν είναι δυνατή η σύνδεση - αποτυχία του δικτύου - Πάρα πολλές ανεπιτυχείς προσπάθειες. Παρακαλώ δοκιμάστε ξανά σε λίγα λεπτά. - Συγνώμη, αυτός ο χρήστης έχει αποκλειστεί από τα Commons - Πρέπει να δώσετε τον κωδικό ελέγχου ταυτότητας δύο παραγόντων. - Η είσοδος απέτυχε - Ανέβασμα + Δεν είναι δυνατή η σύνδεση - αποτυχία δικτύου + Πάρα πολλές ανεπιτυχείς προσπάθειες. Παρακαλούμε, δοκιμάστε ξανά σε λίγα λεπτά. + Λυπούμαστε, αυτός ο χρήστης έχει αποκλειστεί στα Commons + Πρέπει να παράσχετε τον κωδικό ελέγχου ταυτότητας δύο παραγόντων. + Η είσοδος απέτυχε! + Μεταφόρτωση Ονομάστε το σύνολο Τροποποιήσεις - Ανέβασμα + Μεταφόρτωση Αναζήτηση κατηγοριών - Αναζητήστε αντικείμενα που απεικονίζουν τα μέσα σας (βουνό, Ταζ Μαχάλ κ.λπ.) + Αναζητήστε αντικείμενα που απεικονίζονται στα πολυμέσα σας (βουνό, Ταζ Μαχάλ κ.λπ.) Αποθήκευση Ανανέωση Κατάλογος (Καμία μεταφόρτωση ακόμα) - Δεν βρέθηκαν κατηγορίες που ταιριάζουν %1$s - Δεν βρέθηκαν στοιχεία Wikidata που να ταιριάζουν στο %1$s - Το %1$s δεν έχει κλάσεις παιδιά - %1$s δεν έχει κλάσεις γονείς - Προσθέστε κατηγορίες για να κάνετε τις εικόνες σας πιο ανιχνεύσιμες στα Wikimedia Commons.\n\nΑρχίστε να γράφετε για να προσθέσετε κατηγορίες.\nΠατήστε αυτό το μήνυμα (ή πατήστε επιστροφή) για να παραλείψετε αυτό το βήμα. + Δε βρέθηκαν κατηγορίες που ταιριάζουν με %1$s + Δε βρέθηκαν αντικείμενα Wikidata που να ταιριάζουν στο %1$s + Το %1$s δεν έχει θυγατρικές κλάσεις + Το %1$s δεν έχει γονικές κλάσεις + Προσθέστε κατηγορίες για να κάνετε τις εικόνες σας πιο ανιχνεύσιμες στο Wikimedia Commons.\nΞεκινήστε να πληκτρολογείτε για να προσθέσετε κατηγορίες. Κατηγορίες Ρυθμίσεις Εγγραφή Προβεβλημμένες εικόνες Προσαρμοσμένος Επιλογέας Κατηγορία - Αναθεώρηση από Ομότιμους + Αξιολόγηση από ομοτίμους Σχετικά - Λογισμικό ανοικτού κωδικού που κυκλοφορεί υπό την <a href=\"https://github.com/commons-app/apps-android-commons/blob/master/COPYING\">Άδεια Apache v2</a>. Το Wikimedia Commons και το λογότυπο είναι εμπορικά σήματα του Ιδρύματος Wikimedia και χρησιμοποιούνται με άδεια από το Ίδρυμα Wikimedia. Δεν συμμετέχουμε στην δημιουργία, ανάπτυξη ή συντήρηση του Ιδρύματος Wikimedia. - Δημιουργήστε ένα νέο <a href=\"%1$s\">GitHub θέμα</a> για αναφορές σφαλμάτων και προτάσεις. - Πολιτική ιδιωτικότητας + Η εφαρμογή Wikimedia Commons είναι μια ανοιχτού κώδικα εφαρμογή που δημιουργήθηκε και συντηρείται από χορηγούς και εθελοντές της κοινότητας του Ιδρύματος Wikimedia. Το Ίδρυμα Wikimedia δεν εμπλέκεται στη δημιουργία, ανάπτυξη ή συντήρηση της εφαρμογής. + Δημιουργήστε ένα νέο <a href=\"%1$s\">θέμα GitHub</a> για αναφορές σφαλμάτων και προτάσεις. + Πολιτική απορρήτου <u>Συντελεστές</u> Σχετικά - Αποστολή σχολίων (μέσω Email) + Αποστολή σχολίων (μέσω e-mail) Δεν υπάρχει εγκατεστημένη εφαρμογή ηλεκτρονικού ταχυδρομείου Κατηγορίες που χρησιμοποιήθηκαν πρόσφατα Αναμονή για τον πρώτο συγχρονισμό… - Ακόμα δεν έχετε ανεβάσει φωτογραφίες. - Ξαναπροσπαθήστε + Δεν έχετε ανεβάσει φωτογραφίες ακόμη. + Προσπαθήστε πάλι Ακύρωση - Αποστέλλοντας αυτήν την εικόνα, δηλώνω πως αυτή η εργασία είναι δική μου, και δεν περιέχει υλικό άλλου συγγραφέα, και εκτός αυτού πρόσκειται στο , thathref=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\">Κοινές πολιτικές της Wikipedia</a>. + Υποβάλλοντας αυτή τη φωτογραφία, δηλώνω ότι πρόκειται για δικό μου έργο, ότι δεν περιέχει υλικό που προστατεύεται από πνευματικά δικαιώματα ή selfies, και ότι κατά τα λοιπά συμμορφώνεται με τις <a href=\"https://commons.wikimedia.org/wiki/Commons:Policies_and_guidelines\">πολιτικές των Wikimedia Commons</a>. Λήψη Προεπιλεγμένη άδεια Χρήση προηγούμενου τίτλου και περιγραφής Θέμα - Attribution-ShareAlike 4.0 - Attribution 4.0 - Attribution-ShareAlike 3.0 - Attribution 3.0 + Αναφορά-Παρόμοια Διανομή 4.0 + Αναφορά 4.0 + Αναφορά-Παρόμοια Διανομή 4.0 3.0 + Αναφορά 3.0 CC0 CC BY-SA 3.0 CC BY 3.0 CC BY-SA 4.0 CC BY 4.0 - Το Wikimedia Commons φιλοξενεί τις περισσότερες από τις εικόνες που χρησιμοποιούνται στη Wikipedia. - Οι εικόνες σας βοηθούν να μορφωθούν άνθρωποι σε όλο τον κόσμο! - Παρακαλούμε ανεβάστε εικόνες που έχουν ληφθεί ή δημιουργηθεί εξ ολοκλήρου από τον εαυτό σας: + Τα Wikimedia Commons φιλοξενούν τις περισσότερες από τις εικόνες που χρησιμοποιούνται στη Βικιπαίδεια. + Οι εικόνες σας βοηθούν στην εκπαίδευση των ανθρώπων σε όλο τον κόσμο! + Παρακαλούμε μεταφορτώστε φωτογραφίες που έχουν ληφθεί ή δημιουργηθεί εξ ολοκλήρου από εσάς: Φυσικά αντικείμενα (λουλούδια, ζώα, βουνά) Χρήσιμα αντικείμενα (ποδήλατα, σταθμοί τρένων) - Διάσημοι άνθρωποι (ο δήμαρχος, αθλητές Ολυμπιακών αγώνων που συναντήσατε) - Παρακαλούμε ΜΗΝ ανεβάσετε: + Διασημότητες (ο δήμαρχος σας, αθλητές Ολυμπιακών Αγώνων που συναντήσατε) + Παρακαλούμε ΜΗΝ μεταφορτώνετε: Σέλφι ή φωτογραφίες των φίλων σας - Φωτογραφίες που κατεβάσατε από το διαδίκτυο - Στιγμιότυπα ιδιόκτητων εφαρμογών - Παράδειγμα ανεβάσματος: - Τίτλος: Όπερα του Σίδνεϋ - Περιγραφή: Η Όπερα του Σίδνεϋ όπως φαίνεται κατά μήκος του κόλπου - Κατηγορία: η Όπερα του Σίδνεϋ από τα δυτικά, απομακρυσμένες προβολές της Όπερας του Σίδνεϋ - Συνεισφέρετε τις εικόνες σας. Βοηθείστε τα λήμματα της Wikipedia να έρθουν στη ζωή! - Οι εικόνες στη Wikipedia προέρχονται από το Wikimedia Commons. - Οι εικόνες σας βοηθούν να εκπαιδευτούν άνθρωποι σε όλο τον κόσμο. - Αποφύγετε προστατευμένο υλικό που βρήκατε από το Internet, καθώς και εικόνες, αφίσες, εξώφυλλα βιβλίων, κλπ. - Τι λες, μπορείς; + Φωτογραφίες που κατεβάσατε από το Διαδίκτυο + Στιγμιότυπα οθόνης ιδιόκτητων εφαρμογών + Παράδειγμα μεταφόρτωσης: + Τίτλος: Όπερα του Σίδνεϊ + Περιγραφή: Όπερα του Σίδνεϊ όπως φαίνεται κατά μήκος του κόλπου + Κατηγορίες: Sydney Opera House from the west, Sydney Opera House remote views + Συνεισφέρετε τις εικόνες σας. Βοηθήστε τα λήμματα της Βικιπαίδειας να ζωντανέψουν! + Οι εικόνες στη Βικιπαίδεια προέρχονται από τα Wikimedia Commons. + Οι εικόνες σας βοηθούν στην εκπαίδευση ανθρώπων σε όλο τον κόσμο! + Αποφύγετε υλικό που προστατεύεται από πνευματικά δικαιώματα και βρήκατε από το Διαδίκτυο, καθώς και εικόνες αφισών, εξώφυλλων βιβλίων κ.λπ.. + Νομίζεις ότι το έχεις; Ναι! - Περισσότερες Πληροφορίες + Περισσότερες πληροφορίες Κατηγορίες - Φόρτωση… + Φόρτωση σε εξέλιξη... Καμία επιλεγμένη - Καμία λεζάντα - Καμία περιγραφή + Χωρίς λεζάντα + Χωρίς περιγραφή Καμία συζήτηση Άγνωστη άδεια Ανανέωση - Αιτείται Άδεια Αποθήκευσης - Απαιτούμενη άδεια: Ανάγνωση εξωτερικής αποθήκευσης. Η εφαρμογή δεν μπορεί να έχει πρόσβαση στην συλλογή σας χωρίς αυτή. - Απαιτούμενη άδεια: Εγγραφή σε εξωτερική αποθήκευση. Το πρόγραμμα δεν θα έχει πρόσβαση στην κάμερα/συλλογή σας χωρίς αυτήν. - Αιτείται Άδεια Τοποθεσίας + Αίτηση για άδεια αποθήκευσης + Απαιτούμενη άδεια: Ανάγνωση εξωτερικής αποθήκευσης. Η εφαρμογή δεν μπορεί να έχει πρόσβαση στη συλλογή σας χωρίς αυτή. + Απαιτούμενη άδεια: Εγγραφή σε εξωτερική αποθήκευση. Η εφαρμογή δε θα έχει πρόσβαση στην κάμερα/συλλογή σας χωρίς αυτήν. + Αίτηση για άδεια τοποθεσίας Καταγραφή τοποθεσίας για λήψεις εντός εφαρμογής Ενεργοποιήστε το για να καταγράψετε την τοποθεσία με λήψεις εντός εφαρμογής σε περίπτωση που η κάμερα της συσκευής δεν την καταγράψει Εντάξει @@ -233,24 +234,24 @@ Συντεταγμένες Δεν δόθηκε τίποτα Γίνετε Δοκιμαστής Beta - Συμμετέχετε στο κανάλι beta μας στο Google Play και αποκτήστε πρώιμη πρόσβαση σε νέες λειτουργίες και διορθώσεις σφαλμάτων + Συμμετέχετε στο κανάλι beta στο Google Play και αποκτήστε πρώιμη πρόσβαση σε νέες λειτουργίες και διορθώσεις σφαλμάτων Κωδικός 2FA Θέλετε σίγουρα να αποσυνδεθείτε; - Η Εικόνα των Μέσων Απέτυχε (δεν μπορεί να φορτωθεί) - Δεν βρέθηκαν υποκατηγορίες - Δεν βρέθηκαν γονικές κατηγορίες + Η εικόνα πολυμέσων απέτυχε + Δε βρέθηκαν υποκατηγορίες + Δε βρέθηκαν γονικές κατηγορίες Όρος Ζάο - Llamas - Γέφυρα Ουρανίου Τόξου + Λάμα + Γέφυρα Ρέινμποου Τουλίπα Καλωσήρθατε στη Βικιπαίδεια - Καλωσορίστε το Δικαίωμα Αντιγραφής - Κτίρια Όπερας Sidney - Ακυρώστε - Ανοίξτε - Κλείστε - Αρχική Σελίδα - Ανέβασμα αρχείου + Καλώς ορίσατε στα Πνευματικά δικαιώματα + Όπερα του Σίδνεϊ + Ακύρωση + Άνοιγμα + Κλείσιμο + Αρχική σελίδα + Μεταφόρτωση αρχείου Κοντά σας Σχετικά Ρυθμίσεις @@ -258,135 +259,135 @@ Ανατροφοδότηση μέσω Github Αποσύνδεση Σεμινάριο - Ενημερώσεις - Επιθεώρηση - δεν βρέθηκε περιγραφή - Σελίδα αρχείου Commons + Ειδοποιήσεις + Έλεγχος + δε βρέθηκε περιγραφή + Σελίδα αρχείου στα Commons Αντικείμενο Wikidata Λήμμα Βικιπαίδειας - Παρακαλώ περιγράψετε τα μέσα όσο το δυνατόν περισσότερο : Πού λήφθηκε; Τι δείχνει; Ποιο είναι το περιεχόμενο του; Παρακαλώ περιγράψετε τα αντικείμενα ή τα πρόσωπα. Αποκαλύψετε πληροφορίες που δεν είναι εύκολο να μαντέψει κανείς, για παράδειγμα την ώρα εντός της ημέρας αν πρόκειται για τοπίο. Αν τα μέσα δείξουν κάτι ασύνηθες, παρακαλώ εξηγήστε τι το καθιστούν μη συνηθισμένα. - Γράψτε μια σύντομη περιγραφή της εικόνας. Η πρώτη λεζάντα θα χρησιμοποιηθεί ως τίτλος για την εικόνα. Όριο 255 χαρακτήρες. + Παρακαλούμε, περιγράψετε τα πολυμέσα όσο το δυνατόν περισσότερο: Πού λήφθηκε; Τι απεικονίζει; Ποιο είναι το περιεχόμενο του; Παρακαλούμε, περιγράψετε τα αντικείμενα ή τα πρόσωπα. Δώστε πληροφορίες που δεν είναι εύκολο να μαντέψει κανείς, για παράδειγμα την ώρα εντός της ημέρας αν πρόκειται για τοπίο. Αν τα πολυμέσα δείχνουν κάτι ασυνήθιστο, παρακαλούμε εξηγήστε τι το χαρακτηρίζει ως τέτοιο. + Παρακαλούμε να γράψετε μια σύντομη περιγραφή της εικόνας. Η πρώτη λεζάντα θα χρησιμοποιηθεί ως τίτλος για την εικόνα. Περιοριστείτε σε 255 χαρακτήρες. Πιθανά προβλήματα με αυτήν την εικόνα: Η εικόνα είναι πολύ σκοτεινή. Η εικόνα είναι θολή. - Η εικόνα βρίσκεται ήδη στα Commons. + Η εικόνα είναι ήδη στα Commons. Η εικόνα λήφθηκε σε διαφορετική τοποθεσία. - Ανεβάστε μόνο φωτογραφίες που έχετε τραβήξει μόνοι σας. Μην ανεβάζετε φωτογραφίες που έχετε βρει σε λογαριασμούς άλλων ατόμων στο Facebook. - Θέλετε ακόμη να ανεβάσετε αυτή την εικόνα; - Σφάλμα Σύνδεσης + Παρακαλούμε ανεβάστε μόνο φωτογραφίες που έχετε τραβήξει μόνοι σας. Μην ανεβάζετε φωτογραφίες που έχετε βρει σε λογαριασμούς άλλων ατόμων στο Facebook. + Θέλετε ακόμα να ανεβάσετε αυτήν την φωτογραφία; + Σφάλμα σύνδεσης Η διαδικασία μεταφόρτωσης απαιτεί ενεργή πρόσβαση στο Διαδίκτυο. Ελέγξτε τη σύνδεσή σας στο δίκτυο. Βρέθηκαν προβλήματα στην εικόνα - Ανεβάστε μόνο φωτογραφίες που έχετε τραβήξει μόνοι σας. Μην ανεβάζετε φωτογραφίες που έχετε κατεβάσει από το Διαδίκτυο. + Παρακαλούμε ανεβάστε μόνο φωτογραφίες που έχετε τραβήξει μόνοι σας. Μην ανεβάζετε φωτογραφίες που έχετε κατεβάσει από το Διαδίκτυο. Αποθηκεύστε φωτογραφίες εντός εφαρμογής Αποθηκεύστε φωτογραφίες που τραβήξατε με την κάμερα εντός εφαρμογής στο χώρο αποθήκευσης της συσκευής σας - Συνδεθείτε στο λογαριασμό σας. + Συνδεθείτε στον λογαριασμό σας. Αποστολή αρχείου καταγραφής - Στείλτε το αρχείο καταγραφής στους προγραμματιστές μέσω email για να βοηθήσετε τη διόρθωση σφαλμάτων της εφαρμογής. Σημείωση: οι καταγραφές ενδέχεται να περιλαμβάνουν αναγνωριστικές πληροφορίες - Δεν βρέθηκε φυλλομετρητής για το άνοιγμα της διευθύνσεως URL - Σφάλμα! Η διεύθυνση URL δεν βρέθηκε + Στείλτε το αρχείο καταγραφής στους προγραμματιστές μέσω email για να βοηθήσετε τη διόρθωση σφαλμάτων της εφαρμογής. Σημείωση: οι καταγραφές ενδέχεται να περιλαμβάνουν πληροφορίες ταυτοποίησης + Δε βρέθηκε πρόγραμμα περιήγησης ιστού για το άνοιγμα της διεύθυνσης URL + Σφάλμα! Η διεύθυνση URL δε βρέθηκε Προτείνετε για διαγραφή - Αυτή εικόνα έχει προταθεί για διαγραφή. + Αυτή η εικόνα έχει προταθεί για διαγραφή. Δείτε την ιστοσελίδα για λεπτομέρειες Παράβλεψη Είσοδος Θέλετε πραγματικά να παραβλέψετε τη σύνδεση; - Θα χρειάζεται να συνδεθείτε για να ανεβάζετε εικόνες στο μέλλον. - Παρακαλούμε συνδεθείτε για να χρησιμοποιήσετε αυτό το χαρακτηριστικό + Θα χρειαστεί να συνδεθείτε για να μεταφορτώσετε φωτογραφίες στο μέλλον. + Παρακαλούμε να συνδεθείτε για να χρησιμοποιήσετε αυτή τη λειτουργία Αντιγράψτε το wikitext στο πρόχειρο Το wikitext αντιγράφηκε στο πρόχειρο - Ο τόπος δεν είναι διαθέσιμος. + Η λειτουργία «Κοντά σας» ενδέχεται να μη δουλεύει σωστά, η Τοποθεσία δεν είναι διαθέσιμη. Δεν επιτρέπεται η πρόσβαση στην τοποθεσία. Ρυθμίστε την τοποθεσία σας με χειροκίνητο τρόπο για να χρησιμοποιήσετε αυτήν τη δυνατότητα. - Απαιτείται άδεια για την εμφάνιση λίστας κοντινών σημείων - Απαιτείται άδεια για την εμφάνιση λίστας κοντινών εικόνων - Κατευθύνσεις - Δεδομένα wiki + Απαιτείται άδεια για την εμφάνιση καταλόγου κοντινών σημείων + Απαιτείται άδεια για την εμφάνιση καταλόγου κοντινών εικόνων + Οδηγίες + Wikidata Βικιπαίδεια - Κοινά + Commons Βαθμολογήστε μας Συχνές ερωτήσεις Οδηγός χρήστη - Παράβλεψη εισαγωγής + Παράλειψη εκμάθησης Το διαδίκτυο δεν είναι διαθέσιμο - Σφάλμα κατά την συγκέντρωση ειδοποιήσεων - Σφάλμα κατά την ανάκτηση της εικόνας για έλεγχο. Πατήστε το refresh για να προσπαθήσετε ξανά. - Δεν βρέθηκαν ειδοποιήσεις + Σφάλμα κατά την ανάκτηση ειδοποιήσεων + Σφάλμα κατά την ανάκτηση της εικόνας για έλεγχο. Ανανεώστε για να προσπαθήσετε ξανά. + Δε βρέθηκαν ειδοποιήσεις Μετάφραση Γλώσσες - Επιλέξτε την γλώσσα που θα θέλατε να υποβάλετε μεταφράσεις για αυτή + Επιλέξτε τη γλώσσα για την οποία θέλετε να υποβάλετε μεταφράσεις Συνέχεια Ακύρωση - Ξαναπροσπαθήστε - Αυτά είναι τα μέρη κοντά σας που χρειάζονται φωτογραφίες για να εικονογραφηθούν τα λήμματά τους στη Βικιπαίδεια.\n\nΚάνοντας κλικ στην \"ΑΝΑΖΗΤΗΣΗ ΣΕ ΑΥΤΉ ΤΗΝ ΠΕΡΙΟΧΗ\" κλειδώνει ο χάρτης και ξεκινά μια κοντινή αναζήτηση γύρω από αυτή την τοποθεσία. - Αυτή η τοποθεσία χρειάζεται φωτογραφία. - Αυτή η τοποθεσία έχει ήδη φωτογραφία. - Η τοποθεσία δεν υπάρχει πλέον. - Δεν βρέθηκαν εικόνες! - Συνέβη σφάλμα κατά το ανέβασμα των εικόνων. - Ανέβηκε από: %1$s + Επανάληψη + Αυτά είναι τα μέρη κοντά σας που χρειάζονται φωτογραφίες για να εικονογραφηθούν τα λήμματά τους στη Βικιπαίδεια.\n\nΚάνοντας κλικ στην «ΑΝΑΖΗΤΗΣΗ ΣΕ ΑΥΤΗ ΤΗΝ ΠΕΡΙΟΧΗ» κλειδώνει ο χάρτης και ξεκινά μια κοντινή αναζήτηση γύρω από αυτή την τοποθεσία. + Αυτό το μέρος χρειάζεται μια φωτογραφία. + Αυτό το μέρος έχει ήδη μια φωτογραφία. + Αυτό το μέρος δεν υπάρχει πλέον. + Δε βρέθηκαν εικόνες! + Παρουσιάστηκε σφάλμα κατά τη φόρτωση των εικόνων. + Μεταφορτώθηκε από: %1$s Αποκλεισμένος - Είστε αποκλεισμένοι από την επεξεργασία των Κοινών - Φωτογραφία της Ημέρας + Έχετε αποκλειστεί από την επεξεργασία στα Commons + Φωτογραφία της ημέρας Αναζήτηση - Αναζήτηση στα κοινά + Αναζήτηση στα Commons Αναζήτηση Πρόσφατες αναζητήσεις: - Πρόσφατα αναζητημένα ερωτήματα + Ερωτήματα που αναζητήθηκαν πρόσφατα Πρόσφατα ερωτήματα γλώσσας - Συνέβη σφάλμα κατά τη φόρτωση κατηγοριών. + Παρουσιάστηκε σφάλμα κατά τη φόρτωση κατηγοριών. Παρουσιάστηκε σφάλμα κατά τη φόρτωση των απεικονίσεων. - Μέσα + Πολυμέσα Κατηγορίες Αντικείμενα Χαρακτηριστικά Μεταφορτώθηκε μέσω κινητού Χάρτης - Η εικόνα προστέθηκε επιτυχώς στο %1$s στο Wikidata! - Αποτυχία ενημέρωσης της αντιστοιχούσας οντότητας του Wikidata! - Ρύθμιση ως ταπετσαρία + Η εικόνα προστέθηκε επιτυχώς στο %1$s στα Wikidata! + Αποτυχία ενημέρωσης της αντιστοιχούσας οντότητας των Wikidata! + Ορισμός ως ταπετσαρία Η ταπετσαρία ρυθμίστηκε επιτυχώς! Κουίζ - Αυτή η φωτογραφία είναι εντάξει για ανέβασμα; + Είναι εντάξει αυτή η εικόνα για μεταφόρτωση; Ερώτηση Αποτέλεσμα - Εάν συνεχίζετε να ανεβάζετε εικόνες που απαιτούν διαγραφή, ο λογαριασμός σας πιθανώς θα φραγεί. Είστε σίγουρος ότι θέλετε να τελειώστε το κουίζ; - Πάνω από το %1$s των εικόνων που ανεβάσατε έχουν διαγραφεί. Εάν συνεχίσετε να ανεβάζετε εικόνες που απαιτούν διαγραφή, ο λογαριασμός σας πιθανώς θα φραγεί. \n\nΘα θέλατε να ξαναδείτε τον οδηγό νέων χρηστών ξανά και να κάνετε ένα κουίζ για να σας βοηθήσει να μάθετε ποιοι τύποι εικόνων πρέπει ή δεν πρέπει να ανεβάζετε; - Οι σέλφι δεν έχουν πολύ εγκυκλοπαιδική αξία. Παρακαλώ μην ανεβάζετε φωτογραφία του εαυτού σας εκτός εάν έχετε ένα λήμμα στη Βικιπαίδεια για εσάς. - Οι φωτογραφίες μνημείων και εξωτερικού σκηνικού είναι εντάξει για ανέβασμα στις περισσότερες χώρες. Παρακαλώ σημειώστε ότι οι προσωρινές εγκαταστάσεις τέχνες καλύπτονται συχνά από πνευματικά δικαιώματα και δεν είναι εντάξει για ανέβασμα. - Τα στιγμιότυπα ιστοσελίδων θεωρούνται παράγωγα έργα και υποκείμενα σε οποιαδήποτε πνευματικά δικαιώματα στην ίδια την ιστοσελίδα. Αυτές μπορούν να χρησιμοποιηθούν μετά από άδεια από τον συγγραφέα. Χωρίς τέτοια άδεια, οποιαδήποτε τέχνη που δημιουργείτε βασισμένη στο έργο τους θεωρείται νομικά ως μη αδειοδοτημένο έργο κατεχόμενο από τον αρχικό συγγραφέα. - Ένας από τους στόχους των Κοινών είναι να συγκεντρώσει ποιοτικές εικόνες. Γι\'αυτό, οι θολές εικόνες δεν θα πρέπει να ανεβάζονται. Πάντα προσπαθήστε να τραβάτε ωραίες φωτογραφίες με καλό φωτισμό. - Οι φωτογραφίες που εμφανίζουν τεχνολογία ή πολιτισμό είναι πολύ ευσπρόδεκτες στα Κοινά. + Εάν συνεχίσετε να ανεβάζετε εικόνες που απαιτούν διαγραφή, ο λογαριασμός σας πιθανότατα θα αποκλειστεί. Είστε βέβαιοι ότι θέλετε να τερματίσετε το κουίζ; + Περισσότερες από %1$s από τις εικόνες που ανεβάσατε έχουν διαγραφεί. Εάν συνεχίσετε να ανεβάζετε εικόνες που απαιτούν διαγραφή, ο λογαριασμός σας πιθανότατα θα αποκλειστεί.\n\nΘα θέλατε να δείτε ξανά το σεμινάριο και μετά να κάνετε ένα κουίζ για να σας βοηθήσει να μάθετε τι είδους εικόνες πρέπει ή όχι να ανεβάσετε; + Οι σέλφι δεν έχουν μεγάλη εγκυκλοπαιδική αξία. Παρακαλούμε μην ανεβάζετε φωτογραφία του εαυτού σας εκτός εάν έχετε ένα λήμμα στη Βικιπαίδεια για εσάς. + Οι φωτογραφίες μνημείων και εξωτερικών τοπίων είναι εντάξει για μεταφόρτωση στις περισσότερες χώρες. Λάβετε υπόψη ότι οι προσωρινές εξωτερικές εγκαταστάσεις τέχνης συχνά προστατεύονται από πνευματικά δικαιώματα και δεν επιτρέπεται η μεταφόρτωση. + Τα στιγμιότυπα οθόνης των ιστότοπων θεωρούνται παράγωγα έργα και υπόκεινται σε τυχόν πνευματικά δικαιώματα στον ίδιο τον ιστότοπο. Αυτά μπορούν να χρησιμοποιηθούν μετά από άδεια του δημιουργού. Χωρίς αυτή την άδεια, κάθε έργο τέχνης που δημιουργείτε με βάση το έργο τους θεωρείται νομικά ως αντίγραφο χωρίς άδεια που ανήκει στον αρχικό δημιουργό. + Ένας από τους στόχους των Commons είναι να συγκεντρώσει ποιοτικές εικόνες. Γι\' αυτό, οι θολές εικόνες δε θα πρέπει να μεταφορτώνονται. Πάντα προσπαθήστε να τραβάτε περιποιημένες φωτογραφίες με καλό φωτισμό. + Οι φωτογραφίες που εμφανίζουν τεχνολογία ή πολιτισμό είναι πολύ ευσπρόδεκτες στα Commons. Είχατε το %1$s των απαντήσεων σωστό. Συγχαρητήρια! Επιλέξτε μια από τις δύο επιλογές για να απαντήσετε στην ερώτηση - Η περίοδος σύνδεσης έληξε, παρακαλούμε συνδεθείτε ξανά. + Η περίοδος σύνδεσης έληξε. Παρακαλούμε συνδεθείτε ξανά. Μοιραστείτε το κουίζ με τους φίλους σας! Συνέχεια Σωστή απάντηση - Λάθος απάντηση - Αυτό το στιγμιότυπο είναι εντάξει για ανέβασμα; + Λανθασμένη απάντηση + Είναι εντάξει αυτό το στιγμιότυπο οθόνης για μεταφόρτωση; Κοινοποίηση εφαρμογής - Γυρίστε + Περιστροφή Σφάλμα κατά την εύρεση κοντινών μερών. Δεν υπάρχουν φωτογραφίες σε αυτήν την περιοχή - Δεν υπάρχουν μέρη κοντά + Δεν υπάρχουν μέρη κοντά σας Σφάλμα κατά την εύρεση κοντινών μνημείων. Καμία πρόσφατη αναζήτηση Είστε σίγουρος ότι θέλετε να καθαρίσετε το ιστορικό αναζήτησης; - Είστε σίγουροι ότι θέλετε να ακυρώσετε αυτό το ανέβασμα; + Θέλετε σίγουρα να ακυρώσετε τη μεταφόρτωση; Θέλετε να διαγράψετε αυτήν την αναζήτηση; Το ιστορικό αναζήτησης διεγράφη - Ορίστε για Αφαίρεση + Πρόταση για διαγραφή Διαγραφή - Κατορθώματα + Επιτεύγματα Προφίλ Στατιστικά - Ευχαριστίες που έχουν ληφθεί + Ευχαριστίες που έχετε λάβει Προβεβλημμένες εικόνες - Εικόνες μέσω \"Κοντινά μέρη\" + Εικόνες μέσω «Κοντινά μέρη» Επίπεδο - Εικόνες που ανέβηκαν + Εικόνες που μεταφορτώθηκαν Εικόνες που δεν ανεστράφησαν Εικόνες που χρησιμοποιήθηκαν - Μοιραστείτε τα κατορθώματά σας με τους φίλους σας! + Μοιραστείτε τα επιτεύγματά σας με τους φίλους σας! Το επίπεδό σας αυξάνεται όσο πληρείτε αυτές στις απαιτήσεις. Τα αντικείμενα στο τμήμα \"Στατιστικά\" δεν μετρούν στο επίπεδό σας. ελάχιστο που απαιτείται: Ο αριθμός εικόνων που ανεβάσατε στα Κοινά, μέσω οποιουδήποτε λογισμικού ανεβάσματος @@ -708,7 +709,7 @@ Οι κοντινοί χάρτες πρέπει να διαβάζουν PHONE STATE για να λειτουργούν σωστά Συνεισφορές χρήστη: %s Επιτεύγματα χρήστη: %s - Προβολή σελίδας χρήστη + Προβολή σελίδας χρήστη Επεξεργασία απεικονίσεων Επεξεργασία κατηγοριών Σύνθετες Επιλογές @@ -788,4 +789,13 @@ Να θυμάστε ότι όλες οι εικόνες σε μια πολλαπλή μεταφόρτωση έχουν τις ίδιες κατηγορίες και απεικονίσεις. Εάν οι εικόνες δεν μοιράζονται απεικονίσεις και κατηγορίες, πραγματοποιήστε πολλές ξεχωριστές μεταφορτώσεις. Σημείωση για τις πολλαπλές μεταφορτώσεις + Αναφορά προβλήματος σχετικά με αυτό το αντικείμενο των Wikidata + Παρακαλώ εισάγετε κάποια σχόλια + Συζήτηση + Γράψτε κάτι για το αντικείμενο \'%1$s\'. Θα είναι δημόσια ορατό. + Το \'%1$s\' δεν υφίσταται πλέον, καμία φωτογραφία δεν μπορεί να εξαχθεί. + Το \'%1$s\' βρίσκεται σε διαφορετική θέση. Παρακαλούμε προσδιορίστε τη σωστή θέση παρακαλώ, και αν είναι εφικτό, γράψτε το σωστό γεωγραφικό πλάτος και μήκος. + Άλλο πρόβλημα ή πληροφορίες (παρακαλούμε εξηγήστε παρακάτω). + Τα σχόλιά σας δημοσιεύονται στην ακόλουθη σελίδα wiki: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Εφαρμογή για κινητά/Σχόλια</a> + Δεν ήταν δυνατή η φόρτωση δεδομένων της θέσης diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 1a98091e1..072882852 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -116,6 +116,7 @@ Nie znaleziono pliku. Spróbuj znaleźć inny. Osiągnięto maksymalny limit ponownych prób! Anuluj przesyłanie i spróbuj ponownie Wyłączyć optymalizację baterii? + Przesyłanie więcej niż 3 obrazów działa bardziej niezawodnie, gdy optymalizacja baterii jest wyłączona. Wyłącz optymalizację baterii dla aplikacji Commons w ustawieniach, aby zapewnić płynne przesyłanie. \n\nMożliwe kroki, aby wyłączyć optymalizację baterii:\n\nKrok 1: Stuknij przycisk „Ustawienia” poniżej.\n\nKrok 2: Przełącz z „Niezoptymalizowane” na „Wszystkie aplikacje”.\n\nKrok 3: Wyszukaj „Commons” lub „fr.free.nrw.commons”.\n\nKrok 4: Stuknij i wybierz „Nie optymalizuj”.\n\nKrok 5: Naciśnij „Gotowe”. Uwierzytelnianie nie powiodło się, zaloguj się ponownie, proszę. Wysyłanie rozpoczęte! Prześlij w kolejce (włączony tryb ograniczonego połączenia) @@ -306,7 +307,7 @@ Pomiń Zaloguj się Czy na pewno chcesz pominąć logowanie? - Musisz się zalogować, aby przesłać zdjęcia w przyszłości + Aby w przyszłości przesyłać zdjęcia, będziesz musiał się zalogować. Zaloguj się, aby skorzystać z tej funkcji Skopiuj wikitext do schowka Wikitext został skopiowany do schowka @@ -462,6 +463,7 @@ Kończy się na: Wyświetl kampanie Zobacz trwające kampanie + Zezwól aplikacji na pobieranie lokalizacji, jeśli kamera jej nie rejestruje. Niektóre kamery urządzeń nie rejestrują lokalizacji. W takich przypadkach pozwolenie aplikacji na pobieranie i dołączanie do niej lokalizacji sprawia, że Twój wkład jest bardziej użyteczny. Możesz to zmienić w dowolnym momencie w Ustawieniach Zezwól Odrzuć Upewnij się, że ten nowy selektor Androida nie usuwa lokalizacji ze zdjęć. @@ -770,6 +772,7 @@ Nie można udostępnić tego elementu Edytuj obraz Edytuj lokalizację + Lokalizacja zaktualizowana! Dziękuję autorowi Błąd wysyłania podziękowań do autora. Pomyślnie zapisano From ec4a6bc0c42801ee07d201a1b12d96b0c4bd50c3 Mon Sep 17 00:00:00 2001 From: Rohit Verma <101377978+rohit9625@users.noreply.github.com> Date: Tue, 27 Aug 2024 19:37:12 +0530 Subject: [PATCH 4/5] remove asynchronous call to fetch local depictedItems (#5792) --- .../upload/depicts/DepictsPresenter.kt | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt index cd0033e08..d236292d1 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt @@ -16,12 +16,9 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import io.reactivex.processors.PublishProcessor import io.reactivex.schedulers.Schedulers -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking import timber.log.Timber import java.lang.reflect.Proxy -import java.util.* import javax.inject.Inject import javax.inject.Named import javax.inject.Singleton @@ -88,7 +85,7 @@ class DepictsPresenter @Inject constructor( var recentDepictedItemList: MutableList = ArrayList(); //show recentDepictedItemList when queryString is empty if (querystring.isEmpty()) { - recentDepictedItemList = getRecentDepictedItems(); + recentDepictedItemList = getRecentDepictedItems().toMutableList() } if (media == null) { @@ -268,17 +265,9 @@ class DepictsPresenter @Inject constructor( /** * Get the depicts from DepictsRoomdataBase */ - fun getRecentDepictedItems(): MutableList { - val depictedItemList: MutableList = ArrayList() - CoroutineScope(Dispatchers.IO).launch { - val depictsList = depictsDao.depictsList().await() - - for (i in depictsList.indices) { - val depictedItem = depictsList[i].item - depictedItemList.add(depictedItem) - } - } - return depictedItemList + private fun getRecentDepictedItems(): List = runBlocking { + val depictsList = depictsDao.depictsList().await() + return@runBlocking depictsList.map { it.item } } } From 190135d36cd4d86906d38e1bf8c06a0613f81c04 Mon Sep 17 00:00:00 2001 From: Rohit Verma <101377978+rohit9625@users.noreply.github.com> Date: Wed, 28 Aug 2024 11:59:16 +0530 Subject: [PATCH 5/5] Fix failing tests for updateDepictsProperty method (#5795) * tests: fix failing testUpdateDepictsProperty * replace deprecated circular progress bar with material progress bar * refactor: update SettingsActivity to not use custom appCompatDeletegate It is required because that delegate is automatically handled in new libraries. --- app/build.gradle | 2 +- .../achievements/AchievementsFragment.java | 11 +-- .../nrw/commons/quiz/QuizResultActivity.java | 8 +- .../commons/settings/SettingsActivity.java | 10 +- .../nrw/commons/wikidata/WikiBaseClient.kt | 4 +- .../main/res/layout/activity_quiz_result.xml | 45 ++++++--- .../main/res/layout/fragment_achievements.xml | 96 +++++++++---------- .../wikidata/WikidataEditServiceTest.kt | 15 ++- 8 files changed, 107 insertions(+), 84 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 44834951b..c8124e42b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -47,7 +47,7 @@ dependencies { implementation 'com.jakewharton.timber:timber:4.7.1' implementation 'com.github.deano2390:MaterialShowcaseView:1.2.0' - implementation 'com.dinuscxj:circleprogressbar:1.1.1' + implementation "com.google.android.material:material:1.9.0" implementation 'com.karumi:dexter:5.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' diff --git a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java index 96a1cb9f9..2b6022fab 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java @@ -306,6 +306,7 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment { if (uploadCount==0){ setZeroAchievements(); }else { + binding.imagesUploadedProgressbar.setVisibility(View.VISIBLE); binding.imagesUploadedProgressbar.setProgress (100*uploadCount/levelInfo.getMaxUploadCount()); @@ -342,8 +343,8 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment { private void setImageRevertPercentage(int notRevertPercentage){ binding.imageRevertsProgressbar.setVisibility(View.VISIBLE); binding.imageRevertsProgressbar.setProgress(notRevertPercentage); - String revertPercentage = Integer.toString(notRevertPercentage); - binding.imageRevertsProgressbar.setProgressTextFormatPattern(revertPercentage + "%%"); + final String revertPercentage = Integer.toString(notRevertPercentage); + binding.tvRevertedImages.setText(revertPercentage + "%"); binding.imagesRevertLimitText.setText(getResources().getString(R.string.achievements_revert_limit_message)+ levelInfo.getMinNonRevertPercentage() + "%"); } @@ -357,10 +358,8 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment { binding.thanksReceived.setText(String.valueOf(achievements.getThanksReceived())); binding.imagesUsedByWikiProgressBar.setProgress (100 * achievements.getUniqueUsedImages() / levelInfo.getMaxUniqueImages()); - if(binding.tvWikiPb != null) { - binding.tvWikiPb.setText - (achievements.getUniqueUsedImages() + "/" + levelInfo.getMaxUniqueImages()); - } + binding.tvWikiPb.setText(achievements.getUniqueUsedImages() + "/" + + levelInfo.getMaxUniqueImages()); binding.imageFeatured.setText(String.valueOf(achievements.getFeaturedImages())); binding.qualityImages.setText(String.valueOf(achievements.getQualityImages())); String levelUpInfoString = getString(R.string.level).toUpperCase(); diff --git a/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.java b/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.java index 0b267a0fe..ec6d1070d 100644 --- a/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/quiz/QuizResultActivity.java @@ -65,10 +65,10 @@ public class QuizResultActivity extends AppCompatActivity { * @param score */ public void setScore(int score) { - int per = score * MULTIPLIER_TO_GET_PERCENTAGE; - binding.resultProgressBar.setProgress(per); - binding.resultProgressBar.setProgressTextFormatPattern(score +" / " + NUMBER_OF_QUESTIONS); - String message = getResources().getString(R.string.congratulatory_message_quiz,per + "%"); + final int scorePercent = score * MULTIPLIER_TO_GET_PERCENTAGE; + binding.resultProgressBar.setProgress(scorePercent); + binding.tvResultProgress.setText(score +" / " + NUMBER_OF_QUESTIONS); + final String message = getResources().getString(R.string.congratulatory_message_quiz,scorePercent + "%"); binding.congratulatoryMessage.setText(message); } diff --git a/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java b/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java index fd231597b..ff5024b32 100644 --- a/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/settings/SettingsActivity.java @@ -15,7 +15,7 @@ import fr.free.nrw.commons.theme.BaseActivity; public class SettingsActivity extends BaseActivity { private ActivitySettingsBinding binding; - private AppCompatDelegate settingsDelegate; +// private AppCompatDelegate settingsDelegate; /** * to be called when the activity starts * @param savedInstanceState the previously saved state @@ -39,10 +39,10 @@ public class SettingsActivity extends BaseActivity { @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); - if (settingsDelegate == null) { - settingsDelegate = AppCompatDelegate.create(this, null); - } - settingsDelegate.onPostCreate(savedInstanceState); +// if (settingsDelegate == null) { +// settingsDelegate = AppCompatDelegate.create(this, null); +// } +// settingsDelegate.onPostCreate(savedInstanceState); } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt b/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt index 70a976164..d34a564a2 100644 --- a/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt +++ b/app/src/main/java/fr/free/nrw/commons/wikidata/WikiBaseClient.kt @@ -47,9 +47,9 @@ class WikiBaseClient @Inject constructor( } } - fun postDeleteClaims(entityId: String, data: String): Observable { + fun postDeleteClaims(entityId: String, data: String?): Observable { return csrfToken().switchMap { editToken -> - wikiBaseInterface.postDeleteClaims(editToken, entityId, data) + wikiBaseInterface.postDeleteClaims(editToken, entityId, data!!) .map { response: MwPostResponse -> response.successVal == 1 } } } diff --git a/app/src/main/res/layout/activity_quiz_result.xml b/app/src/main/res/layout/activity_quiz_result.xml index a91105191..65db12902 100644 --- a/app/src/main/res/layout/activity_quiz_result.xml +++ b/app/src/main/res/layout/activity_quiz_result.xml @@ -41,20 +41,37 @@ android:textSize="32sp" android:layout_marginTop="@dimen/activity_margin_vertical" /> - + + + + + + + android:layout_marginEnd="32dp"> - + app:showAnimationBehavior="outward" + app:indicatorColor="@color/primaryColor" + app:indicatorSize="32dp" + app:trackThickness="@dimen/progressbar_stroke" + app:trackColor="#B7B6B6" + android:visibility="gone"/> - + android:layout_marginEnd="32dp"> + + + + + android:layout_marginEnd="32dp"> - + app:showAnimationBehavior="outward" + app:indicatorColor="@color/primaryColor" + app:indicatorSize="32dp" + app:trackThickness="@dimen/progressbar_stroke" + app:trackColor="#B7B6B6" + android:visibility="gone"/>