diff --git a/app/build.gradle b/app/build.gradle index c8124e42b..a9c0c498c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -51,6 +51,21 @@ dependencies { implementation 'com.karumi:dexter:5.0.0' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + // Jetpack Compose + def composeBom = platform('androidx.compose:compose-bom:2024.08.00') + + implementation "androidx.activity:activity-compose:1.9.1" + implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.8.4" + implementation (composeBom) + implementation "androidx.compose.runtime:runtime" + implementation "androidx.compose.ui:ui" + implementation "androidx.compose.ui:ui-graphics" + implementation "androidx.compose.ui:ui-tooling" + implementation "androidx.compose.foundation:foundation" + implementation "androidx.compose.foundation:foundation-layout" + implementation "androidx.compose.material3:material3" + androidTestImplementation(composeBom) + implementation "com.hannesdorfmann:adapterdelegates4-kotlin-dsl-viewbinding:$ADAPTER_DELEGATES_VERSION" implementation "com.hannesdorfmann:adapterdelegates4-pagination:$ADAPTER_DELEGATES_VERSION" implementation "androidx.paging:paging-runtime-ktx:$PAGING_VERSION" @@ -186,7 +201,7 @@ project.gradle.taskGraph.whenReady { } android { - compileSdkVersion 33 + compileSdkVersion 34 defaultConfig { //applicationId 'fr.free.nrw.commons' @@ -196,7 +211,7 @@ android { setProperty("archivesBaseName", "app-commons-v$versionName-" + getBranchName()) minSdkVersion 21 - targetSdkVersion 33 + targetSdkVersion 34 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunnerArguments clearPackageData: 'true' @@ -253,11 +268,12 @@ android { } } debug { - testCoverageEnabled true minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' testProguardFile 'test-proguard-rules.txt' versionNameSuffix "-debug-" + getBranchName() + enableUnitTestCoverage true + enableAndroidTestCoverage true } } @@ -354,13 +370,17 @@ android { targetCompatibility JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "11" } buildToolsVersion buildToolsVersion buildFeatures { viewBinding true + compose true + } + composeOptions { + kotlinCompilerExtensionVersion '1.3.2' } namespace 'fr.free.nrw.commons' lint { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 87e182cc3..6a47a4644 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,23 +3,29 @@ xmlns:tools="http://schemas.android.com/tools"> - + - + - - + + - + + + @@ -183,6 +189,10 @@ android:name="org.acra.sender.SenderService" android:exported="false" android:process=":acra" /> + + = VERSION_CODES.Q) { - PermissionUtils.checkPermissionsAndPerformAction( - this, - () -> { - }, - R.string.media_location_permission_denied, - R.string.add_location_manually, - permission.ACCESS_MEDIA_LOCATION); - } +// if (VERSION.SDK_INT >= VERSION_CODES.Q) { +// ActivityCompat.requestPermissions(this, +// new String[]{Manifest.permission.ACCESS_MEDIA_LOCATION}, 0); +// PermissionUtils.checkPermissionsAndPerformAction( +// this, +// () -> {}, +// R.string.media_location_permission_denied, +// R.string.add_location_manually, +// permission.ACCESS_MEDIA_LOCATION); +// } checkAndResumeStuckUploads(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/helper/OnSwipeTouchListener.kt b/app/src/main/java/fr/free/nrw/commons/customselector/helper/OnSwipeTouchListener.kt index f454a3af8..961d51158 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/helper/OnSwipeTouchListener.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/helper/OnSwipeTouchListener.kt @@ -40,14 +40,14 @@ open class OnSwipeTouchListener(context: Context?) : View.OnTouchListener { * Detects the gestures */ override fun onFling( - event1: MotionEvent, + event1: MotionEvent?, event2: MotionEvent, velocityX: Float, velocityY: Float ): Boolean { try { - val diffY: Float = event2.y - event1.y - val diffX: Float = event2.x - event1.x + val diffY: Float = event2.y - (event1?.y ?: event2.y) + val diffX: Float = event2.x - (event1?.x ?: event2.x) if (abs(diffX) > abs(diffY)) { if (abs(diffX) > SWIPE_THRESHOLD_WIDTH && abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/FolderAdapter.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/FolderAdapter.kt index 60d299491..abebc8944 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/FolderAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/FolderAdapter.kt @@ -62,13 +62,15 @@ class FolderAdapter( folder.images.removeAll(toBeRemoved) val count = folder.images.size - if(count == 0) { + if(count == 0 && folders.size > 0) { // Folder is empty, remove folder from the adapter. holder.itemView.post{ val updatePosition = folders.indexOf(folder) - folders.removeAt(updatePosition) - notifyItemRemoved(updatePosition) - notifyItemRangeChanged(updatePosition, folders.size) + if(updatePosition != -1) { + folders.removeAt(updatePosition) + notifyItemRemoved(updatePosition) + notifyItemRangeChanged(updatePosition, folders.size) + } } } else { val previewImage = folder.images[0] diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt index 47784153e..58f4c8385 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/adapter/ImageAdapter.kt @@ -122,7 +122,7 @@ class ImageAdapter( * Bind View holder, load image, selected view, click listeners. */ override fun onBindViewHolder(holder: ImageViewHolder, position: Int) { - + if(images.size == 0) { return } var image=images[position] holder.image.setImageDrawable (null) if (context.contentResolver.getType(image.uri) == null) { diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt index 7cf0229cb..bcb7446d8 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/CustomSelectorActivity.kt @@ -1,16 +1,49 @@ package fr.free.nrw.commons.customselector.ui.selector +import android.Manifest import android.app.Activity import android.app.Dialog import android.content.Intent import android.content.SharedPreferences +import android.content.pm.PackageManager +import android.os.Build import android.os.Bundle +import android.util.Log import android.view.View import android.view.Window import android.widget.Button import android.widget.ImageButton import android.widget.TextView +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedCard +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.colorResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.content.ContextCompat import androidx.lifecycle.ViewModelProvider import fr.free.nrw.commons.R import fr.free.nrw.commons.customselector.database.NotForUploadStatus @@ -24,10 +57,12 @@ import fr.free.nrw.commons.databinding.ActivityCustomSelectorBinding import fr.free.nrw.commons.databinding.CustomSelectorBottomLayoutBinding import fr.free.nrw.commons.databinding.CustomSelectorToolbarBinding import fr.free.nrw.commons.filepicker.Constants +import fr.free.nrw.commons.filepicker.FilePicker import fr.free.nrw.commons.media.ZoomableActivity import fr.free.nrw.commons.theme.BaseActivity import fr.free.nrw.commons.upload.FileUtilsWrapper import fr.free.nrw.commons.utils.CustomSelectorUtils +import fr.free.nrw.commons.utils.PermissionUtils import kotlinx.coroutines.* import java.io.File import java.lang.Integer.max @@ -114,14 +149,37 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL private var progressDialogText:String="" + private var showPartialAccessIndicator by mutableStateOf(false) + /** * onCreate Activity, sets theme, initialises the view model, setup view. */ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE && + ContextCompat.checkSelfPermission( + this, Manifest.permission.READ_MEDIA_IMAGES + ) == PackageManager.PERMISSION_DENIED + ) { + showPartialAccessIndicator = true + } + binding = ActivityCustomSelectorBinding.inflate(layoutInflater) toolbarBinding = CustomSelectorToolbarBinding.bind(binding.root) bottomSheetBinding = CustomSelectorBottomLayoutBinding.bind(binding.root) + binding.partialAccessIndicator.setContent { + PartialStorageAccessIndicator( + isVisible = showPartialAccessIndicator, + onManage = { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + requestPermissions(arrayOf(Manifest.permission.READ_MEDIA_IMAGES), 1) + } + }, + modifier = Modifier + .padding(vertical = 8.dp, horizontal = 4.dp) + .fillMaxWidth() + ) + } val view = binding.root setContentView(view) @@ -147,6 +205,24 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL } } + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array, + grantResults: IntArray + ) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + if(requestCode == 1 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + if(grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + showPartialAccessIndicator = false + } + } + } + + override fun onResume() { + super.onResume() + fetchData() + } + /** * When data will be send from full screen mode, it will be passed to fragment */ @@ -181,7 +257,6 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL supportFragmentManager.beginTransaction() .replace(R.id.fragment_container, FolderFragment.newInstance()) .commit() - fetchData() setUpToolbar() setUpBottomLayout() } @@ -498,3 +573,52 @@ class CustomSelectorActivity : BaseActivity(), FolderClickListener, ImageSelectL const val ITEM_ID: String = "ItemId" } } +@Composable +fun PartialStorageAccessIndicator( + isVisible: Boolean, + onManage: ()-> Unit, + modifier: Modifier = Modifier +) { + if(isVisible) { + OutlinedCard( + modifier = modifier, + colors = CardDefaults.cardColors( + containerColor = colorResource(R.color.primarySuperLightColor) + ), + border = BorderStroke(0.5.dp, color = colorResource(R.color.primaryColor)), + shape = RoundedCornerShape(8.dp) + ) { + Row(modifier = Modifier.padding(16.dp).fillMaxWidth()) { + Text( + text = "You've given access to a select number of photos", + modifier = Modifier.weight(1f) + ) + TextButton( + onClick = onManage, + modifier = Modifier.align(Alignment.Bottom), + colors = ButtonDefaults.buttonColors( + containerColor = colorResource(R.color.primaryColor) + ), + shape = RoundedCornerShape(8.dp) + ) { + Text( + text = "Manage", + style = MaterialTheme.typography.labelMedium, + color = colorResource(R.color.primaryTextColor) + ) + } + } + } + } +} + +@Preview +@Composable +fun PartialStorageAccessIndicatorPreview() { + Surface { + PartialStorageAccessIndicator(isVisible = true, onManage = {}, modifier = Modifier + .padding(vertical = 8.dp, horizontal = 4.dp) + .fillMaxWidth() + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt index 0f546e788..95f427f49 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/FolderFragment.kt @@ -116,11 +116,14 @@ class FolderFragment : CommonsDaggerSupportFragment() { private fun handleResult(result: Result) { if(result.status is CallbackStatus.SUCCESS){ val images = result.images - if(images.isNullOrEmpty()) - { + if(images.isEmpty()){ binding?.emptyText?.let { it.visibility = View.VISIBLE } + } else { + binding?.emptyText?.let { + it.visibility = View.GONE + } } folders = ImageHelper.folderListFromImages(result.images) folderAdapter.init(folders) diff --git a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt index 842531dd2..c5e5de4f6 100644 --- a/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/customselector/ui/selector/ImageFragment.kt @@ -39,6 +39,7 @@ import fr.free.nrw.commons.upload.FileUtilsWrapper import io.reactivex.schedulers.Schedulers import java.util.* import javax.inject.Inject +import kotlin.collections.ArrayList /** * Custom Selector Image Fragment. @@ -279,6 +280,8 @@ class ImageFragment : CommonsDaggerSupportFragment(), RefreshUIListener, PassDat } } } else { + filteredImages = ArrayList() + allImages = filteredImages binding?.emptyText?.let { it.visibility = View.VISIBLE } @@ -324,7 +327,7 @@ class ImageFragment : CommonsDaggerSupportFragment(), RefreshUIListener, PassDat .findFirstVisibleItemPosition() // Check for empty RecyclerView. - if (position != -1) { + if (position != -1 && filteredImages.size > 0) { context?.let { context -> context.getSharedPreferences( "CustomSelector", diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt index 19e0a91cd..3ff43aeac 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt @@ -2,24 +2,15 @@ package fr.free.nrw.commons.explore.media import android.content.Context import android.os.Bundle -import android.view.LayoutInflater import android.view.View -import android.view.ViewGroup import fr.free.nrw.commons.Media import fr.free.nrw.commons.R import fr.free.nrw.commons.category.CategoryImagesCallback -import fr.free.nrw.commons.databinding.FragmentSearchPaginatedBinding import fr.free.nrw.commons.explore.paging.BasePagingFragment import fr.free.nrw.commons.media.MediaDetailPagerFragment.MediaDetailProvider abstract class PageableMediaFragment : BasePagingFragment(), MediaDetailProvider { - /** - * ViewBinding - */ - private var _binding: FragmentSearchPaginatedBinding? = null - private val binding get() = _binding!! - override val pagedListAdapter by lazy { PagedMediaAdapter(categoryImagesCallback::onMediaClicked) } @@ -39,15 +30,6 @@ abstract class PageableMediaFragment : BasePagingFragment(), MediaDetailP } } - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - _binding = FragmentSearchPaginatedBinding.inflate(inflater, container, false) - return binding.root - } - private val simpleDataObserver = SimpleDataObserver { categoryImagesCallback.viewPagerNotifyDataSetChanged() } @@ -57,7 +39,6 @@ abstract class PageableMediaFragment : BasePagingFragment(), MediaDetailP } override fun onDestroyView() { - _binding = null super.onDestroyView() pagedListAdapter.unregisterAdapterDataObserver(simpleDataObserver) } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingFragment.kt index e61f0dc30..d4e8f0e8f 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingFragment.kt @@ -29,12 +29,19 @@ abstract class BasePagingFragment : CommonsDaggerSupportFragment(), private val mergeAdapter by lazy { MergeAdapter(pagedListAdapter, loadingAdapter) } private var searchResults: LiveData>? = null - private var binding : FragmentSearchPaginatedBinding? = null + protected lateinit var binding : FragmentSearchPaginatedBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentSearchPaginatedBinding.inflate(inflater, container, false) + return binding.root + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - val binding = FragmentSearchPaginatedBinding.bind(view) - this.binding = binding binding.paginatedSearchResultsList.apply { layoutManager = GridLayoutManager(context, if (isPortrait) 1 else 2) @@ -51,7 +58,7 @@ abstract class BasePagingFragment : CommonsDaggerSupportFragment(), */ override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) - binding!!.paginatedSearchResultsList.apply { + binding.paginatedSearchResultsList.apply { layoutManager = GridLayoutManager(context, if (isPortrait) 1 else 2) } } @@ -75,15 +82,15 @@ abstract class BasePagingFragment : CommonsDaggerSupportFragment(), } override fun hideInitialLoadProgress() { - binding!!.paginatedSearchInitialLoadProgress.visibility = GONE + binding.paginatedSearchInitialLoadProgress.visibility = GONE } override fun showInitialLoadInProgress() { - binding!!.paginatedSearchInitialLoadProgress.visibility = VISIBLE + binding.paginatedSearchInitialLoadProgress.visibility = VISIBLE } override fun showSnackbar() { - ViewUtil.showShortSnackbar(binding!!.paginatedSearchResultsList, errorTextId) + ViewUtil.showShortSnackbar(binding.paginatedSearchResultsList, errorTextId) } fun onQueryUpdated(query: String) { @@ -91,14 +98,14 @@ abstract class BasePagingFragment : CommonsDaggerSupportFragment(), } override fun showEmptyText(query: String) { - binding!!.contentNotFound.text = getEmptyText(query) - binding!!.contentNotFound.visibility = VISIBLE + binding.contentNotFound.text = getEmptyText(query) + binding.contentNotFound.visibility = VISIBLE } abstract fun getEmptyText(query: String): String override fun hideEmptyText() { - binding!!.contentNotFound.visibility = GONE + binding.contentNotFound.visibility = GONE } } diff --git a/app/src/main/java/fr/free/nrw/commons/feedback/FeedbackContentCreator.java b/app/src/main/java/fr/free/nrw/commons/feedback/FeedbackContentCreator.java index 839858b3e..1723da723 100644 --- a/app/src/main/java/fr/free/nrw/commons/feedback/FeedbackContentCreator.java +++ b/app/src/main/java/fr/free/nrw/commons/feedback/FeedbackContentCreator.java @@ -6,6 +6,9 @@ import fr.free.nrw.commons.auth.AccountUtil; import fr.free.nrw.commons.feedback.model.Feedback; import fr.free.nrw.commons.utils.LangCodeUtils; import java.util.Locale; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; /** * Creates a wikimedia recognizable format @@ -32,11 +35,19 @@ public class FeedbackContentCreator { /* * Construct the feedback section title */ + + //Get the UTC Date and Time and add it to the Title + final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.ENGLISH); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + final String UTC_FormattedDate = dateFormat.format(new Date()); + sectionTitleBuilder = new StringBuilder(); sectionTitleBuilder.append("Feedback from "); sectionTitleBuilder.append(AccountUtil.getUserName(context)); sectionTitleBuilder.append(" for version "); sectionTitleBuilder.append(feedback.getVersion()); + sectionTitleBuilder.append(" on "); + sectionTitleBuilder.append(UTC_FormattedDate); /* * Construct the feedback section text @@ -96,6 +107,7 @@ public class FeedbackContentCreator { } sectionTextBuilder.append("~~~~"); sectionTextBuilder.append("\n"); + } public String getSectionText() { diff --git a/app/src/main/java/fr/free/nrw/commons/notification/NotificationHelper.java b/app/src/main/java/fr/free/nrw/commons/notification/NotificationHelper.java index d4c08d7a5..b63d3a4c1 100644 --- a/app/src/main/java/fr/free/nrw/commons/notification/NotificationHelper.java +++ b/app/src/main/java/fr/free/nrw/commons/notification/NotificationHelper.java @@ -4,16 +4,12 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; - import android.os.Build; import androidx.core.app.NotificationCompat; - import javax.inject.Inject; import javax.inject.Singleton; - import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.R; - import static androidx.core.app.NotificationCompat.DEFAULT_ALL; import static androidx.core.app.NotificationCompat.PRIORITY_HIGH; @@ -30,11 +26,11 @@ public class NotificationHelper { public static final int NOTIFICATION_EDIT_DESCRIPTION = 4; public static final int NOTIFICATION_EDIT_DEPICTIONS = 5; - private NotificationManager notificationManager; - private NotificationCompat.Builder notificationBuilder; + private final NotificationManager notificationManager; + private final NotificationCompat.Builder notificationBuilder; @Inject - public NotificationHelper(Context context) { + public NotificationHelper(final Context context) { notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); notificationBuilder = new NotificationCompat .Builder(context, CommonsApplication.NOTIFICATION_CHANNEL_ID_ALL) @@ -49,12 +45,13 @@ public class NotificationHelper { * @param notificationId the notificationID * @param intent the intent to be fired when the notification is clicked */ - public void showNotification(Context context, - String notificationTitle, - String notificationMessage, - int notificationId, - Intent intent) { - + public void showNotification( + final Context context, + final String notificationTitle, + final String notificationMessage, + final int notificationId, + final Intent intent + ) { notificationBuilder.setDefaults(DEFAULT_ALL) .setContentTitle(notificationTitle) .setStyle(new NotificationCompat.BigTextStyle() @@ -65,14 +62,11 @@ public class NotificationHelper { .setPriority(PRIORITY_HIGH); int flags = PendingIntent.FLAG_UPDATE_CURRENT; - - // Check if the API level is 31 or higher to modify the flag - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - // For API level 31 or above, PendingIntent requires either FLAG_IMMUTABLE or FLAG_MUTABLE to be set - flags |= PendingIntent.FLAG_IMMUTABLE; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + flags |= PendingIntent.FLAG_IMMUTABLE; // This flag was introduced in API 23 } - PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, flags); + final PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, flags); notificationBuilder.setContentIntent(pendingIntent); notificationManager.notify(notificationId, notificationBuilder.build()); } 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 707bf1363..eb180ec44 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 @@ -278,7 +278,8 @@ public class UploadActivity extends BaseActivity implements UploadContract.View, public void checkStoragePermissions() { // Check if all required permissions are granted final boolean hasAllPermissions = PermissionUtils.hasPermission(this, PERMISSIONS_STORAGE); - if (hasAllPermissions) { + final boolean hasPartialAccess = PermissionUtils.hasPartialAccess(this); + if (hasAllPermissions || hasPartialAccess) { // All required permissions are granted, so enable UI elements and perform actions receiveSharedItems(); binding.cvContainerTopCard.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt index 4a06cafb6..ebf930915 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt @@ -6,6 +6,7 @@ import android.app.PendingIntent import android.app.TaskStackBuilder import android.content.Context import android.content.Intent +import android.content.pm.ServiceInfo import android.graphics.BitmapFactory import android.os.Build import androidx.core.app.NotificationCompat @@ -46,13 +47,12 @@ import java.util.* import java.util.regex.Pattern import javax.inject.Inject - -class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : - CoroutineWorker(appContext, workerParams) { +class UploadWorker( + private var appContext: Context, workerParams: WorkerParameters +): CoroutineWorker(appContext, workerParams) { private var notificationManager: NotificationManagerCompat? = null - @Inject lateinit var wikidataEditService: WikidataEditService @@ -83,12 +83,11 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : //Attributes of the current-upload notification private var currentNotificationID: Int = -1// lateinit is not allowed with primitives private lateinit var currentNotificationTag: String - private var curentNotification: NotificationCompat.Builder + private var currentNotification: NotificationCompat.Builder private val statesToProcess= ArrayList() - private val STASH_ERROR_CODES = Arrays - .asList( + private val STASH_ERROR_CODES = listOf( "uploadstash-file-not-found", "stashfailed", "verification-error", @@ -100,7 +99,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : .getInstance(appContext) .commonsApplicationComponent .inject(this) - curentNotification = + currentNotification = getNotificationBuilder(CommonsApplication.NOTIFICATION_CHANNEL_ID_ALL)!! statesToProcess.add(Contribution.STATE_QUEUED) @@ -120,21 +119,23 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : fun onProgress(transferred: Long, total: Long) { if (transferred == total) { // Completed! - curentNotification.setContentTitle(notificationFinishingTitle) + currentNotification.setContentTitle(notificationFinishingTitle) .setProgress(0, 100, true) } else { - curentNotification + currentNotification .setProgress( 100, (transferred.toDouble() / total.toDouble() * 100).toInt(), false ) } - notificationManager?.cancel(PROCESSING_UPLOADS_NOTIFICATION_TAG, PROCESSING_UPLOADS_NOTIFICATION_ID) + notificationManager?.cancel( + PROCESSING_UPLOADS_NOTIFICATION_TAG, PROCESSING_UPLOADS_NOTIFICATION_ID + ) notificationManager?.notify( currentNotificationTag, currentNotificationID, - curentNotification.build()!! + currentNotification.build() ) contribution!!.transferred = transferred contributionDao.update(contribution).blockingAwait() @@ -248,10 +249,18 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : * Create new notification for foreground service */ private fun createForegroundInfo(): ForegroundInfo { - return ForegroundInfo( - 1, - createNotificationForForegroundService() - ) + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + ForegroundInfo( + 1, + createNotificationForForegroundService(), + ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC + ) + } else { + ForegroundInfo( + 1, + createNotificationForForegroundService() + ) + } } override suspend fun getForegroundInfo(): ForegroundInfo { @@ -282,9 +291,9 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : currentNotificationID = (contribution.localUri.toString() + contribution.media.filename).hashCode() - curentNotification + currentNotification getNotificationBuilder(CommonsApplication.NOTIFICATION_CHANNEL_ID_ALL)!! - curentNotification.setContentTitle( + currentNotification.setContentTitle( appContext.getString( R.string.upload_progress_notification_title_start, displayTitle @@ -294,7 +303,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : notificationManager?.notify( currentNotificationTag, currentNotificationID, - curentNotification.build()!! + currentNotification.build() ) val filename = media.filename @@ -312,14 +321,16 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : val stashUploadResult = uploadClient.uploadFileToStash( filename!!, contribution, notificationProgressUpdater ).onErrorReturn{ - return@onErrorReturn StashUploadResult(StashUploadState.FAILED,fileKey = null,errorMessage = it.message) + return@onErrorReturn StashUploadResult( + StashUploadState.FAILED,fileKey = null,errorMessage = it.message + ) }.blockingSingle() when (stashUploadResult.state) { StashUploadState.SUCCESS -> { //If the stash upload succeeds Timber.d("Upload to stash success for fileName: $filename") - Timber.d("Ensure uniqueness of filename"); - val uniqueFileName = findUniqueFileName(filename!!) + Timber.d("Ensure uniqueness of filename") + val uniqueFileName = findUniqueFileName(filename) try { //Upload the file from stash @@ -335,7 +346,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : ) wikidataEditService.addDepictionsAndCaptions(uploadResult, contribution) - .blockingSubscribe(); + .blockingSubscribe() if(contribution.wikidataPlace==null){ Timber.d( "WikiDataEdit not required, upload success" @@ -378,12 +389,15 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : } else -> { Timber.e("""upload file to stash failed with status: ${stashUploadResult.state}""") + contribution.state = Contribution.STATE_FAILED contribution.chunkInfo = null contribution.errorInfo = stashUploadResult.errorMessage showErrorNotification(contribution) contributionDao.saveSynchronous(contribution) - if (stashUploadResult.errorMessage.equals(CsrfTokenClient.INVALID_TOKEN_ERROR_MESSAGE)) { + if (stashUploadResult.errorMessage.equals( + CsrfTokenClient.INVALID_TOKEN_ERROR_MESSAGE) + ) { Timber.e("Invalid Login, logging out") showInvalidLoginNotification(contribution) val username = sessionManager.userName @@ -475,7 +489,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : imageSha1 == modifiedSha1, true ) - ); + ) } } } @@ -519,8 +533,8 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : private fun showSuccessNotification(contribution: Contribution) { val displayTitle = contribution.media.displayTitle contribution.state=Contribution.STATE_COMPLETED - curentNotification.setContentIntent(getPendingIntent(MainActivity::class.java)) - curentNotification.setContentTitle( + currentNotification.setContentIntent(getPendingIntent(MainActivity::class.java)) + currentNotification.setContentTitle( appContext.getString( R.string.upload_completed_notification_title, displayTitle @@ -531,7 +545,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : .setOngoing(false) notificationManager?.notify( currentNotificationTag, currentNotificationID, - curentNotification.build() + currentNotification.build() ) } @@ -542,8 +556,8 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : @SuppressLint("StringFormatInvalid") private fun showFailedNotification(contribution: Contribution) { val displayTitle = contribution.media.displayTitle - curentNotification.setContentIntent(getPendingIntent(UploadProgressActivity::class.java)) - curentNotification.setContentTitle( + currentNotification.setContentIntent(getPendingIntent(UploadProgressActivity::class.java)) + currentNotification.setContentTitle( appContext.getString( R.string.upload_failed_notification_title, displayTitle @@ -554,13 +568,13 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : .setOngoing(false) notificationManager?.notify( currentNotificationTag, currentNotificationID, - curentNotification.build() + currentNotification.build() ) } @SuppressLint("StringFormatInvalid") private fun showInvalidLoginNotification(contribution: Contribution) { val displayTitle = contribution.media.displayTitle - curentNotification.setContentTitle( + currentNotification.setContentTitle( appContext.getString( R.string.upload_failed_notification_title, displayTitle @@ -571,7 +585,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : .setOngoing(false) notificationManager?.notify( currentNotificationTag, currentNotificationID, - curentNotification.build() + currentNotification.build() ) } @@ -581,7 +595,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : @SuppressLint("StringFormatInvalid") private fun showErrorNotification(contribution: Contribution) { val displayTitle = contribution.media.displayTitle - curentNotification.setContentTitle( + currentNotification.setContentTitle( appContext.getString( R.string.upload_failed_notification_title, displayTitle @@ -592,7 +606,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : .setOngoing(false) notificationManager?.notify( currentNotificationTag, currentNotificationID, - curentNotification.build() + currentNotification.build() ) } @@ -602,8 +616,9 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : */ private fun showPausedNotification(contribution: Contribution) { val displayTitle = contribution.media.displayTitle - curentNotification.setContentIntent(getPendingIntent(UploadProgressActivity::class.java)) - curentNotification.setContentTitle( + + currentNotification.setContentIntent(getPendingIntent(UploadProgressActivity::class.java)) + currentNotification.setContentTitle( appContext.getString( R.string.upload_paused_notification_title, displayTitle @@ -614,7 +629,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : .setOngoing(false) notificationManager!!.notify( currentNotificationTag, currentNotificationID, - curentNotification.build() + currentNotification.build() ) } @@ -624,8 +639,8 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : */ private fun showCancelledNotification(contribution: Contribution) { val displayTitle = contribution.media.displayTitle - curentNotification.setContentIntent(getPendingIntent(UploadProgressActivity::class.java)) - curentNotification.setContentTitle( + currentNotification.setContentIntent(getPendingIntent(UploadProgressActivity::class.java)) + currentNotification.setContentTitle( displayTitle ) .setContentText("Upload has been cancelled!") @@ -633,7 +648,7 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : .setOngoing(false) notificationManager!!.notify( currentNotificationTag, currentNotificationID, - curentNotification.build() + currentNotification.build() ) } @@ -652,6 +667,6 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : } else { getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT) } - }; + } } } diff --git a/app/src/main/java/fr/free/nrw/commons/utils/PermissionUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/PermissionUtils.java index b0a72eae1..9082c1f0f 100644 --- a/app/src/main/java/fr/free/nrw/commons/utils/PermissionUtils.java +++ b/app/src/main/java/fr/free/nrw/commons/utils/PermissionUtils.java @@ -1,6 +1,7 @@ package fr.free.nrw.commons.utils; import android.Manifest; +import android.Manifest.permission; import android.app.Activity; import android.content.Intent; import android.content.pm.PackageManager; @@ -20,24 +21,26 @@ import fr.free.nrw.commons.R; import fr.free.nrw.commons.upload.UploadActivity; import java.util.List; - public class PermissionUtils { + public static String[] PERMISSIONS_STORAGE = getPermissionsStorage(); - public static String[] PERMISSIONS_STORAGE = isSDKVersionScopedStorageCompatible() ? - isSDKVersionTiramisu() ? new String[]{ - Manifest.permission.READ_MEDIA_IMAGES} : - new String[]{Manifest.permission.READ_EXTERNAL_STORAGE} - : isSDKVersionTiramisu() ? new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.READ_MEDIA_IMAGES} - : new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.READ_EXTERNAL_STORAGE}; - - private static boolean isSDKVersionScopedStorageCompatible() { - return Build.VERSION.SDK_INT > Build.VERSION_CODES.P; - } - - public static boolean isSDKVersionTiramisu() { - return Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU; + static String[] getPermissionsStorage() { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + return new String[]{ Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED, + Manifest.permission.READ_MEDIA_IMAGES, + Manifest.permission.ACCESS_MEDIA_LOCATION }; + } + if(Build.VERSION.SDK_INT == Build.VERSION_CODES.TIRAMISU) { + return new String[]{ Manifest.permission.READ_MEDIA_IMAGES, + Manifest. permission.ACCESS_MEDIA_LOCATION }; + } + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + return new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.ACCESS_MEDIA_LOCATION }; + } + return new String[]{ + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE }; } /** @@ -45,11 +48,11 @@ public class PermissionUtils { * blocked(marked never ask again by the user) It open the app settings from where the user can * manually give us the required permission. * - * @param activity + * @param activity The Activity which requires a permission which has been blocked */ - private static void askUserToManuallyEnablePermissionFromSettings(Activity activity) { - Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); - Uri uri = Uri.fromParts("package", activity.getPackageName(), null); + private static void askUserToManuallyEnablePermissionFromSettings(final Activity activity) { + final Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); + final Uri uri = Uri.fromParts("package", activity.getPackageName(), null); intent.setData(uri); activity.startActivityForResult(intent, CommonsApplication.OPEN_APPLICATION_DETAIL_SETTINGS); @@ -58,14 +61,13 @@ public class PermissionUtils { /** * Checks whether the app already has a particular permission * - * @param activity - * @param permissions permissions to be checked - * @return + * @param activity The Activity context to check permissions against + * @param permissions An array of permission strings to check + * @return `true if the app has all the specified permissions, `false` otherwise */ - public static boolean hasPermission(Activity activity, String permissions[]) { + public static boolean hasPermission(final Activity activity, final String[] permissions) { boolean hasPermission = true; - for (String permission : permissions - ) { + for(final String permission : permissions) { hasPermission = hasPermission && ContextCompat.checkSelfPermission(activity, permission) == PackageManager.PERMISSION_GRANTED; @@ -73,6 +75,17 @@ public class PermissionUtils { return hasPermission; } + public static boolean hasPartialAccess(final Activity activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + return ContextCompat.checkSelfPermission(activity, + permission.READ_MEDIA_VISUAL_USER_SELECTED + ) == PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission( + activity, permission.READ_MEDIA_IMAGES + ) == PackageManager.PERMISSION_DENIED; + } + return false; + } + /** * Checks for a particular permission and runs the runnable to perform an action when the * permission is granted Also, it shows a rationale if needed @@ -99,9 +112,17 @@ public class PermissionUtils { * @param rationaleMessage rationale message to be displayed when permission was denied. It * can be an invalid @StringRes */ - public static void checkPermissionsAndPerformAction(Activity activity, - Runnable onPermissionGranted, @StringRes int rationaleTitle, - @StringRes int rationaleMessage, String... permissions) { + public static void checkPermissionsAndPerformAction( + final Activity activity, + final Runnable onPermissionGranted, + final @StringRes int rationaleTitle, + final @StringRes int rationaleMessage, + final String... permissions + ) { + if (hasPartialAccess(activity)) { + onPermissionGranted.run(); + return; + } checkPermissionsAndPerformAction(activity, onPermissionGranted, null, rationaleTitle, rationaleMessage, permissions); } @@ -125,25 +146,30 @@ public class PermissionUtils { * @param rationaleTitle rationale title to be displayed when permission was denied * @param rationaleMessage rationale message to be displayed when permission was denied */ - public static void checkPermissionsAndPerformAction(Activity activity, - Runnable onPermissionGranted, Runnable onPermissionDenied, @StringRes int rationaleTitle, - @StringRes int rationaleMessage, String... permissions) { + public static void checkPermissionsAndPerformAction( + final Activity activity, + final Runnable onPermissionGranted, + final Runnable onPermissionDenied, + final @StringRes int rationaleTitle, + final @StringRes int rationaleMessage, + final String... permissions + ) { Dexter.withActivity(activity) .withPermissions(permissions) .withListener(new MultiplePermissionsListener() { @Override - public void onPermissionsChecked(MultiplePermissionsReport report) { - if (report.areAllPermissionsGranted()) { + public void onPermissionsChecked(final MultiplePermissionsReport report) { + if (report.areAllPermissionsGranted() || hasPartialAccess(activity)) { onPermissionGranted.run(); return; } if (report.isAnyPermissionPermanentlyDenied()) { // permission is denied permanently, we will show user a dialog message. - DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle), + DialogUtil.showAlertDialog( + activity, activity.getString(rationaleTitle), activity.getString(rationaleMessage), activity.getString(R.string.navigation_item_settings), - null, - () -> { + null, () -> { askUserToManuallyEnablePermissionFromSettings(activity); if (activity instanceof UploadActivity) { ((UploadActivity) activity).setShowPermissionsDialog(true); @@ -158,13 +184,16 @@ public class PermissionUtils { } @Override - public void onPermissionRationaleShouldBeShown(List permissions, - PermissionToken token) { + public void onPermissionRationaleShouldBeShown( + final List permissions, + final PermissionToken token + ) { if (rationaleTitle == -1 && rationaleMessage == -1) { token.continuePermissionRequest(); return; } - DialogUtil.showAlertDialog(activity, activity.getString(rationaleTitle), + DialogUtil.showAlertDialog( + activity, activity.getString(rationaleTitle), activity.getString(rationaleMessage), activity.getString(android.R.string.ok), activity.getString(android.R.string.cancel), @@ -173,24 +202,19 @@ public class PermissionUtils { ((UploadActivity) activity).setShowPermissionsDialog(true); } token.continuePermissionRequest(); - } - , + }, () -> { Toast.makeText(activity.getApplicationContext(), - R.string.permissions_are_required_for_functionality, - Toast.LENGTH_LONG) - .show(); + R.string.permissions_are_required_for_functionality, + Toast.LENGTH_LONG + ).show(); token.cancelPermissionRequest(); if (activity instanceof UploadActivity) { activity.finish(); } - } - , - null, - false); + }, null, false + ); } - }) - .onSameThread() - .check(); + }).onSameThread().check(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/widget/PicOfDayAppWidget.java b/app/src/main/java/fr/free/nrw/commons/widget/PicOfDayAppWidget.java index f33631784..273452078 100644 --- a/app/src/main/java/fr/free/nrw/commons/widget/PicOfDayAppWidget.java +++ b/app/src/main/java/fr/free/nrw/commons/widget/PicOfDayAppWidget.java @@ -9,10 +9,9 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.net.Uri; +import android.os.Build; import android.widget.RemoteViews; - import androidx.annotation.Nullable; - import com.facebook.common.executors.CallerThreadExecutor; import com.facebook.common.references.CloseableReference; import com.facebook.datasource.DataSource; @@ -22,10 +21,8 @@ import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber; import com.facebook.imagepipeline.image.CloseableImage; import com.facebook.imagepipeline.request.ImageRequest; import com.facebook.imagepipeline.request.ImageRequestBuilder; - import fr.free.nrw.commons.media.MediaClient; import javax.inject.Inject; - import fr.free.nrw.commons.R; import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.di.ApplicationlessInjection; @@ -41,17 +38,28 @@ import static android.content.Intent.ACTION_VIEW; */ public class PicOfDayAppWidget extends AppWidgetProvider { - private CompositeDisposable compositeDisposable = new CompositeDisposable(); + private final CompositeDisposable compositeDisposable = new CompositeDisposable(); @Inject MediaClient mediaClient; - void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.pic_of_day_app_widget); + void updateAppWidget( + final Context context, + final AppWidgetManager appWidgetManager, + final int appWidgetId + ) { + final RemoteViews views = new RemoteViews( + context.getPackageName(), R.layout.pic_of_day_app_widget); // Launch App on Button Click - Intent viewIntent = new Intent(context, MainActivity.class); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, viewIntent, PendingIntent.FLAG_IMMUTABLE); + final Intent viewIntent = new Intent(context, MainActivity.class); + int flags = PendingIntent.FLAG_UPDATE_CURRENT; + if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.M) { + flags |= PendingIntent.FLAG_IMMUTABLE; + } + final PendingIntent pendingIntent = PendingIntent.getActivity( + context, 0, viewIntent, flags); + views.setOnClickPendingIntent(R.id.camera_button, pendingIntent); appWidgetManager.updateAppWidget(appWidgetId, views); @@ -60,61 +68,76 @@ public class PicOfDayAppWidget extends AppWidgetProvider { /** * Loads the picture of the day using media wiki API - * @param context - * @param views - * @param appWidgetManager - * @param appWidgetId + * @param context The application context. + * @param views The RemoteViews object used to update the App Widget UI. + * @param appWidgetManager The AppWidgetManager instance for managing the widget. + * @param appWidgetId he ID of the App Widget to update. */ - private void loadPictureOfTheDay(Context context, - RemoteViews views, - AppWidgetManager appWidgetManager, - int appWidgetId) { + private void loadPictureOfTheDay( + final Context context, + final RemoteViews views, + final AppWidgetManager appWidgetManager, + final int appWidgetId + ) { compositeDisposable.add(mediaClient.getPictureOfTheDay() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( - response -> { - if (response != null) { - views.setTextViewText(R.id.appwidget_title, response.getDisplayTitle()); + response -> { + if (response != null) { + views.setTextViewText(R.id.appwidget_title, response.getDisplayTitle()); - // View in browser - Intent viewIntent = new Intent(); - viewIntent.setAction(ACTION_VIEW); - viewIntent.setData(Uri.parse(response.getPageTitle().getMobileUri())); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, viewIntent, PendingIntent.FLAG_IMMUTABLE); - views.setOnClickPendingIntent(R.id.appwidget_image, pendingIntent); + // View in browser + final Intent viewIntent = new Intent(); + viewIntent.setAction(ACTION_VIEW); + viewIntent.setData(Uri.parse(response.getPageTitle().getMobileUri())); - loadImageFromUrl(response.getThumbUrl(), context, views, appWidgetManager, appWidgetId); + int flags = PendingIntent.FLAG_UPDATE_CURRENT; + if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.M) { + flags |= PendingIntent.FLAG_IMMUTABLE; } - }, - t -> Timber.e(t, "Fetching picture of the day failed") + final PendingIntent pendingIntent = PendingIntent.getActivity( + context, 0, viewIntent, flags); + + views.setOnClickPendingIntent(R.id.appwidget_image, pendingIntent); + loadImageFromUrl(response.getThumbUrl(), + context, views, appWidgetManager, appWidgetId); + } + }, + t -> Timber.e(t, "Fetching picture of the day failed") )); } /** * Uses Fresco to load an image from Url - * @param imageUrl - * @param context - * @param views - * @param appWidgetManager - * @param appWidgetId + * @param imageUrl The URL of the image to load. + * @param context The application context. + * @param views The RemoteViews object used to update the App Widget UI. + * @param appWidgetManager The AppWidgetManager instance for managing the widget. + * @param appWidgetId he ID of the App Widget to update. */ - private void loadImageFromUrl(String imageUrl, - Context context, - RemoteViews views, - AppWidgetManager appWidgetManager, - int appWidgetId) { - ImageRequest request = ImageRequestBuilder.newBuilderWithSource(Uri.parse(imageUrl)).build(); - ImagePipeline imagePipeline = Fresco.getImagePipeline(); - DataSource> dataSource - = imagePipeline.fetchDecodedImage(request, context); + private void loadImageFromUrl( + final String imageUrl, + final Context context, + final RemoteViews views, + final AppWidgetManager appWidgetManager, + final int appWidgetId + ) { + final ImageRequest request = ImageRequestBuilder + .newBuilderWithSource(Uri.parse(imageUrl)).build(); + final ImagePipeline imagePipeline = Fresco.getImagePipeline(); + final DataSource> dataSource = imagePipeline + .fetchDecodedImage(request, context); + dataSource.subscribe(new BaseBitmapDataSubscriber() { @Override - protected void onNewResultImpl(@Nullable Bitmap tempBitmap) { + protected void onNewResultImpl(@Nullable final Bitmap tempBitmap) { Bitmap bitmap = null; if (tempBitmap != null) { - bitmap = Bitmap.createBitmap(tempBitmap.getWidth(), tempBitmap.getHeight(), Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); + bitmap = Bitmap.createBitmap( + tempBitmap.getWidth(), tempBitmap.getHeight(), Bitmap.Config.ARGB_8888 + ); + final Canvas canvas = new Canvas(bitmap); canvas.drawBitmap(tempBitmap, 0f, 0f, new Paint()); } views.setImageViewBitmap(R.id.appwidget_image, bitmap); @@ -122,32 +145,37 @@ public class PicOfDayAppWidget extends AppWidgetProvider { } @Override - protected void onFailureImpl(DataSource> dataSource) { + protected void onFailureImpl( + final DataSource> dataSource + ) { // Ignore failure for now. } }, CallerThreadExecutor.getInstance()); } @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + public void onUpdate( + final Context context, + final AppWidgetManager appWidgetManager, + final int[] appWidgetIds + ) { ApplicationlessInjection - .getInstance(context - .getApplicationContext()) + .getInstance(context.getApplicationContext()) .getCommonsApplicationComponent() .inject(this); // There may be multiple widgets active, so update all of them - for (int appWidgetId : appWidgetIds) { + for (final int appWidgetId : appWidgetIds) { updateAppWidget(context, appWidgetManager, appWidgetId); } } @Override - public void onEnabled(Context context) { + public void onEnabled(final Context context) { // Enter relevant functionality for when the first widget is created } @Override - public void onDisabled(Context context) { + public void onDisabled(final Context context) { // Enter relevant functionality for when the last widget is disabled } } diff --git a/app/src/main/res/layout/activity_custom_selector.xml b/app/src/main/res/layout/activity_custom_selector.xml index fbd036f94..02c864422 100644 --- a/app/src/main/res/layout/activity_custom_selector.xml +++ b/app/src/main/res/layout/activity_custom_selector.xml @@ -1,17 +1,25 @@ + + + app:layout_constraintTop_toBottomOf="@+id/partial_access_indicator" + tools:layout_editor_absoluteX="-16dp" /> diff --git a/app/src/main/res/layout/welcome_bullet.xml b/app/src/main/res/layout/welcome_bullet.xml index 6e2102206..3974d99ff 100644 --- a/app/src/main/res/layout/welcome_bullet.xml +++ b/app/src/main/res/layout/welcome_bullet.xml @@ -1,6 +1,7 @@ @@ -8,7 +9,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:paddingRight="@dimen/tiny_margin" - android:text="@string/bullet" + android:text="•" android:textColor="@android:color/white" - android:textSize="@dimen/normal_text" /> + android:textSize="@dimen/normal_text" + tools:ignore="HardcodedText" /> \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index bcf3c5538..b46cbf547 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -113,7 +113,6 @@ التعليقات الخصوصية المشاعات - الإعدادات رفع إلى المشاعات جار الرفع diff --git a/app/src/main/res/values-as/strings.xml b/app/src/main/res/values-as/strings.xml index 43d9084c8..960b55bda 100644 --- a/app/src/main/res/values-as/strings.xml +++ b/app/src/main/res/values-as/strings.xml @@ -18,7 +18,6 @@ প্ৰতিক্ৰিয়া গোপনিয়তা ক\'ম\'ঞ্চ - ছেটিংছ ক\'ম\'ঞ্চত আপল\'ড কৰক ব্যৱহাৰকাৰীনাম diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml index 6cebe608b..df61ed061 100644 --- a/app/src/main/res/values-ast/strings.xml +++ b/app/src/main/res/values-ast/strings.xml @@ -63,7 +63,6 @@ La to opinión Intimidá Commons - Configuración Xubir a Commons Nome d\'usuariu diff --git a/app/src/main/res/values-b+roa+tara/strings.xml b/app/src/main/res/values-b+roa+tara/strings.xml index 7f886964a..4fa660ef8 100644 --- a/app/src/main/res/values-b+roa+tara/strings.xml +++ b/app/src/main/res/values-b+roa+tara/strings.xml @@ -32,7 +32,6 @@ Segnalazione Privacy Commons - \'Mbostaziune Careche sus a Commons Nome de l\'utende 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 05f757e5f..cd1cb09e8 100644 --- a/app/src/main/res/values-b+sr+Latn/strings.xml +++ b/app/src/main/res/values-b+sr+Latn/strings.xml @@ -59,7 +59,6 @@ Povratne informacije Privatnost Ostava - Podešavanja Otpremi na Ostavu Otpremanje u toku diff --git a/app/src/main/res/values-ba/strings.xml b/app/src/main/res/values-ba/strings.xml index c49f54430..0fc68329f 100644 --- a/app/src/main/res/values-ba/strings.xml +++ b/app/src/main/res/values-ba/strings.xml @@ -52,7 +52,6 @@ Кире бәйләнеш Сер һаҡлау Викимилек - Көйләүҙәр Викимилеккә йөкләргә Ҡатнашыусы исеме diff --git a/app/src/main/res/values-ban/strings.xml b/app/src/main/res/values-ban/strings.xml index 009d7f391..b24bc0022 100644 --- a/app/src/main/res/values-ban/strings.xml +++ b/app/src/main/res/values-ban/strings.xml @@ -51,7 +51,6 @@ Umpan walik Paragaan Commons - Setélan Unggah nuju Commons Pangunggahan kantun mamargi diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 601c40a29..0f765a1fb 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -42,7 +42,6 @@ Обратна връзка Поверителност Общомедия - Настройки Качване в Общомедия Потребителско име diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index d2bc6ad60..2d156c199 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -75,7 +75,6 @@ প্রতিক্রিয়া গোপনীয়তা কমন্স - সেটিং কমন্সে আপলোড করুন আপলোড করা হচ্ছে @@ -527,4 +526,7 @@ এই বিষয়বস্তু সম্পর্কে অভিযোগ জানান এই ব্যবহারকারীকে বাধাদনের অনুরোধ করুন কার্যকারিতার জন্য অনুমতি প্রয়োজন + আপলোড + অমীমাংসিত + ব্যর্থ হয়েছে diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml index 230913779..be454b51b 100644 --- a/app/src/main/res/values-br/strings.xml +++ b/app/src/main/res/values-br/strings.xml @@ -59,7 +59,6 @@ Sonjoù Prevezded Commons - Arventennoù Enporzhiañ e Commons Anv implijer diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index b03ef5e1d..4d49ee632 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -65,7 +65,6 @@ Zpětná vazba Soukromí Commons - Nastavení Nahrát na Commons Uživatelské jméno diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index 0aa1f6b53..8c4b4a652 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -48,7 +48,6 @@ Adborth Preifatrwydd Comin Wicimedia - Gosodiadau Uwchlwytho i Comin Enw defnyddiwr diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 3ddf99698..4116080ea 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -67,7 +67,6 @@ Feedback Privatliv Commons - Indstillinger Upload til Commons Upload i gang @@ -182,7 +181,7 @@ Titel: Sydneys operahus Beskrivelse: Sydneys operahus set fra den anden side af bugten Kategorier: Sydneys operahus fra vest, Sydneys operahus eksterne visninger - Bidrag med dine billeder. Hjælp Wikipedias artikler med at komme til live! + Bidrag med dine billeder og giv Wikipedia-artiklerne mere liv! Billeder på Wikipedia kommer fra Wikimedia Commons. Dine billeder hjælper med til at uddanne folk rundt om i verden. Undgå ophavsretligt beskyttede materialer du har fundet på internettet samt billeder af plakater, bogomslag osv. @@ -783,5 +782,10 @@ \'%1$s\' ligger et andet sted. Angiv venligst det korrekte sted nedenfor, og skriv om muligt den korrekte bredde- og længdegrad. Andet problem eller anden information (forklar venligst nedenfor). Din feedback bliver slået op på følgende wiki-side: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> + Er du sikker på, at du vil annullere alle uploads? + Annullerer alle uploads... + Uploads + Afventer + Mislykkedes Kunne ikke indlæse steddata diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 35a81f1f7..25498e395 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -97,7 +97,6 @@ Rückmeldung Datenschutz Commons - Einstellungen Zu Commons hochladen Hochladen läuft diff --git a/app/src/main/res/values-diq/strings.xml b/app/src/main/res/values-diq/strings.xml index 4530093ae..840b0198d 100644 --- a/app/src/main/res/values-diq/strings.xml +++ b/app/src/main/res/values-diq/strings.xml @@ -53,7 +53,6 @@ Peyderıştış Dızdêniye Commons - Eyari Barê Embari ke Namey karberi diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index fe2143a41..e3675ef0a 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -20,6 +20,7 @@ * Nikosguard * Norhorn * Panos78 +* PeachyOne * Protnet * Tgkarounos * Vtalos @@ -81,7 +82,6 @@ Ανατροφοδότηση Απόρρητο Commons - Ρυθμίσεις Μεταφόρτωση στα Commons Μεταφόρτωση σε εξέλιξη @@ -403,57 +403,57 @@ Ενημερώσεις Ειδοποιήσεις (ανάγνωση) Εμφάνιση ειδοποίησης σε κοντινή απόσταση - Πατήστε εδώ για να δείτε την πιο κοντινή θέση που χρειάζεται εικόνες - Λίστα - Άδεια Αποθήκευσης + Εμφάνιση ειδοποίησης εντός της εφαρμογής για το πλησιέστερο μέρος που χρειάζεται φωτογραφίες + Κατάλογος + Άδεια αποθήκευσης Χρειαζόμαστε την άδειά σας για πρόσβαση στον εξωτερικό χώρο αποθήκευσης της συσκευής σας προκειμένου να ανεβάσουμε εικόνες. - Δεν θα δείτε την πιο κοντινή τοποθεσία που χρειάζεται επιπλέον εικόνες. Ωστόσο, μπορείτε να ενεργοποιήσετε ξανά αυτή την ειδοποίηση στις Ρυθμίσεις αν θέλετε. + Δε θα βλέπετε πλέον το πλησιέστερο μέρος που χρειάζεται φωτογραφίες. Ωστόσο, μπορείτε να ενεργοποιήσετε ξανά αυτή την ειδοποίηση στις Ρυθμίσεις, αν το επιθυμείτε. Βήμα %1$d από %2$d: %3$s Επόμενο Προηγούμενο - Υπάρχει ήδη αρχείο με όνομα %1$s. Είστε σίγουροι πως θέλετε να προχωρήσετε;\n\nΣημείωση: θα προστεθεί αυτόματα μια διόρθωση όνομα αρχείου. - Καμία εφαρμογή χάρτη δεν βρέθηκε στον υπολογιστή. Παρακαλώ εγκαταστήστε εφαρμογή χάρτη για να χρησιμοποιήσετε αυτήν την ιδιότητα. - εικόνες + Υπάρχει ήδη αρχείο με το όνομα %1$s. Είστε σίγουροι πως θέλετε να προχωρήσετε;\n\nΣημείωση: Ένα κατάλληλο επίθημα θα προστεθεί αυτόματα στο όνομα του αρχείου. + Δε βρέθηκε καμία συμβατή εφαρμογή χάρτη στη συσκευή σας. Εγκαταστήστε μια εφαρμογή χάρτη για να χρησιμοποιήσετε αυτήν τη δυνατότητα. + Φωτογραφίες Τοποθεσίες Προσθήκη/Κατάργηση σε σελιδοδείκτες Σελιδοδείκτες Δεν έχετε προσθέσει σελιδοδείκτες Σελιδοδείκτες - Η συλλογή αρχείων καταγραφής ξεκίνησε. ΕΠΑΝΑΚΙΝΗΣΤΕ την εφαρμογή, εκτελέστε την ενέργεια που θέλετε να καταγράψετε και, στη συνέχεια, πατήστε ξανά \"Αποστολή αρχείου καταγραφής\" - Το ανέβασα κατά λάθος - Δεν ήξερα ότι θα δημοσιευόταν - Κατάλαβα πως δεν προστατεύονται τα ατομικά μου στοιχεία - Άλλαξα γνώμη, δεν θέλω να προβάλλεται πλέον δημόσια - Λυπάμαι αυτή η εικόνα δεν έχει ενδιαφέρον για εγκυκλοπαίδεια - Ανέβηκε από εμένα στο %1$s, χρησιμοποιήθηκε σε %2$d άρθρο(α) - Καλώς ήρθατε στα Commons!\n\nΑνεβάστε τα πρώτα σας πολυμέσα πατώντας το κουμπί προσθήκης. + Η συλλογή αρχείων καταγραφής ξεκίνησε. Παρακαλώ ΕΠΑΝΕΚΚΙΝΗΣΤΕ την εφαρμογή, εκτελέστε την ενέργεια που επιθυμείτε να καταγράψετε και, στη συνέχεια, πατήστε ξανά «Αποστολή αρχείου καταγραφής» + Το μεταφόρτωσα κατά λάθος + Δεν ήξερα ότι θα ήταν δημόσια ορατό + Συνειδητοποίησα ότι είναι κακό για την ιδιωτικότητά μου + Άλλαξα γνώμη, δε θέλω να προβάλλεται πλέον δημόσια + Συγγνώμη, αυτή η φωτογραφία δεν είναι ενδιαφέρουσα για μια εγκυκλοπαίδεια + Ανέβηκε από εμένα στο %1$s, χρησιμοποιήθηκε σε %2$d άρθρο/α + Καλώς ήρθατε στα Commons!\n\nΑνεβάστε τα πρώτα σας πολυμέσα πατώντας το κουμπί της προσθήκης. Δεν επιλέχθηκαν κατηγορίες - Εικόνες χωρίς κατηγορίες χρησιμοποιούνται σπάνια. Θέλετε πράγματι να συνεχίσετε δίχως να επιλέξετε κατηγορίες? - Δεν έχουν επιλεγεί αποτυπώσεις - Οι εικόνες με απεικονίσεις βρίσκονται πιο εύκολα και πιο πιθανό να χρησιμοποιηθούν. Είστε βέβαιοι ότι θέλετε να συνεχίσετε χωρίς να επιλέξετε απεικονίσεις; + Οι εικόνες χωρίς κατηγορίες χρησιμοποιούνται σπάνια. Θέλετε πράγματι να συνεχίσετε δίχως να επιλέξετε κατηγορίες; + Δεν έχουν επιλεγεί απεικονίσεις + Οι εικόνες με απεικονίσεις είναι πιο εύκολα ανιχνεύσιμες και πιο πιθανό να χρησιμοποιηθούν. Θέλετε σίγουρα να συνεχίσετε χωρίς να επιλέξετε απεικονίσεις; Ακύρωση Μεταφόρτωσης - Η χρήση του κουμπιού \"πίσω\" θα ακυρώσει αυτήν τη μεταφόρτωση και θα χάσετε την πρόοδό σας + Χρησιμοποιώντας το κουμπί επιστροφής θα ακυρώσετε αυτή τη μεταφόρτωση και θα χάσετε την πρόοδό σας Συνέχιση Μεταφόρτωσης - (Για όλες τις εικόνες στο σετ) + (Για όλες τις εικόνες στο σύνολο) Αναζήτηση στην περιοχή Αίτημα Άδειας Θα θέλατε να χρησιμοποιήσουμε την τρέχουσα τοποθεσία σας για να εμφανίσουμε το πλησιέστερο μέρος που χρειάζεται φωτογραφίες; Δεν είναι δυνατή η εμφάνιση του πλησιέστερου μέρους που χρειάζεται φωτογραφίες χωρίς δικαιώματα τοποθεσίας - Μην το ρωτήσετε ξανά αυτό + Μη με ξαναρωτήσετε Ζητήστε άδεια τοποθεσίας Ζητήστε άδεια τοποθεσίας όταν χρειάζεται για τη λειτουργία προβολής κοντινής κάρτας ειδοποιήσεων. Κάτι πήγε στραβά. Δεν μπορέσαμε να ανακτήσουμε επιτεύγματα - Έχετε κάνει τόσες πολλές συνεισφορές που δεν μπορεί να αντεπεξέλθει το σύστημα υπολογισμού των επιτευγμάτων μας. Αυτό είναι το απόλυτο επίτευγμα. - Τελειώνει σε: - Προβολή καμπανιών - Δείτε τις τρέχουσες καμπάνιες + Έχετε κάνει τόσες πολλές συνεισφορές που δεν μπορεί να αντεπεξέλθει το σύστημα υπολογισμού επιτευγμάτων μας. Αυτό είναι το απόλυτο επίτευγμα. + Λήγει στις: + Προβολή εκστρατειών + Δείτε τις τρέχουσες εκστρατείες Επιτρέψτε στην εφαρμογή να ανακτήσει τοποθεσία σε περίπτωση που η κάμερα δεν την καταγράψει. Ορισμένες κάμερες συσκευών δεν καταγράφουν τοποθεσία. Σε τέτοιες περιπτώσεις, το να αφήσετε την εφαρμογή να ανακτήσει και να επισυνάψει τοποθεσία καθιστά τη συνεισφορά σας πιο χρήσιμη. Μπορείτε να το αλλάξετε ανά πάσα στιγμή από τις Ρυθμίσεις - Επιτρέψτε + Αποδοχή Απόρριψη - Ενεργοποιήστε την πρόσβαση τοποθεσίας από τις Ρυθμίσεις και δοκιμάστε ξανά. \n\nΣημείωση: Η μεταφόρτωση ενδέχεται να μην έχει τοποθεσία, εάν η εφαρμογή δεν μπορεί να ανακτήσει την τοποθεσία από τη συσκευή σε σύντομο χρονικό διάστημα. + Ενεργοποιήστε την πρόσβαση τοποθεσίας από τις Ρυθμίσεις και δοκιμάστε ξανά.\n\nΣημείωση: Η μεταφόρτωση ενδέχεται να μην έχει τοποθεσία, εάν η εφαρμογή δεν μπορεί να ανακτήσει την τοποθεσία από τη συσκευή σε σύντομο χρονικό διάστημα. Η κάμερα εντός εφαρμογής χρειάζεται άδεια τοποθεσίας για να την επισυνάψει στις εικόνες σας σε περίπτωση που η τοποθεσία δεν είναι διαθέσιμη στο EXIF. Επιτρέψτε στην εφαρμογή να αποκτήσει πρόσβαση στην τοποθεσία σας και δοκιμάστε ξανά.\n\nΣημείωση: Η μεταφόρτωση ενδέχεται να μην έχει τοποθεσία εάν η εφαρμογή δεν μπορεί να ανακτήσει την τοποθεσία από τη συσκευή σε σύντομο χρονικό διάστημα. - Η εφαρμογή δεν θα καταγράψει την τοποθεσία μαζί με τις φωτογραφίες λόγω έλλειψης άδειας τοποθεσίας - Η εφαρμογή δεν θα καταγράψει την τοποθεσία μαζί με τις φωτογραφίες καθώς το GPS είναι απενεργοποιημένο + Η εφαρμογή δε θα καταγράψει την τοποθεσία μαζί με τις φωτογραφίες λόγω έλλειψης άδειας τοποθεσίας + Η εφαρμογή δε θα καταγράψει την τοποθεσία μαζί με τις φωτογραφίες καθώς το GPS είναι απενεργοποιημένο Χρησιμοποιήστε εργαλείο επιλογής φωτογραφιών βάσει εγγράφων Το νέο εργαλείο επιλογής φωτογραφιών Android κινδυνεύει να χάσει τις πληροφορίες τοποθεσίας. Ενεργοποιήστε εάν φαίνεται ότι το χρησιμοποιείτε. Παρακαλώ σιγουρευτείτε ότι αύτος ο κανούριος επιλογέας Android δεν αφαιρεί την τοποθεσία από τις εικόνες.\n\nΠατήστε στο \'Διαβάστε περισσότερα\' για περισσότερες πληροφορίες. @@ -797,5 +797,10 @@ Το \'%1$s\' βρίσκεται σε διαφορετική θέση. Παρακαλούμε προσδιορίστε τη σωστή θέση παρακαλώ, και αν είναι εφικτό, γράψτε το σωστό γεωγραφικό πλάτος και μήκος. Άλλο πρόβλημα ή πληροφορίες (παρακαλούμε εξηγήστε παρακάτω). Τα σχόλιά σας δημοσιεύονται στην ακόλουθη σελίδα wiki: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Εφαρμογή για κινητά/Σχόλια</a> + Είστε βέβαιοι ότι θέλετε να ακυρώσετε όλες τις μεταφορτώσεις; + Ακύρωση όλων των μεταφορτώσεων... + Μεταφορτώσεις + Σε εκκρεμότητα + Απέτυχε Δεν ήταν δυνατή η φόρτωση δεδομένων της θέσης diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 9b5bb84ac..69673afbe 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -68,7 +68,6 @@ Prikomentado Privateco Komunejo - Agordoj Alŝuti al la Komunejo Alŝutante diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6d18d34ed..4e90f6864 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -32,6 +32,7 @@ * Juanman * Keneth Urrutia * Ktranz +* Laquin * Luisangelrg * Macofe * Madamebiblio @@ -107,7 +108,6 @@ Sugerencias Privacidad Commons - Configuración Subir a Commons Carga en curso @@ -788,6 +788,9 @@ Se denegaron los permisos de almacenamiento No se puede compartir este elemento Se requieren permisos para la funcionalidad + Aprenda a escribir una descripción útil + Aprenda a escribir una leyenda útil + Ver sus logros Editar Imagen Editar Ubicación ¡Ubicación actualizada! @@ -795,6 +798,8 @@ Eliminar el aviso de ubicación La ubicación hace que las imágenes sean más útiles y accesibles. ¿De verdad quieres eliminar la ubicación de esta foto? ¡Ubicación eliminada! + Agradecer al autor + Error al enviar gracias al autor. Su sesión ha caducado. Inicie sesión de nuevo. No hay ninguna aplicación disponible para abrir archivos GPX Guardado correctamente @@ -810,4 +815,12 @@ Recuerde que todas las imágenes en una carga múltiple tienen la misma categoría y representación. Si las imágenes no comparten representación y categoría, haga varias cargas por separado. Nota sobre cargas múltiples + Informar a Wikidata sobre un problema relacionado con este elemento + Por favor, escriba algunos comentarios. + Discusión + Escriba algo sobre el elemento \'%1$s\'. Será visible públicamente. + Cancelando todas las subidas... + Subidas + Pendiente + Falló diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 0b4476336..ff75cbc7f 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -7,6 +7,7 @@ * Fitoschido * Iñaki LL * Joseba +* Laquin * Mikel Ibaiba * Sator * Subi @@ -24,6 +25,11 @@ Ekarpen berria gehitu Gehitu ekarpena kamaratik Gehitu ekarpena argazkietatik + Gehitu ekarpena aurreko ekarpen-galeriatik + Irudi-oineko testuak + Hizkuntzaren deskribapena + Irudi-oineko testua + Irudia Eguneko argazkia Fitxategi %1$d kargatzen @@ -56,7 +62,6 @@ Feedback Pribatutasuna Commons - Hobespenak Commons-en kargatu Erabiltzaile izena @@ -67,6 +72,7 @@ Eman izena Saioa hasten Mesedez itxaron… + Itxaron mesedez… Sarrera arrakastatsua! Saio hasieran akatsa! Fitxategia ez da aurkitu. Mesedez saiatu beste batekin. @@ -79,6 +85,7 @@ %1$s igotzen bukatzen %1$s igotzean akatsa Ukitu ikusteko + Ukitu ikusteko Nire azken igoerak Itxoite-zerrendan Hutseginda @@ -97,7 +104,7 @@ Sartzeko saiakera txar gehiegi. Mesedez saiatu zaitez minutu batzuk barru. Barka, baina erabiltzaile hau blokeatuta dago Commonsen Zure bi faktoreko autentifikazio kodea eman behar duzu. - Saio hasieran akatsa + Saio hasieran akatsa Igo Izena eman bilduma honi Aldaketak @@ -114,6 +121,7 @@ Eman izena Nabarmendutako irudiak Kategoria + Parekoen Ebaluazioa Honi buruz Wikimedia Commons iturri-irekiko aplikazioa da Wikimedia komunitateko bolondresek sortu eta mantendutakoa. Wikimedia Fundazioa ez dago aplikazioaren sorreran, garapenean, edota mantenuan ibili. <a href=\"%1$s\">GitHub-eko gai</a> berria sortu errore eta iradokizunen berri emateko. @@ -150,6 +158,7 @@ Mesedez EZ igo: Autorretratuak edo zure lagunen argazkiak Internetetik jaitsitako irudiak + Aplikazio jabedunen pantaila-irudiak Igoera adibidea: Izenburua: Sydney Opera House Deskribapena: Sydney Opera House badiaren beste aldetik ikusita @@ -206,6 +215,7 @@ Honi buruz Ezarpenak Feedback + Github-en bidez berrelikatu Saioa itxi Tutoriala Jakinarazpenak @@ -215,9 +225,12 @@ Wikidata itema Wikipediako artikulua 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 ordutan hartu den. Multimediak zerbait berezia erakusten badu, mesedez azaldu zerk egiten duen berezia. + Irudi honen arazo potentzialak: Irudia ilunegia da. + Argazkia lausoa da. Irudia Commonsen badago. Irudi hau beste leku batean hartu da. + Oraindik igo nahi al duzu argazki hau? Konektatzeko Errorea Arazoak aurkitu dira irudian Irudiak aplikazioan gorde @@ -273,6 +286,7 @@ Elementuak Nabarmendua Mugikorretik igota + Mapa Irudia gehitu da %1$s-(e)ra Wikidatan! Ezin izan da dagokion Wikidata entitatea eguneratu! Horma-paper gisa ezarri @@ -328,6 +342,7 @@ Lastermarkak Lastermarkak Leku honetan bilatu + Hainbeste ekarpen egin dituzu, non gure lorpenetarako kalkulu-sistema ez den iristen. Hau da lorpen handiena. Egina Hurrengo orria Bai, zergatik ez @@ -344,6 +359,8 @@ Prentsarako argazkia Logo Arrakasta + Oraindik ez duzu ekarpenik egin + %s(r)ek oraindik ez du ekarpenik egin Hobespenak Iluna Argia @@ -358,4 +375,5 @@ Zenbaketa Igo Hurbilekoak + Erabiltzailearen ekarpenak: %s diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 3d3e66f6a..841160581 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -73,7 +73,6 @@ بازخورد حریم خصوصی ویکی‌انبار - تنظیمات بارگذاری در انبار بارگذاری در جریان است diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index cf791f71b..312ebc84c 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -68,7 +68,6 @@ Palaute Yksityisyys Commons - Asetukset Tallenna Commonsiin Tallennus käynnissä diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 867ca480c..10f601516 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -101,7 +101,6 @@ Commentaire Confidentialité Commons - •&#32; Paramètres Téléverser sur Commons Chargement en cours @@ -815,6 +814,8 @@ Merci de saisir vos commentaires Discussion Ecrivez quelque chose sur l\'article \"%1$s\". Il sera visible par le public\nAjouter une définition terminologique pour ce terme + \'%1$s\' n\'existe plus, aucune photo ne pourra jamais en être prise. + \'%1$s\' se trouve à un endroit différent. Veuillez indiquer l\'endroit correct ci-dessous et, si possible, indiquez la latitude et la longitude correctes. Autre problème ou information (merci d\'expliquer ci-dessous). Vos commentaires sont publiés sur la page wiki suivante : <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> Ne peut pas supporter les données diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index 854988ce0..1740c1890 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -10,13 +10,27 @@ * Mguix * Toliño * Vivaelcelta +* Xosecalvo --> Páxina de Commons en Facebook Código fonte de Commons en Github Logo de Commons Sitio web de Commons + Saír do selector de localización Enviar + Engadir outra descrición + Engadir unha nova achega + Engadir achega desde cámara + Engadir achega desde Photos + Engadir achega desde galería de achegas previas + Lendas + Descrición da lingua + Lenda + Descrición + Imaxe + Todo + Vista de busca Imaxe do día Cargando %1$d ficheiro @@ -52,9 +66,9 @@ Comentarios Privacidade Commons - Configuracións Cargar en Commons + Envío en curso Nome de usuario Contrasinal Acceda á súa conta de Commons Beta @@ -63,18 +77,25 @@ Rexistrarse Accedendo ao sistema Por favor, agarde… - Accedeu correctamente! - Erro durante o inición de sesión! + A actualizar lendas e descricións + Agarde un chisco… + Accedeu correctamente! + Erro durante o inició de sesión! Ficheiro non atopado. Por favor, probe con outro. - Erro de autenticación, por favor inicia unha nova sesión + Alcanzouse o límite máximo de reintentos! Cancele o envío e ténteo de novo + Desactivar a optimización da batería? + Fallou a autenticación. Inicie sesión de novo. A carga comezou! + Envío en cola (modo de conexión limitado activado) Cargouse \"%1$s\"! Prema para ollar a súa carga - Comezando a carga de \"%1$s\" + A enviar ficheiro: %s Cargando \"%1$s\" Rematando a carga de \"%1$s\" - Erro ao cargar \"%1$s\" + Produciuse un erro ao enviar %1$s + Deteuse o envío de %1$s Prema para amosalo + Toque para ver As miñas subas recentes Na cola Erróneo @@ -85,13 +106,15 @@ Preto As miñas subidas Compartir + Ver a páxina do ficheiro Lenda (Obrigatoria) Descrición - Erro ao acceder ao sistema: Fallou a rede + Lenda + Non foi posíbel acceder ao sistema - fallou a rede Demasiados intentos incorrectos. Inténteo de novo nuns minutos. Sentímolo, este usuario está bloqueado en Commons Debe proporcionar o seu código de autenticación de dous factores. - Erro durante o inición de sesión + Fallou o inicio de sesión Subir Dea un nome a este conxunto Modificacións @@ -102,11 +125,13 @@ Lista (Aínda non hai subas) Non se atopou ningunha categoría que coincidise con \"%1$s\" + Non se atopou ningún elemento de Wikidata que coincida con %1$s Engada categorías para facer máis accesibles as súas imaxes na Wikimedia Commons.\nComece a escribir para engadir categorías. Categorías Configuracións Rexistrarse Imaxes destacadas + Selector personalizado Categoría Revisión por pares Acerca de @@ -160,6 +185,7 @@ Categorías Cargando… Ningunha seleccionada + Sen lenda Sen descrición Sen conversas Licenza descoñecida @@ -170,8 +196,11 @@ Pedindo Permiso de Localización Aceptar Aviso + Atopouse un nome de ficheiro duplicado + Enviar Si Non + Lenda Título Descrición Conversa @@ -219,6 +248,8 @@ Esta imaxe foi realizada nunha localización diferente. Por favor sube so fotografías feitas por ti mesmo. Non subas imaxes ou fotografías que atopes nas contas de Facebook de outros. Aínda quere subir esta imaxe? + Erro de conexión + O proceso de envío require acceso activo a Internet. Comprobe a súa conexión de rede. Por favor suba so fotografías feitas por vostede mesmo. Non suba imaxes ou fotografías que descargara da Internet. Gardar fotos tiradas na aplicación Gardar ao almacenamento interno as fotografías tiradas na aplicación @@ -232,8 +263,8 @@ Ver páxina web para máis detalles Omitir Acceder ao sistema - Realmente quere saltar o inicio de sesión? - Terá que iniciar sesión para subir imaxes no futuro. + Confirma quequere saltar o inicio de sesión? + Terá que iniciar sesión para enviar imaxes no futuro. Por favor, inicie a sesión para usar esta funcionalidade Copiar o texto wiki ó portapapeis Texto wiki copiado ó portapapeis @@ -245,6 +276,7 @@ COMMONS Avalíenos FAQ + Guía de uso Saltar titorial Internet non dispoñible Erro ó recuperar as notificacións @@ -257,6 +289,9 @@ Cancelar Reintentar Hai sitios preto de vostede que precisan fotos para ilustrar os seus artigos de Wikipedia + Este lugar precisa dunha foto. + Este lugar xa ten unha foto. + Este lugar xa non existe. Non se atopou ningunha imaxeǃ Houbo un erro ó subir as imaxes. Subida porː %1$s @@ -271,8 +306,10 @@ Houbo un erro ó cargar categorías. Multimedia Categorías + Elementos Destacadas Cargada vía móbil + Mapa A imaxe engadiuse a %1$s en Wikidata! Fallou a actualización da entidade do Wikidata correspondente! Poñer como imaxe de fondo @@ -290,21 +327,27 @@ Fotografiás que amosen tecnoloxía ou cultura son moi benvidas en Commons Acadou un %1$s de respostas correctas. Parabéns! Escolla unha das dúas opcións para contestar a pregunta - A sesión caducou, por favor inicia unha nova sesión. + O inicio de sesión caducou. Inicie sesión de novo. Comparta o seu cuestionario cos seus amigos! Continuar Resposta correcta Resposta incorrecta Pódese subir esta captura de pantalla? Compartir a aplicación - Erro ó procurar os lugares próximos. + Xirar + Non foi posíbel cargar lugares próximos + Non hai imaxes nesta zona + Non hai lugares próximos + Produciuse un erro ao buscar monumentos próximos. Non hai procuras recentes Está seguro de querer borrar o seu historial de procuras? + Confirma que quere cancelar este envío? Queres borrar esta procura? Eliminouse o historial de procuras Nomear para borrado Borrar Logros + Perfil Estatísticas Agradecementos recibidos Imaxes destacadas @@ -355,18 +398,22 @@ Dámoslle a benvida ó Commonsǃ\n\nCargue o seu primeiro ficheiro premendo no botón Engadir. Non hai categorías seleccionadas As imaxes sen categorías só son utilizables en contadas ocasións. Está seguro de que quere continuar sen seleccionar categorías? - (Para tódalas imaxes no conxunto) + Cancelar envío + Continuar co envío + (Para tódalas imaxes do conxunto) Procurar nesta área Solicitude de permisos Desexa que usemos a súa localizacións actual para amosarlle o lugar máis preto que precisa imaxes? Imposible amosar o sitio máis achegado que precisa fotos sen ter permisos de localización Non volver a preguntar isto nunca - Amosar permiso de localización + Solicitar permiso de localización Pedir permisos de localización cando sexa necesario para a funcionalidade de notificación de proximidade. Algo foi mal, non puidemos obter as túas achegas Finaliza o: Amosar campañas Ver as campañas en curso + Permitir + Descartar Xa non verá as campañas. Porén, pode volver habilitar esta notificación na configuración. Esta función require conexión de rede, verifique a súa configuración de conexión. Houbo un erro ó procesar a imaxe. Por favor, ténteo de novoǃ @@ -383,8 +430,8 @@ Enviando agradecementos: Éxito Enviado correctamente o agradecemento a %1$s Enviando agradecementos por %1$s - Si, por que non - Seguinte imaxe + Imaxe seguinte + Si, por que non Ningunha imaxe usada Ningunha imaxe revertida Ningunha imaxe subida @@ -396,6 +443,8 @@ Houbo un erro ó escoller as imaxes Por favor, agarde… Saltar esta imaxe + Xestionar etiquetas EXIF + Seleccione que etiquetas EXIF manter nos envíos Autor Dereitos de autoría Localización @@ -407,16 +456,43 @@ Información da imaxe Non se atoparon categorías Cancelouse a carga + Lingua de descrición predeterminada Nomeando para borrado Todo correcto Fallou - Un autorretrato + Non foi posíbel solicitar a eliminación. + Un autorretrato que non se emprega en ningún artigo Borrosa Sen sentido Foto de prensa Foto aleatoria de internet Logo Porque é + Todo correcto + + Engádese a categoría %1$s . + Engádense as categorías %1$s . + + Non foi posíbel engadir categorías. + Actualizar categorías + A tentar actualizar representacións. + Editar representacións + + Engádese a representación %1$s . + Engádense as representacións %1$s . + + Non foi posíbel engadir representacións. + A tentar actualizar coordenadas. + Actualización de coordenadas + Actualización da descrición + Actualización da lenda + Todo correcto + Engádense as coordenadas %1$s . + Engádense as descricións. + Engádese a lenda. + Non foi posíbel engadir as coordenadas. + Non foi posíbel engadir descricións. + Non foi posíbel engadir lenda. Compartir imaxe vía Conta creada! Existe @@ -429,4 +505,28 @@ Definir como fondo de pantalla Escuro Claro + Melloras suxeridas: + - Engadir categorías a esta imaxe para mellorar a usabilidade. + - Engade esta imaxe ao artigo asociado da Wikipedia que non ten imaxes. + Engadir imaxe á Wikipedia + Confirmar + Instrucións + 7. Publicar o artigo + pausar + continuar + En pausa + Máis + Marcadores + Logros + Tǃboa de maior actividade + Clasificaciónː + Número: + Clasificación + Establecer como avatar + Anualmente + Semanalmente + Todo o tempo + Enviar + A miña clasificación + Activouse o modo de conexión limitadoǃ diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 7cfc785f2..50a04319b 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -4,6 +4,7 @@ * Abijeet Patro * Anamdas * Anandra +* AnupamM * Bhatakati aatma * Gopalindians * Nilesh shukla @@ -60,7 +61,6 @@ आपके सुझाव गोपनीयता कॉमन्स - सेटिंग्स कॉमन्स पर अपलोड करें सदस्य नाम @@ -349,4 +349,9 @@ गणना रद्द करें वार्ता + क्या आप वाकई सभी अपलोड रद्द करना चाहते हैं? + सभी अपलोड रद्द किये जा रहे हैं... + अपलोड + लंबित + विफल हुआ diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 393689f45..d2d731c39 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -37,7 +37,6 @@ Povratna informacija Privatnost Zajednički poslužitelj - Postavke Prenesi na Zajednički poslužitelj Suradničko ime diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index b248a64f2..aefc17d9d 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -58,7 +58,6 @@ Visszajelzés Adatvédelem Commons - Beállítások Feltöltés a Commonsra Feltöltés folyamatban diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index c4404bce6..0e595af04 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -766,7 +766,7 @@ Per favor insere alcun commentos Discussion ‘%1$s’ non existe plus, necun imagine pote jammais esser prendite de illo. - \'%1$s\' es in un altere loco (per favor specifica le loco correcte hic infra, si possibile indica le latitude/longitude correcte). + ‘%1$s’ es in un altere loco. Per favor specifica le loco correcte hic infra, e si possibile, indica le latitude e longitude correcte. Altere problema o information (per favor explica hic infra). Tu retroaction apparera sur le sequente pagina wiki: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 18cd57892..219fa4521 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -3,8 +3,10 @@ * Agam Riyandana * Akmaie Ajam * Arifin.wijaya +* Birusian * DARMAS BUDI SANTOSO * Daud I.F. Argana +* Fafau06 * Farras * Gombang * Hidayatsrf @@ -68,7 +70,6 @@ Umpan balik Privasi Commons - Pengaturan Unggah ke Commons Pengunggahan sedang berlangsung @@ -240,6 +241,7 @@ Perihal Pengaturan Umpan balik + Ulasan melalui GitHub Keluar Tutorial Pemberitahuan @@ -349,6 +351,7 @@ Bagikan Aplikasi Putar Galat saat mengambil tempat terdekat. + Tidak ada gambar di area ini Tidak ditemukan tempat yang dekat Galat saat mengambil monumen terdekat. Tidak ada pencarian terbaru @@ -729,7 +732,19 @@ Pelajari cara menulis deskripsi yang berguna Pelajari cara menulis takarir yang berguna Lihat pencapaian Anda + Edit Gambar + Edit Lokasi + Lokasi diperbarui! + Hapus Lokasi + Hapus Peringatan Lokasi + Lokasi membuat gambar lebih berguna dan mudah ditemukan. Apakah Anda benar-benar ingin menghapus lokasi dari gambar ini? + Lokasi dihapus! %d gambar dipilih + Bicara + Membatalkan semua unggahan... + Unggahan + Menunggu + Gagal diff --git a/app/src/main/res/values-io/strings.xml b/app/src/main/res/values-io/strings.xml index c965b2585..51fe16441 100644 --- a/app/src/main/res/values-io/strings.xml +++ b/app/src/main/res/values-io/strings.xml @@ -136,7 +136,7 @@ Pri La programo \'\'app\'\' di Wikimedia Commons esas libera di autoroyuro, e kreesis e mantenesas da volontarii de la komunitato Wikimedia. La Fonduro Wikimedia ne partoprenas en lua kreo, developo o manteno. Krear nova <a href=\"%1$s\">GitHub temo</a> por raporti pri \'\'bugs\'\' e sugesti. - Sistemo di agado pri privateso + Nia politiki pri privateso Kreinto o kreinti Pri Sendez komenti (per e-posto) diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 188504dcd..417652953 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -60,7 +60,6 @@ Umsagnir Persónuvernd Commons - • \\ Stillingar Senda inn á Commons Notandanafn diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 91e5331a3..be69fa045 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -8,6 +8,7 @@ * Black Sky83 * Champ0999 * Davio +* Dream Indigo * Gianfranco * Lorelai87 * Lorem Ipsum @@ -78,7 +79,6 @@ Feedback Privacy Commons - Impostazioni Carica su Commons Caricamento in corso @@ -127,7 +127,7 @@ Didascalia Impossibile accedere: errore di rete Troppi tentativi falliti. Riprova tra alcuni minuti. - Spiacente, questo utente è stato bloccato su Commons + Spiacente, quest\'utente è stato/a bloccato/a su Commons Devi fornire il tuo codice di autenticazione a due fattori. Accesso non riuscito Carica @@ -737,9 +737,9 @@ Imposta lo sfondo bianco Imposta lo sfondo nero Segnala violazione - Segnala questo utente + Segnala quest\'utente Segnala questo contenuto - Richiedi di bloccare questo utente + Richiedi di bloccare quest\'utente Benvenuto nella modalità di selezione a schermo intero Usa due dita per ingrandire e rimpicciolire. Scorri velocemente e a lungo per eseguire queste azioni: \n- Sinistra/destra: vai al precedente/successivo \n- Su: seleziona\n- Giù: contrassegna come da non caricare. diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 2044e75eb..0b512102b 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -91,7 +91,6 @@ משוב פרטיות ויקישיתוף - הגדרות להעלות לוויקישיתוף מתבצעת העלאה @@ -815,5 +814,10 @@ \"%1$s\" נמצא במקום אחר. נא לציין את המקום הנכון למטה, ואם אפשר, לכתוב את קו הרוחב ואת קו האורך הנכונים. בעיה אחרת או מידע אחר (נא להסביר הלאה). המשוב שלך מתפרסם בדף הוויקי הבא: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> + האם ברצונך באמת לבטל את כל ההעלאות? + ביטול כל ההעלאות... + העלאות + ממתינות + נכשלו לא היה אפשר לטעון את נתוני המקום diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index b004f6c00..6fb40d2ff 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -71,7 +71,6 @@ フィードバック プライバシー コモンズ - 設定 コモンズにアップロード アップロード中 diff --git a/app/src/main/res/values-ji/strings.xml b/app/src/main/res/values-ji/strings.xml index 29413ab3e..0d6cf62a8 100644 --- a/app/src/main/res/values-ji/strings.xml +++ b/app/src/main/res/values-ji/strings.xml @@ -27,7 +27,6 @@ אַלגעמיין פֿידבעק קאמאנס - איינשטעלונגען באַניצער־נאָמען פאַסווארט diff --git a/app/src/main/res/values-jv/strings.xml b/app/src/main/res/values-jv/strings.xml index 462c6e312..e775ba274 100644 --- a/app/src/main/res/values-jv/strings.xml +++ b/app/src/main/res/values-jv/strings.xml @@ -35,7 +35,6 @@ Umum Pamrayoga Commons - Setèlan Unggah menyang Commons Jeneng naraguna diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index eb257b9cc..e6834c728 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -53,7 +53,6 @@ უკუკავშირი კონფიდენციალურობა ვიკისაწყობი - კონფიგურაცია ვიკისაწყობში ატვირთვა მიმდინარეობს ატვირთვა diff --git a/app/src/main/res/values-ko-rKP/strings.xml b/app/src/main/res/values-ko-rKP/strings.xml index d7a621356..b58b509c7 100644 --- a/app/src/main/res/values-ko-rKP/strings.xml +++ b/app/src/main/res/values-ko-rKP/strings.xml @@ -32,7 +32,6 @@ 일반 반결합 공용 - 설정 공용에 올리적재 사용자 이름 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 52bb0a7ac..b729838b9 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -73,7 +73,6 @@ 피드백 개인정보 공용 - 설정 공용에 업로드 업로드 진행 중 diff --git a/app/src/main/res/values-ku/strings.xml b/app/src/main/res/values-ku/strings.xml index 017f5ba6f..506e9e4b4 100644 --- a/app/src/main/res/values-ku/strings.xml +++ b/app/src/main/res/values-ku/strings.xml @@ -61,7 +61,6 @@ Paşragihandin Veşarîtî Commons - Eyar Li Commons-ê bar bike Navê bikarhêner diff --git a/app/src/main/res/values-kum/strings.xml b/app/src/main/res/values-kum/strings.xml index dee29e8a0..8112afea6 100644 --- a/app/src/main/res/values-kum/strings.xml +++ b/app/src/main/res/values-kum/strings.xml @@ -7,7 +7,6 @@ Ортакъ Герибилдирим Энчилик - Кюйлевлер Къоллавчу аты Чечил diff --git a/app/src/main/res/values-lb/strings.xml b/app/src/main/res/values-lb/strings.xml index dc8beda58..9d69efabb 100644 --- a/app/src/main/res/values-lb/strings.xml +++ b/app/src/main/res/values-lb/strings.xml @@ -49,7 +49,6 @@ Feedback Dateschutz Commons - Astellungen Op Commons eroplueden Eroplueden amgaang @@ -66,6 +65,7 @@ Umeldung huet geklappt! D\'Aloggen huet net funktionéiert! Fichier net fonnt. Probéiert wgl. en anere Fichier. + Batterieoptiméierung deaktivieren? D\'Authentifizéierung huet net funktionéiert. Loggt Iech wgl. nach eng Kéier an. D\'Eroplueden huet ugefaang! %1$s eropgelueden! diff --git a/app/src/main/res/values-li/strings.xml b/app/src/main/res/values-li/strings.xml index ec93ae886..f477ed8f0 100644 --- a/app/src/main/res/values-li/strings.xml +++ b/app/src/main/res/values-li/strings.xml @@ -26,7 +26,6 @@ Algemein Feedback Commons - Instèllinge Gebroekersnaam Wachwaord diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index e7ee99831..22749651c 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -55,7 +55,6 @@ Atsiliepimai Privatumas Vikiteka - Nustatymai Įkelti į Vikiteką Naudotojo vardas diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 615c7a8da..7a6d9e362 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -12,7 +12,6 @@ Atsauksmes Konfidencialitāte Commons - Iestatījumi Augšupielādēt Commons Lietotājvārds diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index 016d7338d..00a8ba098 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -61,7 +61,6 @@ Мислења Лични податоци Ризница - Поставки Подигни на Ризницата Подигањето е во тек @@ -779,5 +778,10 @@ „%1$s“ се наоѓа на друго место. Подолу укажете го исправното место и, ако е можно, ставете исправна географска ширина и должина. Друг проблем или информација (објаснете подолу). Вашите мислења се објавуваат на следнава викистраница: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> + Дали сигурно сакате да ги откажете сите подигања? + Ги откажувам сите подигања... + Подигања + Во исчекување + Неуспешно Не можев да ги вчитам податоците за место diff --git a/app/src/main/res/values-mni/strings.xml b/app/src/main/res/values-mni/strings.xml index 4991e2592..de888dcbc 100644 --- a/app/src/main/res/values-mni/strings.xml +++ b/app/src/main/res/values-mni/strings.xml @@ -10,7 +10,6 @@ ꯅꯨꯃꯤꯠꯁꯤꯒꯤ ꯃꯤꯔꯦꯜ ꯑꯔꯣꯟꯕꯥ ꯀꯣꯃꯣꯟꯁ - ꯁꯦꯝꯐꯝ ꯀꯃꯣꯟꯁꯇ ꯈꯥꯒꯠꯂꯨ ꯁꯤꯖꯤꯟꯅꯔꯤꯕ ꯃꯃꯤꯡ diff --git a/app/src/main/res/values-mnw/strings.xml b/app/src/main/res/values-mnw/strings.xml index 99d1e733a..a6c18bca3 100644 --- a/app/src/main/res/values-mnw/strings.xml +++ b/app/src/main/res/values-mnw/strings.xml @@ -36,7 +36,6 @@ ကဵုကသပ် မဒှ်ဒြပ်ပူဂဵု ကောမ္မောန် - ဖျေဟ်ဒၞာဲ ပတိုန်ပၠုပ် ပ္ဍဲကောမ်မောန် ယၟုညးလွပ် @@ -50,7 +49,7 @@ လုက်အေန် အာစိုပ်ဒတုဲ! လံက်အေန် လီုလာ်! ဝှာင် ဟွံဂွံဆဵု၊ ပဂုန်တုဲ ဂၠာဲ ဝှာင်တၞဟ်။ - ပွမစၟဳစၟတ်ဂှ် ဟွံအံင်ဇၞး။ ပဂုန်တုဲ လံက်အေန် မွဲဝါပၠန် + ပွမစၟဳစၟတ်ဂှ် ဟွံအံင်ဇၞး။ ပဂုန်တုဲ လံက်အေန် မွဲဝါပၠန် ပတိုန်ဝှာင် စဒၟံင်ရ! %1$s ပတိုန်ပၠုပ်တုဲ! ဒၞာဲမကလေင်ရံင် ဝှာင်ပတိုန်ပၠုပ် မၞး @@ -69,11 +68,12 @@ ဗဒဲါဒၞာဲဏအ် ပတိုန်ပၠုပ် ဇကုဂမၠိုင် ပါ်ပရအ် + ဗဵု မုက်လိက် ဝှာင် က္ဍိုပ်လိက် (အာတ်မိက်ဒၟံင်) ပဂုန်တုဲ ကဵု က္ဍိုပ်လိက် ဝှာင်ဏအ်ညိ မဗမံက်ထ္ၜး - က္ဍိုပ်လိက် (ပိုင်ခြာလဝ် လၟိဟ်မလိက် ၂၅၅) - လုပ်လံက်အေန် ဟွံဂွံ - ဇာဇၞိက် ဗၠေတ် + က္ဍိုပ်လိက် + လုပ်လံက်အေန် ဟွံဂွံ - ဇာဇၞိက် ဗၠေတ် ပရေင်ဂိုတ်ဂစာန် ဟွံအံင်ဇၞး ဂၠိုင်လောန်အာရ။ ပဂုန်တုဲ မိနေတ်ညိညပၠန် ကလေင်စမ်ပၠန်။ သၠးအခေါင်၊ ညးလွပ်ဏအ် ဒးဒုင်ကၟာတ်လဒဵုလဝ် ပ္ဍဲ ကောမ်မောန် ကုစၟဳစၟတ်မၞးၜါဂှ် သ္ဒးပါ်လဝ် ဗွဲတၞဟ်ခြာရောင်။ @@ -85,7 +85,7 @@ ဂၠာဲ ကဏ္ဍဂမၠိုၚ် ဂၠာဲ တင်ဂၞင် မၞိဟ်မဗၟံက်ထ္ၜး (မပတံ ဒဵု၊ ဍုင်လ္ဂုင်) ဂိုင်သိပ် - ကလေင်မၚုဟ် + ကလေင်မင္ၚုဟ် စရၚ် ဟွံဂွံ ပတိုန်ပၠုပ်ဏီ ကဏ္ဍ မကိတ်ညဳ ကု %1$s ဟွံဆဵု diff --git a/app/src/main/res/values-mr/strings.xml b/app/src/main/res/values-mr/strings.xml index 491e5f2b2..546b43f4f 100644 --- a/app/src/main/res/values-mr/strings.xml +++ b/app/src/main/res/values-mr/strings.xml @@ -34,7 +34,6 @@ सामान्य अभिप्राय कॉमन्स - सेटिंग्स सदस्यनाव परवलीचा शब्द(पासवर्ड) diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml index 4c4661175..1fce0c0da 100644 --- a/app/src/main/res/values-my/strings.xml +++ b/app/src/main/res/values-my/strings.xml @@ -41,7 +41,6 @@ အကြံပေးရန် ကိုယ်ရေးမူဝါဒ ကွန်မွန်းစ် - အပြင်အဆင်များ ကွန်မွန့်စ်တွင် တင်ရန် အသုံးပြုသူအမည် diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 63e192cc9..727ec7aba 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -69,7 +69,6 @@ Tilbakemelding Personvern Commons - Innstillinger Last opp til Commons Opplasting pågår diff --git a/app/src/main/res/values-ne/strings.xml b/app/src/main/res/values-ne/strings.xml index 93e27d1db..2687c5e07 100644 --- a/app/src/main/res/values-ne/strings.xml +++ b/app/src/main/res/values-ne/strings.xml @@ -27,7 +27,6 @@ प्रतिक्रिया गोपनीयता कमन्स - मेरो अभिरुचिहरू कमन्समा उर्ध्वभरण गर्नुहाेस् प्रयोगकर्ता नाम diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 25af749e6..aeb8eab94 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -82,7 +82,6 @@ Terugkoppeling Privacy Commons - Instellingen Uploaden naar Commons Aan het uploaden @@ -800,5 +799,10 @@ ‘%1$s’ bevindt zich ergens anders. Geef hieronder de juiste plaats aan en noteer, indien mogelijk, de juiste breedte- en lengtegraad. Ander probleem of andere informatie (verklaar hieronder). Uw feedback wordt op de volgende wikipagina geplaatst: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> + Weet u zeker dat u alle uploads wilt annuleren? + Alle uploads worden geannuleerd… + Uploads + In behandeling + Mislukt Plaatsgegevens konden niet geladen worden diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 072882852..dcd8ea284 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -97,7 +97,6 @@ Opinia Prywatność Commons - Ustawienia Prześlij do Commons Przesyłanie w toku diff --git a/app/src/main/res/values-pms/strings.xml b/app/src/main/res/values-pms/strings.xml index 0b92fb404..788a34a4b 100644 --- a/app/src/main/res/values-pms/strings.xml +++ b/app/src/main/res/values-pms/strings.xml @@ -59,7 +59,6 @@ Sugeriment Confidensialità Comun - Paràmeter Carié su Commons Cariament an cors @@ -775,5 +774,10 @@ \'%1$s\' a l\'é ant un pòst diferent. Për piasì, ch\'a spessìfica ël pòst giust sì-sota e, si possìbil, ch\'a scriva latitùdin e longitùdin giuste. Àutr problema o anformassion (për piasì, ch\'a spiega sì-sota). Ij sò sugeriment a saran giontà a coste pàgine wiki: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> + É-lo sigur ëd vorèj anulé tuti ij cariament? + Anulament ëd tuti ij cariament... + Cariament + An atèisa + Falì Impossìbil carié ij dàit dël pòst diff --git a/app/src/main/res/values-ps/strings.xml b/app/src/main/res/values-ps/strings.xml index 36ccc9f46..4f17da26f 100644 --- a/app/src/main/res/values-ps/strings.xml +++ b/app/src/main/res/values-ps/strings.xml @@ -14,7 +14,6 @@ دا انځور به د %1$s په منښتليک سمبال وي. ويکي خونديځ - امستنې کارن-نوم پټنوم diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 5fe7223fe..3779a8a51 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -85,7 +85,6 @@ Comentário Privacidade Commons - Configurações Carregar no Commons Upload em progresso diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index b5fe1c23f..bad9dc500 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -77,7 +77,6 @@ Comentários Privacidade Commons - Configurações Carregar na wiki Commons Carregamento em progresso diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 3a3529ce3..0bcbc1550 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -64,7 +64,6 @@ Feedback Confidențialitate Commons - Setări Încarcă la Commons Încărcare în curs diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 3bfb44db2..ca771ea98 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -18,6 +18,7 @@ * Jesusmc * Kaganer * Kareyac +* Lutece398 * MaxBioHazard * McDutchie * Megakott @@ -115,7 +116,6 @@ Обратная связь Конфиденциальность Викисклад - Настройки Загрузить на Викисклад Идёт загрузка… @@ -839,5 +839,10 @@ \'%1$s\' находится в другом месте. Пожалуйста, укажите правильное место ниже и, если возможно, напишите правильную широту и долготу. Другая проблема или информация (пожалуйста, объясните ниже). Ваш отзыв будет опубликован на следующей вики-странице: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobile app/Feedback</a> + Вы уверены, что хотите отменить все загрузки? + Отмена всех загрузок... + Загрузки + В ожидании + Не удалось Не удалось загрузить данные о месте diff --git a/app/src/main/res/values-sd/strings.xml b/app/src/main/res/values-sd/strings.xml index a9159264c..08f9a1fec 100644 --- a/app/src/main/res/values-sd/strings.xml +++ b/app/src/main/res/values-sd/strings.xml @@ -57,7 +57,6 @@ موٽ نويڪلائي العام - ترتيبون العام ۾ چاڙهيو واپرائيندڙنانءُ diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 3c5548be5..53d14e226 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -81,7 +81,6 @@ Spätná väzba Súkromie Commons - Nastavenia Nahrať na Commons Používateľské meno diff --git a/app/src/main/res/values-skr/strings.xml b/app/src/main/res/values-skr/strings.xml index 1c26fe048..4c68ee91b 100644 --- a/app/src/main/res/values-skr/strings.xml +++ b/app/src/main/res/values-skr/strings.xml @@ -23,7 +23,6 @@ تہاڈی رائے رازداری کامنز - ترتیباں کامنز تے اپ لوڈ کرو ورتݨ آلا ناں @@ -270,4 +269,7 @@ رپورٹ مصنف کوں شکریہ بھیڄݨ وچ خرابی۔ ڳالھ مہاڑ + اپلوڈاں + وچار ہیٹھ + ناکام تھیا diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 514c8da9f..61531980f 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -77,7 +77,6 @@ Povratne informacije Zasebnost Zbirka - Nastavitve Naloži v Zbirko Nalaganje poteka diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 4bef698e2..fe70bc6b6 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -67,7 +67,6 @@ Повратне информације Приватност Остава - Подешавања Отпреми на Оставу Отпремање у току @@ -735,4 +734,7 @@ Унесите коментар Разговор „%1$s” не постоји више, и није га могуће више сликати. + Отпремања + На чекању + Није успело diff --git a/app/src/main/res/values-su/strings.xml b/app/src/main/res/values-su/strings.xml index e96b72158..79ae5ea28 100644 --- a/app/src/main/res/values-su/strings.xml +++ b/app/src/main/res/values-su/strings.xml @@ -60,7 +60,6 @@ Eupan balik Privasi Commons - Séting Unjal ka Commons Sandiasma diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 35a11ce0b..370bf0915 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -67,7 +67,6 @@ Återkoppling Integritet Commons - Inställningar Ladda upp till Commons Uppladdning pågår @@ -783,5 +782,10 @@ \"%1$s\" är på en annan plats. Ange den korrekta platsen nedan samt ange latitud och longitud om det är möjligt. Andra problem eller information (ange nedan). Din återkoppling kommer att skickas till följande wikisida: <a href=\"https://commons.wikimedia.org/wiki/Commons:Mobile_app/Feedback\">Commons:Mobilapp/Återkoppling</a> + Är du säker på att du vill avbryta alla uppladdningar? + Avbryter alla uppladdningar... + Uppladdningar + Pågår + Misslyckades Kunde inte läsa in platsdata diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index e96ee7c20..f9162bc7b 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -26,7 +26,6 @@ பின்னூட்டம் அந்தரங்கம் பொதுவகம் - அமைப்புகள் பொதுவகத்துக்குப் பதிவேற்று பயனர் பெயர் diff --git a/app/src/main/res/values-tcy/strings.xml b/app/src/main/res/values-tcy/strings.xml index 8cecb413f..add46f7b7 100644 --- a/app/src/main/res/values-tcy/strings.xml +++ b/app/src/main/res/values-tcy/strings.xml @@ -46,7 +46,6 @@ ಸಾಮಾನ್ಯೊ ಅಬಿಪ್ರಾಯೊ ಕಾಮನ್ಸ್ - ಸಂಯೋಜನೆಲು ಕಾಮನ್ಸ್ ಗ್ ಸೆರಲೆ ಬಳಕೆದಾರೆರೆಪುದರ್ diff --git a/app/src/main/res/values-te/strings.xml b/app/src/main/res/values-te/strings.xml index 6f1217371..ae80a5335 100644 --- a/app/src/main/res/values-te/strings.xml +++ b/app/src/main/res/values-te/strings.xml @@ -50,7 +50,6 @@ ప్రతిస్పందన అంతరంగికత కామన్స్ - అమరికలు కామన్స్ లోకి ఎక్కించండి వాడుకరిపేరు diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 04d5e0c9b..125bba590 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -61,7 +61,6 @@ คำติชม ความเป็นส่วนตัว คอมมอนส์ - การตั้งค่า อัปโหลดไปคอมมอนส์ ชื่อผู้ใช้ diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index e03bae660..31a9f0b53 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -88,7 +88,6 @@ Geri bildirim Gizlilik Commons - Ayarlar Commons\'a yükle Yükleme devam etmekte diff --git a/app/src/main/res/values-ug/strings.xml b/app/src/main/res/values-ug/strings.xml index c0ca0cd73..2f189f48b 100644 --- a/app/src/main/res/values-ug/strings.xml +++ b/app/src/main/res/values-ug/strings.xml @@ -14,7 +14,6 @@ ئادەتتە ئىنكاس بايلىق ھەمبەھىرلەش - . تەڭشەكلەر ئورۇن بايلىقىنى يوللاش ئىشلەتكۇچى ئىسمى diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index b555fa582..9e821ae24 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -92,7 +92,6 @@ Зворотний зв\'язок Конфіденційність Вікісховище - Налаштування Завантажити до Вікісховища Триває вивантаження diff --git a/app/src/main/res/values-uz/strings.xml b/app/src/main/res/values-uz/strings.xml index bfb03280c..3576e0ce1 100644 --- a/app/src/main/res/values-uz/strings.xml +++ b/app/src/main/res/values-uz/strings.xml @@ -1,5 +1,6 @@