Merge remote-tracking branch 'origin/master' into dev

This commit is contained in:
Tobias Kaminsky 2024-04-18 03:42:43 +02:00
commit 44c2ec6508
116 changed files with 2258 additions and 1019 deletions

View file

@ -1,4 +1,4 @@
FROM ubuntu:jammy@sha256:77906da86b60585ce12215807090eb327e7386c8fafb5402369e421f44eff17e FROM ubuntu:jammy@sha256:1b8d8ff4777f36f19bfe73ee4df61e3a0b789caeff29caa019539ec7c9a57f95
ARG DEBIAN_FRONTEND=noninteractive ARG DEBIAN_FRONTEND=noninteractive
ENV ANDROID_HOME=/usr/lib/android-sdk ENV ANDROID_HOME=/usr/lib/android-sdk

View file

@ -39,7 +39,7 @@ jobs:
with: with:
swap-size-gb: 10 swap-size-gb: 10
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@df5a14dc28094dc936e103b37d749c6628682b60 # v3.25.0 uses: github/codeql-action/init@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Set up JDK 17 - name: Set up JDK 17
@ -53,4 +53,4 @@ jobs:
echo "org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" echo "org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
./gradlew assembleDebug ./gradlew assembleDebug
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@df5a14dc28094dc936e103b37d749c6628682b60 # v3.25.0 uses: github/codeql-action/analyze@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1

View file

@ -42,6 +42,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard. # Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning" - name: "Upload to code-scanning"
uses: github/codeql-action/upload-sarif@df5a14dc28094dc936e103b37d749c6628682b60 # v3.25.0 uses: github/codeql-action/upload-sarif@c7f9125735019aa87cfc361530512d50ea439c71 # v3.25.1
with: with:
sarif_file: results.sarif sarif_file: results.sarif

View file

@ -77,7 +77,7 @@ configurations.configureEach {
// semantic versioning for version code // semantic versioning for version code
def versionMajor = 3 def versionMajor = 3
def versionMinor = 29 def versionMinor = 30
def versionPatch = 0 def versionPatch = 0
def versionBuild = 0 // 0-50=Alpha / 51-98=RC / 90-99=stable def versionBuild = 0 // 0-50=Alpha / 51-98=RC / 90-99=stable

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@ import com.nextcloud.client.preferences.SubFolderRule;
import com.owncloud.android.AbstractIT; import com.owncloud.android.AbstractIT;
import com.owncloud.android.databinding.SyncedFoldersLayoutBinding; import com.owncloud.android.databinding.SyncedFoldersLayoutBinding;
import com.owncloud.android.datamodel.MediaFolderType; import com.owncloud.android.datamodel.MediaFolderType;
import com.owncloud.android.datamodel.SyncedFolder;
import com.owncloud.android.datamodel.SyncedFolderDisplayItem; import com.owncloud.android.datamodel.SyncedFolderDisplayItem;
import com.owncloud.android.ui.activity.SyncedFoldersActivity; import com.owncloud.android.ui.activity.SyncedFoldersActivity;
import com.owncloud.android.ui.dialog.SyncedFolderPreferencesDialogFragment; import com.owncloud.android.ui.dialog.SyncedFolderPreferencesDialogFragment;
@ -63,7 +64,8 @@ public class SyncedFoldersActivityIT extends AbstractIT {
MediaFolderType.IMAGE, MediaFolderType.IMAGE,
false, false,
SubFolderRule.YEAR_MONTH, SubFolderRule.YEAR_MONTH,
false); false,
SyncedFolder.NOT_SCANNED_YET);
SyncedFolderPreferencesDialogFragment sut = SyncedFolderPreferencesDialogFragment.newInstance(item, 0); SyncedFolderPreferencesDialogFragment sut = SyncedFolderPreferencesDialogFragment.newInstance(item, 0);
Intent intent = new Intent(targetContext, SyncedFoldersActivity.class); Intent intent = new Intent(targetContext, SyncedFoldersActivity.class);

View file

@ -201,7 +201,7 @@ class BackgroundJobManagerTest {
fun job_is_unique_and_replaces_previous_job() { fun job_is_unique_and_replaces_previous_job() {
verify(workManager).enqueueUniqueWork( verify(workManager).enqueueUniqueWork(
eq(BackgroundJobManagerImpl.JOB_CONTENT_OBSERVER), eq(BackgroundJobManagerImpl.JOB_CONTENT_OBSERVER),
eq(ExistingWorkPolicy.APPEND), eq(ExistingWorkPolicy.REPLACE),
argThat(IsOneTimeWorkRequest()) argThat(IsOneTimeWorkRequest())
) )
} }

View file

@ -0,0 +1,32 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.owncloud.android
import com.owncloud.android.datamodel.OCFile
import java.security.SecureRandom
open class EncryptionIT : AbstractIT() {
fun testFolder(): OCFile {
val rootPath = "/"
val folderPath = "/TestFolder/"
OCFile(rootPath).apply {
storageManager.saveFile(this)
}
return OCFile(folderPath).apply {
decryptedRemotePath = folderPath
isEncrypted = true
fileLength = SecureRandom().nextLong()
setFolder()
parentId = storageManager.getFileByDecryptedRemotePath(rootPath)!!.fileId
storageManager.saveFile(this)
}
}
}

View file

@ -836,7 +836,7 @@ public class EncryptionTestIT extends AbstractIT {
// Encryption // Encryption
Cipher encryptorCipher = EncryptionUtils.getCipher(Cipher.ENCRYPT_MODE, key, iv); Cipher encryptorCipher = EncryptionUtils.getCipher(Cipher.ENCRYPT_MODE, key, iv);
EncryptionUtils.encryptFile(file, encryptorCipher); EncryptionUtils.encryptFile(user.getAccountName(), file, encryptorCipher);
String encryptorCipherAuthTag = EncryptionUtils.getAuthenticationTag(encryptorCipher); String encryptorCipherAuthTag = EncryptionUtils.getAuthenticationTag(encryptorCipher);
// Decryption // Decryption

View file

@ -7,13 +7,18 @@
*/ */
package com.owncloud.android.utils package com.owncloud.android.utils
import com.owncloud.android.AbstractIT import com.owncloud.android.EncryptionIT
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl import com.owncloud.android.datamodel.ArbitraryDataProviderImpl
import com.owncloud.android.datamodel.e2e.v1.decrypted.Data
import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFile
import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1
import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedMetadata
import com.owncloud.android.lib.resources.e2ee.CsrHelper import com.owncloud.android.lib.resources.e2ee.CsrHelper
import com.owncloud.android.operations.RefreshFolderOperation
import org.junit.Assert.assertEquals import org.junit.Assert.assertEquals
import org.junit.Test import org.junit.Test
class EncryptionUtilsIT : AbstractIT() { class EncryptionUtilsIT : EncryptionIT() {
@Throws( @Throws(
java.security.NoSuchAlgorithmException::class, java.security.NoSuchAlgorithmException::class,
java.io.IOException::class, java.io.IOException::class,
@ -30,4 +35,25 @@ class EncryptionUtilsIT : AbstractIT() {
assertEquals(key, EncryptionUtils.getPublicKey(user, e2eUser, arbitraryDataProvider)) assertEquals(key, EncryptionUtils.getPublicKey(user, e2eUser, arbitraryDataProvider))
} }
@Test
@Throws(Exception::class)
fun testUpdateFileNameForEncryptedFileV1() {
val folder = testFolder()
val decryptedFilename = "image.png"
val mockEncryptedFilename = "encrypted_file_name.png"
val decryptedMetadata = DecryptedMetadata()
val filesData = DecryptedFile().apply {
encrypted = Data().apply {
filename = decryptedFilename
}
}
val files = mapOf(mockEncryptedFilename to filesData)
val metadata = DecryptedFolderMetadataFileV1(decryptedMetadata, files)
RefreshFolderOperation.updateFileNameForEncryptedFileV1(storageManager, metadata, folder)
assertEquals(folder.decryptedRemotePath.contains("null"), false)
}
} }

View file

@ -10,7 +10,7 @@ package com.owncloud.android.utils
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.nextcloud.client.account.MockUser import com.nextcloud.client.account.MockUser
import com.nextcloud.common.User import com.nextcloud.common.User
import com.owncloud.android.AbstractIT import com.owncloud.android.EncryptionIT
import com.owncloud.android.datamodel.OCFile import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.datamodel.e2e.v1.decrypted.Data import com.owncloud.android.datamodel.e2e.v1.decrypted.Data
import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1 import com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFolderMetadataFileV1
@ -21,13 +21,15 @@ import com.owncloud.android.datamodel.e2e.v2.decrypted.DecryptedUser
import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFiledrop import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFiledrop
import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFiledropUser import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFiledropUser
import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFolderMetadataFile import com.owncloud.android.datamodel.e2e.v2.encrypted.EncryptedFolderMetadataFile
import com.owncloud.android.operations.RefreshFolderOperation
import com.owncloud.android.util.EncryptionTestIT import com.owncloud.android.util.EncryptionTestIT
import junit.framework.TestCase.assertEquals import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertTrue import junit.framework.TestCase.assertTrue
import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNotEquals
import org.junit.Test import org.junit.Test
class EncryptionUtilsV2IT : AbstractIT() { @Suppress("TooManyFunctions", "LargeClass")
class EncryptionUtilsV2IT : EncryptionIT() {
private val encryptionTestUtils = EncryptionTestUtils() private val encryptionTestUtils = EncryptionTestUtils()
private val encryptionUtilsV2 = EncryptionUtilsV2() private val encryptionUtilsV2 = EncryptionUtilsV2()
@ -781,6 +783,21 @@ class EncryptionUtilsV2IT : AbstractIT() {
assertTrue(encryptionUtilsV2.verifySignedMessage(base64Ans, jsonBase64, certs)) assertTrue(encryptionUtilsV2.verifySignedMessage(base64Ans, jsonBase64, certs))
} }
@Test
@Throws(Exception::class)
fun testUpdateFileNameForEncryptedFile() {
val folder = testFolder()
val metadata = EncryptionTestUtils().generateFolderMetadataV2(
client.userId,
EncryptionTestIT.publicKey
)
RefreshFolderOperation.updateFileNameForEncryptedFile(storageManager, metadata, folder)
assertEquals(folder.decryptedRemotePath.contains("null"), false)
}
/** /**
* DecryptedFolderMetadata -> EncryptedFolderMetadata -> JSON -> encrypt -> decrypt -> JSON -> * DecryptedFolderMetadata -> EncryptedFolderMetadata -> JSON -> encrypt -> decrypt -> JSON ->
* EncryptedFolderMetadata -> DecryptedFolderMetadata * EncryptedFolderMetadata -> DecryptedFolderMetadata

View file

@ -174,7 +174,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
MediaFolderType.IMAGE, MediaFolderType.IMAGE,
false, false,
SubFolderRule.YEAR_MONTH, SubFolderRule.YEAR_MONTH,
false false,
SyncedFolder.NOT_SCANNED_YET
) )
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder)) Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
} }
@ -198,7 +199,8 @@ class SyncedFolderUtilsTest : AbstractIT() {
MediaFolderType.IMAGE, MediaFolderType.IMAGE,
false, false,
SubFolderRule.YEAR_MONTH, SubFolderRule.YEAR_MONTH,
false false,
SyncedFolder.NOT_SCANNED_YET
) )
Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder)) Assert.assertFalse(SyncedFolderUtils.isQualifyingMediaFolder(folder))
} }

View file

@ -42,8 +42,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.nextcloud.client.assistant.component.AddTaskAlertDialog import com.nextcloud.client.assistant.component.AddTaskAlertDialog
import com.nextcloud.client.assistant.component.CenterText import com.nextcloud.client.assistant.component.CenterText
import com.nextcloud.client.assistant.component.TaskTypesRow import com.nextcloud.client.assistant.taskTypes.TaskTypesRow
import com.nextcloud.client.assistant.component.TaskView import com.nextcloud.client.assistant.task.TaskView
import com.nextcloud.client.assistant.repository.AssistantMockRepository import com.nextcloud.client.assistant.repository.AssistantMockRepository
import com.nextcloud.ui.composeActivity.ComposeActivity import com.nextcloud.ui.composeActivity.ComposeActivity
import com.nextcloud.ui.composeComponents.alertDialog.SimpleAlertDialog import com.nextcloud.ui.composeComponents.alertDialog.SimpleAlertDialog

View file

@ -35,3 +35,8 @@ fun Task.statusData(): Pair<Int, Int> {
} }
} }
} }
// TODO add
fun Task.completionDateRepresentation(): String {
return completionExpectedAt ?: "TODO IMPLEMENT IT"
}

View file

@ -7,12 +7,14 @@
*/ */
package com.nextcloud.client.assistant.repository package com.nextcloud.client.assistant.repository
import com.nextcloud.utils.extensions.getRandomString
import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.resources.assistant.model.Task import com.owncloud.android.lib.resources.assistant.model.Task
import com.owncloud.android.lib.resources.assistant.model.TaskList import com.owncloud.android.lib.resources.assistant.model.TaskList
import com.owncloud.android.lib.resources.assistant.model.TaskType import com.owncloud.android.lib.resources.assistant.model.TaskType
import com.owncloud.android.lib.resources.assistant.model.TaskTypes import com.owncloud.android.lib.resources.assistant.model.TaskTypes
@Suppress("MagicNumber")
class AssistantMockRepository(private val giveEmptyTasks: Boolean = false) : AssistantRepositoryType { class AssistantMockRepository(private val giveEmptyTasks: Boolean = false) : AssistantRepositoryType {
override fun getTaskTypes(): RemoteOperationResult<TaskTypes> { override fun getTaskTypes(): RemoteOperationResult<TaskTypes> {
return RemoteOperationResult<TaskTypes>(RemoteOperationResult.ResultCode.OK).apply { return RemoteOperationResult<TaskTypes>(RemoteOperationResult.ResultCode.OK).apply {
@ -41,16 +43,8 @@ class AssistantMockRepository(private val giveEmptyTasks: Boolean = false) : Ass
null, null,
"12", "12",
"", "",
"Give me some text", "Give me some long text 1",
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. " + "Lorem ipsum".getRandomString(100),
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s," +
" when an unknown printer took a galley of type and scrambled it to make a type" +
" specimen book. It has survived not only five centuries, " +
"but also the leap into electronic typesetting, remaining essentially unchanged." +
" It was popularised in the 1960s with the release of Letraset sheets containing " +
"Lorem Ipsum passages, and more recently with desktop publishing software like Aldus" +
" PageMaker including versions of Lorem Ipsum",
"",
"" ""
), ),
Task( Task(
@ -60,7 +54,62 @@ class AssistantMockRepository(private val giveEmptyTasks: Boolean = false) : Ass
"12", "12",
"", "",
"Give me some text 2", "Give me some text 2",
"Lorem Ipsum is simply dummy text of the printing and typesetting industry.", "Lorem".getRandomString(100),
"",
""
),
Task(
3,
"FreePrompt",
null,
"12",
"",
"Give me some text 3",
"Lorem".getRandomString(300),
"",
""
),
Task(
4,
"FreePrompt",
null,
"12",
"",
"Give me some text 4",
"Lorem".getRandomString(300),
"",
""
),
Task(
5,
"FreePrompt",
null,
"12",
"",
"Give me some text 5",
"Lorem".getRandomString(300),
"",
""
),
Task(
6,
"FreePrompt",
null,
"12",
"",
"Give me some text 6",
"Lorem".getRandomString(300),
"",
""
),
Task(
7,
"FreePrompt",
null,
"12",
"",
"Give me some text 7",
"Lorem".getRandomString(300),
"", "",
"" ""
) )

View file

@ -0,0 +1,58 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.client.assistant.task
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.nextcloud.client.assistant.extensions.statusData
import com.owncloud.android.lib.resources.assistant.model.Task
@Composable
fun TaskStatus(task: Task, foregroundColor: Color) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
val (iconId, descriptionId) = task.statusData()
Image(
painter = painterResource(id = iconId),
modifier = Modifier.size(16.dp),
colorFilter = ColorFilter.tint(foregroundColor),
contentDescription = "status icon"
)
Spacer(modifier = Modifier.width(6.dp))
Text(text = stringResource(id = descriptionId), color = foregroundColor)
/*
Spacer(modifier = Modifier.weight(1f))
Text(text = task.completionDateRepresentation(), color = foregroundColor)
Spacer(modifier = Modifier.width(6.dp))
*/
}
}

View file

@ -1,27 +1,22 @@
/* /*
* Nextcloud - Android Client * Nextcloud - Android Client
* *
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper_ozturk@proton.me> * SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */
package com.nextcloud.client.assistant.component package com.nextcloud.client.assistant.task
import androidx.compose.animation.animateContentSize import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
@ -31,18 +26,15 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.nextcloud.client.assistant.extensions.statusData import com.nextcloud.client.assistant.taskDetail.TaskDetailBottomSheet
import com.nextcloud.ui.composeComponents.bottomSheet.MoreActionsBottomSheet import com.nextcloud.ui.composeComponents.bottomSheet.MoreActionsBottomSheet
import com.nextcloud.utils.extensions.getRandomString
import com.owncloud.android.R import com.owncloud.android.R
import com.owncloud.android.lib.resources.assistant.model.Task import com.owncloud.android.lib.resources.assistant.model.Task
@ -53,7 +45,7 @@ fun TaskView(
task: Task, task: Task,
showDeleteTaskAlertDialog: (Long) -> Unit showDeleteTaskAlertDialog: (Long) -> Unit
) { ) {
var expanded by remember { mutableStateOf(false) } var showTaskDetailBottomSheet by remember { mutableStateOf(false) }
var showMoreActionsBottomSheet by remember { mutableStateOf(false) } var showMoreActionsBottomSheet by remember { mutableStateOf(false) }
Column( Column(
@ -62,7 +54,7 @@ fun TaskView(
.clip(RoundedCornerShape(16.dp)) .clip(RoundedCornerShape(16.dp))
.background(MaterialTheme.colorScheme.primary) .background(MaterialTheme.colorScheme.primary)
.combinedClickable(onClick = { .combinedClickable(onClick = {
expanded = !expanded showTaskDetailBottomSheet = true
}, onLongClick = { }, onLongClick = {
showMoreActionsBottomSheet = true showMoreActionsBottomSheet = true
}) })
@ -84,10 +76,11 @@ fun TaskView(
HorizontalDivider(modifier = Modifier.padding(horizontal = 4.dp, vertical = 8.dp)) HorizontalDivider(modifier = Modifier.padding(horizontal = 4.dp, vertical = 8.dp))
Text( Text(
text = if (expanded) it else it.take(100) + "...", text = it.take(100),
fontSize = 12.sp, fontSize = 12.sp,
color = Color.White, color = Color.White,
modifier = Modifier modifier = Modifier
.height(100.dp)
.animateContentSize( .animateContentSize(
animationSpec = spring( animationSpec = spring(
dampingRatio = Spring.DampingRatioLowBouncy, dampingRatio = Spring.DampingRatioLowBouncy,
@ -97,39 +90,7 @@ fun TaskView(
) )
} }
Row( TaskStatus(task, foregroundColor = Color.White)
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
val (iconId, descriptionId) = task.statusData()
Image(
painter = painterResource(id = iconId),
modifier = Modifier.size(16.dp),
colorFilter = ColorFilter.tint(Color.White),
contentDescription = "status icon"
)
Spacer(modifier = Modifier.width(6.dp))
Text(text = stringResource(id = descriptionId), color = Color.White)
Spacer(modifier = Modifier.weight(1f))
if ((task.output?.length ?: 0) >= 100) {
Image(
painter = painterResource(
id = if (!expanded) R.drawable.ic_expand_more else R.drawable.ic_expand_less
),
contentDescription = "expand content icon",
colorFilter = ColorFilter.tint(Color.White)
)
}
Spacer(modifier = Modifier.width(8.dp))
}
if (showMoreActionsBottomSheet) { if (showMoreActionsBottomSheet) {
val bottomSheetAction = listOf( val bottomSheetAction = listOf(
@ -147,27 +108,20 @@ fun TaskView(
dismiss = { showMoreActionsBottomSheet = false } dismiss = { showMoreActionsBottomSheet = false }
) )
} }
if (showTaskDetailBottomSheet) {
TaskDetailBottomSheet(task) {
showTaskDetailBottomSheet = false
}
}
} }
} }
@Suppress("MagicNumber")
@Preview @Preview
@Composable @Composable
private fun TaskViewPreview() { private fun TaskViewPreview() {
val output = val output = "Lorem".getRandomString(100)
"Lorem Ipsum is simply dummy text of the printing and " +
"typesetting industry. Lorem Ipsum has been the " +
"industry's standard dummy text ever since the 1500s, " +
"when an unknown printer took a galley of type and " +
"scrambled it to make a type specimen book. " +
"It has survived not only five centuries, but also " +
"the leap into electronic typesetting, remaining" +
" essentially unchanged. It wLorem Ipsum is simply dummy" +
" text of the printing and typesetting industry. " +
"Lorem Ipsum has been the industry's standard dummy " +
"text ever since the 1500s, when an unknown printer took a" +
" galley of type and scrambled it to make a type specimen book. " +
"It has survived not only five centuries, but also the leap " +
"into electronic typesetting, remaining essentially unchanged."
TaskView( TaskView(
task = Task( task = Task(

View file

@ -0,0 +1,165 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.client.assistant.taskDetail
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.nextcloud.client.assistant.task.TaskStatus
import com.nextcloud.utils.extensions.getRandomString
import com.owncloud.android.R
import com.owncloud.android.lib.resources.assistant.model.Task
@Suppress("LongMethod")
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun TaskDetailBottomSheet(task: Task, dismiss: () -> Unit) {
var showInput by remember { mutableStateOf(true) }
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
ModalBottomSheet(
modifier = Modifier.padding(top = 32.dp),
containerColor = Color.White,
onDismissRequest = {
dismiss()
},
sheetState = sheetState
) {
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
stickyHeader {
Row(
modifier = Modifier
.fillMaxWidth()
.background(color = colorResource(id = R.color.light_grey), shape = RoundedCornerShape(8.dp))
) {
TextInputSelectButton(
Modifier.weight(1f),
R.string.assistant_task_detail_screen_input_button_title,
showInput,
onClick = {
showInput = true
}
)
TextInputSelectButton(
Modifier.weight(1f),
R.string.assistant_task_detail_screen_output_button_title,
!showInput,
onClick = {
showInput = false
}
)
}
}
item {
Spacer(modifier = Modifier.height(16.dp))
Column(
modifier = Modifier
.fillMaxSize()
.background(color = colorResource(id = R.color.light_grey), shape = RoundedCornerShape(8.dp))
.padding(16.dp)
) {
Text(
text = if (showInput) {
task.input ?: ""
} else {
task.output ?: ""
},
fontSize = 12.sp,
color = Color.Black,
modifier = Modifier
.animateContentSize(
animationSpec = spring(
dampingRatio = Spring.DampingRatioLowBouncy,
stiffness = Spring.StiffnessLow
)
)
)
}
TaskStatus(task, foregroundColor = Color.Black)
Spacer(modifier = Modifier.height(32.dp))
}
}
}
}
@Composable
private fun TextInputSelectButton(modifier: Modifier, titleId: Int, highlightCondition: Boolean, onClick: () -> Unit) {
Button(
onClick = onClick,
shape = RoundedCornerShape(8.dp),
colors = if (highlightCondition) {
ButtonDefaults.buttonColors(containerColor = Color.White)
} else {
ButtonDefaults.buttonColors(containerColor = colorResource(id = R.color.light_grey))
},
modifier = modifier
.widthIn(min = 0.dp, max = 200.dp)
.padding(horizontal = 4.dp)
) {
Text(text = stringResource(id = titleId), color = Color.Black)
}
}
@Suppress("MagicNumber")
@Preview
@Composable
private fun TaskDetailScreenPreview() {
TaskDetailBottomSheet(
task = Task(
1,
"Free Prompt",
0,
"1",
"1",
"Give me text".getRandomString(100),
"output".getRandomString(300),
"",
""
)
) {
}
}

View file

@ -5,7 +5,7 @@
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH * SPDX-FileCopyrightText: 2024 Nextcloud GmbH
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */
package com.nextcloud.client.assistant.component package com.nextcloud.client.assistant.taskTypes
import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row

View file

@ -58,7 +58,8 @@ import com.owncloud.android.db.ProviderMeta
AutoMigration(from = 76, to = 77), AutoMigration(from = 76, to = 77),
AutoMigration(from = 77, to = 78), AutoMigration(from = 77, to = 78),
AutoMigration(from = 78, to = 79, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class), AutoMigration(from = 78, to = 79, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
AutoMigration(from = 79, to = 80) AutoMigration(from = 79, to = 80),
AutoMigration(from = 80, to = 81)
], ],
exportSchema = true exportSchema = true
) )

View file

@ -45,6 +45,8 @@ data class SyncedFolderEntity(
val hidden: Int?, val hidden: Int?,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE) @ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE)
val subFolderRule: Int?, val subFolderRule: Int?,
@ColumnInfo(name = ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN) @ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_EXCLUDE_HIDDEN)
val excludeHidden: Int? val excludeHidden: Int?,
@ColumnInfo(name = ProviderTableMeta.SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS)
val lastScanTimestampMs: Long?
) )

View file

@ -264,7 +264,7 @@ internal class BackgroundJobManagerImpl(
.setConstraints(constrains) .setConstraints(constrains)
.build() .build()
workManager.enqueueUniqueWork(JOB_CONTENT_OBSERVER, ExistingWorkPolicy.APPEND, request) workManager.enqueueUniqueWork(JOB_CONTENT_OBSERVER, ExistingWorkPolicy.REPLACE, request)
} }
override fun schedulePeriodicContactsBackup(user: User) { override fun schedulePeriodicContactsBackup(user: User) {

View file

@ -11,6 +11,7 @@ import androidx.work.Worker
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import com.nextcloud.client.device.PowerManagementService import com.nextcloud.client.device.PowerManagementService
import com.owncloud.android.datamodel.SyncedFolderProvider import com.owncloud.android.datamodel.SyncedFolderProvider
import com.owncloud.android.lib.common.utils.Log_OC
/** /**
* This work is triggered when OS detects change in media folders. * This work is triggered when OS detects change in media folders.
@ -31,6 +32,7 @@ class ContentObserverWork(
backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class)) backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class))
if (params.triggeredContentUris.size > 0) { if (params.triggeredContentUris.size > 0) {
Log_OC.d(TAG, "File-sync Content Observer detected files change")
checkAndStartFileSyncJob() checkAndStartFileSyncJob()
backgroundJobManager.startMediaFoldersDetectionJob() backgroundJobManager.startMediaFoldersDetectionJob()
} }

View file

@ -62,7 +62,6 @@ class FilesSyncWork(
companion object { companion object {
const val TAG = "FilesSyncJob" const val TAG = "FilesSyncJob"
const val SKIP_CUSTOM = "skipCustom"
const val OVERRIDE_POWER_SAVING = "overridePowerSaving" const val OVERRIDE_POWER_SAVING = "overridePowerSaving"
const val CHANGED_FILES = "changedFiles" const val CHANGED_FILES = "changedFiles"
const val FOREGROUND_SERVICE_ID = 414 const val FOREGROUND_SERVICE_ID = 414
@ -70,7 +69,7 @@ class FilesSyncWork(
@Suppress("MagicNumber") @Suppress("MagicNumber")
private fun updateForegroundWorker(progressPercent: Int, useForegroundWorker: Boolean) { private fun updateForegroundWorker(progressPercent: Int, useForegroundWorker: Boolean) {
if (useForegroundWorker) { if (!useForegroundWorker) {
return return
} }
@ -95,6 +94,7 @@ class FilesSyncWork(
@Suppress("MagicNumber") @Suppress("MagicNumber")
override fun doWork(): Result { override fun doWork(): Result {
backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class)) backgroundJobManager.logStartOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class))
Log_OC.d(TAG, "File-sync worker started")
val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false) val overridePowerSaving = inputData.getBoolean(OVERRIDE_POWER_SAVING, false)
// If we are in power save mode, better to postpone upload // If we are in power save mode, better to postpone upload
@ -114,7 +114,9 @@ class FilesSyncWork(
// Get changed files from ContentObserverWork (only images and videos) or by scanning filesystem // Get changed files from ContentObserverWork (only images and videos) or by scanning filesystem
val changedFiles = inputData.getStringArray(CHANGED_FILES) val changedFiles = inputData.getStringArray(CHANGED_FILES)
Log_OC.d(TAG, "File-sync worker changed files from observer: " + changedFiles.contentToString())
collectChangedFiles(changedFiles) collectChangedFiles(changedFiles)
Log_OC.d(TAG, "File-sync worker finished checking files.")
// Create all the providers we'll need // Create all the providers we'll need
val filesystemDataProvider = FilesystemDataProvider(contentResolver) val filesystemDataProvider = FilesystemDataProvider(contentResolver)
@ -129,11 +131,7 @@ class FilesSyncWork(
(50 + (index.toDouble() / syncedFolders.size.toDouble()) * 50).toInt(), (50 + (index.toDouble() / syncedFolders.size.toDouble()) * 50).toInt(),
changedFiles.isNullOrEmpty() changedFiles.isNullOrEmpty()
) )
if (syncedFolder.isEnabled && ( if (syncedFolder.isEnabled) {
changedFiles.isNullOrEmpty() ||
MediaFolderType.CUSTOM != syncedFolder.type
)
) {
syncFolder( syncFolder(
context, context,
resources, resources,
@ -145,6 +143,7 @@ class FilesSyncWork(
) )
} }
} }
Log_OC.d(TAG, "File-sync worker finished")
val result = Result.success() val result = Result.success()
backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result) backgroundJobManager.logEndOfWorker(BackgroundJobManagerImpl.formatClassTag(this::class), result)
return result return result
@ -222,7 +221,6 @@ class FilesSyncWork(
needsWifi = syncedFolder.isWifiOnly needsWifi = syncedFolder.isWifiOnly
uploadAction = syncedFolder.uploadAction uploadAction = syncedFolder.uploadAction
} }
FileUploadHelper.instance().uploadNewFiles( FileUploadHelper.instance().uploadNewFiles(
user, user,
localPaths, localPaths,

View file

@ -75,8 +75,10 @@ class FileUploadHelper {
) { ) {
val failedUploads = uploadsStorageManager.failedUploads val failedUploads = uploadsStorageManager.failedUploads
if (failedUploads == null || failedUploads.isEmpty()) { if (failedUploads == null || failedUploads.isEmpty()) {
Log_OC.d(TAG, "Failed uploads are empty or null")
return return
} }
retryUploads( retryUploads(
uploadsStorageManager, uploadsStorageManager,
connectivityService, connectivityService,
@ -120,6 +122,7 @@ class FileUploadHelper {
val charging = batteryStatus.isCharging || batteryStatus.isFull val charging = batteryStatus.isCharging || batteryStatus.isFull
val isPowerSaving = powerManagementService.isPowerSavingEnabled val isPowerSaving = powerManagementService.isPowerSavingEnabled
var uploadUser = Optional.empty<User>() var uploadUser = Optional.empty<User>()
for (failedUpload in failedUploads) { for (failedUpload in failedUploads) {
// 1. extract failed upload owner account and cache it between loops (expensive query) // 1. extract failed upload owner account and cache it between loops (expensive query)
if (!uploadUser.isPresent || !uploadUser.get().nameEquals(failedUpload.accountName)) { if (!uploadUser.isPresent || !uploadUser.get().nameEquals(failedUpload.accountName)) {

View file

@ -165,16 +165,16 @@ class FileUploadWorker(
} }
if (user.isPresent) { if (user.isPresent) {
val operation = createUploadFileOperation(upload, user.get()) val uploadFileOperation = createUploadFileOperation(upload, user.get())
currentUploadFileOperation = operation currentUploadFileOperation = uploadFileOperation
val result = upload(operation, user.get()) val result = upload(uploadFileOperation, user.get())
currentUploadFileOperation = null currentUploadFileOperation = null
fileUploaderDelegate.sendBroadcastUploadFinished( fileUploaderDelegate.sendBroadcastUploadFinished(
operation, uploadFileOperation,
result, result,
operation.oldFile?.storagePath, uploadFileOperation.oldFile?.storagePath,
context, context,
localBroadcastManager localBroadcastManager
) )
@ -205,39 +205,39 @@ class FileUploadWorker(
} }
@Suppress("TooGenericExceptionCaught", "DEPRECATION") @Suppress("TooGenericExceptionCaught", "DEPRECATION")
private fun upload(operation: UploadFileOperation, user: User): RemoteOperationResult<Any?> { private fun upload(uploadFileOperation: UploadFileOperation, user: User): RemoteOperationResult<Any?> {
lateinit var result: RemoteOperationResult<Any?> lateinit var result: RemoteOperationResult<Any?>
notificationManager.prepareForStart( notificationManager.prepareForStart(
operation, uploadFileOperation,
intents.startIntent(operation), cancelPendingIntent = intents.startIntent(uploadFileOperation),
intents.notificationStartIntent(operation) intents.notificationStartIntent(uploadFileOperation)
) )
try { try {
val storageManager = operation.storageManager val storageManager = uploadFileOperation.storageManager
val ocAccount = OwnCloudAccount(user.toPlatformAccount(), context) val ocAccount = OwnCloudAccount(user.toPlatformAccount(), context)
val uploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context) val uploadClient = OwnCloudClientManagerFactory.getDefaultSingleton().getClientFor(ocAccount, context)
result = operation.execute(uploadClient) result = uploadFileOperation.execute(uploadClient)
val task = ThumbnailsCacheManager.ThumbnailGenerationTask(storageManager, user) val task = ThumbnailsCacheManager.ThumbnailGenerationTask(storageManager, user)
val file = File(operation.originalStoragePath) val file = File(uploadFileOperation.originalStoragePath)
val remoteId: String? = operation.file.remoteId val remoteId: String? = uploadFileOperation.file.remoteId
task.execute(ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, remoteId)) task.execute(ThumbnailsCacheManager.ThumbnailGenerationTaskObject(file, remoteId))
} catch (e: Exception) { } catch (e: Exception) {
Log_OC.e(TAG, "Error uploading", e) Log_OC.e(TAG, "Error uploading", e)
result = RemoteOperationResult<Any?>(e) result = RemoteOperationResult<Any?>(e)
} finally { } finally {
cleanupUploadProcess(result, operation) cleanupUploadProcess(result, uploadFileOperation)
} }
return result return result
} }
private fun cleanupUploadProcess(result: RemoteOperationResult<Any?>, operation: UploadFileOperation) { private fun cleanupUploadProcess(result: RemoteOperationResult<Any?>, uploadFileOperation: UploadFileOperation) {
if (!isStopped || !result.isCancelled) { if (!isStopped || !result.isCancelled) {
uploadsStorageManager.updateDatabaseUploadResult(result, operation) uploadsStorageManager.updateDatabaseUploadResult(result, uploadFileOperation)
notifyUploadResult(operation, result) notifyUploadResult(uploadFileOperation, result)
notificationManager.dismissWorkerNotifications() notificationManager.dismissWorkerNotifications()
} }
} }
@ -315,10 +315,11 @@ class FileUploadWorker(
if (percent != lastPercent) { if (percent != lastPercent) {
notificationManager.run { notificationManager.run {
updateUploadProgress(fileAbsoluteName, percent, currentUploadFileOperation)
val accountName = currentUploadFileOperation?.user?.accountName val accountName = currentUploadFileOperation?.user?.accountName
val remotePath = currentUploadFileOperation?.remotePath val remotePath = currentUploadFileOperation?.remotePath
val filename = currentUploadFileOperation?.fileName ?: ""
updateUploadProgress(filename, percent, currentUploadFileOperation)
if (accountName != null && remotePath != null) { if (accountName != null && remotePath != null) {
val key: String = val key: String =
@ -329,7 +330,7 @@ class FileUploadWorker(
progressRate, progressRate,
totalTransferredSoFar, totalTransferredSoFar,
totalToTransfer, totalToTransfer,
fileAbsoluteName filename
) )
} }

View file

@ -16,7 +16,6 @@ import android.os.Build
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import com.owncloud.android.R import com.owncloud.android.R
import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.operations.RemoteOperationResult
import com.owncloud.android.lib.resources.files.FileUtils
import com.owncloud.android.operations.UploadFileOperation import com.owncloud.android.operations.UploadFileOperation
import com.owncloud.android.ui.notifications.NotificationUtils import com.owncloud.android.ui.notifications.NotificationUtils
import com.owncloud.android.utils.theme.ViewThemeUtils import com.owncloud.android.utils.theme.ViewThemeUtils
@ -44,14 +43,18 @@ class UploadNotificationManager(private val context: Context, viewThemeUtils: Vi
} }
@Suppress("MagicNumber") @Suppress("MagicNumber")
fun prepareForStart(upload: UploadFileOperation, pendingIntent: PendingIntent, startIntent: PendingIntent) { fun prepareForStart(
uploadFileOperation: UploadFileOperation,
cancelPendingIntent: PendingIntent,
startIntent: PendingIntent
) {
notificationBuilder.run { notificationBuilder.run {
setContentTitle(context.getString(R.string.uploader_upload_in_progress_ticker)) setContentTitle(context.getString(R.string.uploader_upload_in_progress_ticker))
setContentText( setContentText(
String.format( String.format(
context.getString(R.string.uploader_upload_in_progress), context.getString(R.string.uploader_upload_in_progress),
0, 0,
upload.fileName uploadFileOperation.fileName
) )
) )
setTicker(context.getString(R.string.foreground_service_upload)) setTicker(context.getString(R.string.foreground_service_upload))
@ -62,13 +65,13 @@ class UploadNotificationManager(private val context: Context, viewThemeUtils: Vi
addAction( addAction(
R.drawable.ic_action_cancel_grey, R.drawable.ic_action_cancel_grey,
context.getString(R.string.common_cancel), context.getString(R.string.common_cancel),
pendingIntent cancelPendingIntent
) )
setContentIntent(startIntent) setContentIntent(startIntent)
} }
if (!upload.isInstantPicture && !upload.isInstantVideo) { if (!uploadFileOperation.isInstantPicture && !uploadFileOperation.isInstantVideo) {
showNotification() showNotification()
} }
} }
@ -138,11 +141,10 @@ class UploadNotificationManager(private val context: Context, viewThemeUtils: Vi
} }
@Suppress("MagicNumber") @Suppress("MagicNumber")
fun updateUploadProgress(filePath: String, percent: Int, currentOperation: UploadFileOperation?) { fun updateUploadProgress(filename: String, percent: Int, currentOperation: UploadFileOperation?) {
notificationBuilder.run { notificationBuilder.run {
setProgress(100, percent, false) setProgress(100, percent, false)
val fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1) val text = String.format(context.getString(R.string.uploader_upload_in_progress), percent, filename)
val text = String.format(context.getString(R.string.uploader_upload_in_progress), percent, fileName)
setContentText(text) setContentText(text)
showNotification() showNotification()

View file

@ -36,7 +36,7 @@ import java.lang.ref.WeakReference
class ComposeActivity : DrawerActivity() { class ComposeActivity : DrawerActivity() {
lateinit var binding: ActivityComposeBinding lateinit var binding: ActivityComposeBinding
private var menuItemId: Int? = null private var menuItemId: Int = R.id.nav_all_files
companion object { companion object {
const val DESTINATION = "DESTINATION" const val DESTINATION = "DESTINATION"
@ -51,13 +51,12 @@ class ComposeActivity : DrawerActivity() {
val destination = intent.getSerializableArgument(DESTINATION, ComposeDestination::class.java) val destination = intent.getSerializableArgument(DESTINATION, ComposeDestination::class.java)
val titleId = intent.getIntExtra(TITLE, R.string.empty) val titleId = intent.getIntExtra(TITLE, R.string.empty)
menuItemId = intent.getIntExtra(MENU_ITEM, -1) menuItemId = intent.getIntExtra(MENU_ITEM, R.id.nav_all_files)
setupToolbar() setupDrawer(menuItemId)
updateActionBarTitleAndHomeButtonByString(getString(titleId))
if (menuItemId != -1) { setupToolbarShowOnlyMenuButtonAndTitle(getString(titleId)) {
setupDrawer(menuItemId!!) openDrawer()
} }
binding.composeView.setContent { binding.composeView.setContent {
@ -72,15 +71,13 @@ class ComposeActivity : DrawerActivity() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
if (menuItemId != -1) { setDrawerMenuItemChecked(menuItemId)
setDrawerMenuItemChecked(R.id.nav_assistant)
}
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) { return when (item.itemId) {
android.R.id.home -> { android.R.id.home -> {
if (isDrawerOpen) closeDrawer() else openDrawer() toggleDrawer()
true true
} }
else -> super.onOptionsItemSelected(item) else -> super.onOptionsItemSelected(item)

View file

@ -0,0 +1,17 @@
/*
* Nextcloud - Android Client
*
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
package com.nextcloud.utils.extensions
fun String.getRandomString(length: Int): String {
val allowedChars = ('A'..'Z') + ('a'..'z') + ('0'..'9')
val result = (1..length)
.map { allowedChars.random() }
.joinToString("")
return this + result
}

View file

@ -124,7 +124,7 @@ import static com.owncloud.android.ui.activity.ContactsPreferenceActivity.PREFER
* Contains methods to build the "static" strings. These strings were before constants in different classes. * Contains methods to build the "static" strings. These strings were before constants in different classes.
*/ */
public class MainApp extends MultiDexApplication implements HasAndroidInjector { public class MainApp extends MultiDexApplication implements HasAndroidInjector {
public static final OwnCloudVersion OUTDATED_SERVER_VERSION = NextcloudVersion.nextcloud_23; public static final OwnCloudVersion OUTDATED_SERVER_VERSION = NextcloudVersion.nextcloud_26;
public static final OwnCloudVersion MINIMUM_SUPPORTED_SERVER_VERSION = OwnCloudVersion.nextcloud_16; public static final OwnCloudVersion MINIMUM_SUPPORTED_SERVER_VERSION = OwnCloudVersion.nextcloud_16;
private static final String TAG = MainApp.class.getSimpleName(); private static final String TAG = MainApp.class.getSimpleName();

View file

@ -56,7 +56,10 @@ import com.owncloud.android.utils.FileStorageUtils;
import com.owncloud.android.utils.MimeType; import com.owncloud.android.utils.MimeType;
import com.owncloud.android.utils.MimeTypeUtil; import com.owncloud.android.utils.MimeTypeUtil;
import org.apache.commons.io.FileUtils;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -71,6 +74,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import kotlin.Pair;
public class FileDataStorageManager { public class FileDataStorageManager {
private static final String TAG = FileDataStorageManager.class.getSimpleName(); private static final String TAG = FileDataStorageManager.class.getSimpleName();
@ -338,6 +342,36 @@ public class FileDataStorageManager {
return ocFile; return ocFile;
} }
public static void clearTempEncryptedFolder(String accountName) {
File tempEncryptedFolder = new File(FileStorageUtils.getTemporalEncryptedFolderPath(accountName));
if (!tempEncryptedFolder.exists()) {
Log_OC.d(TAG,"tempEncryptedFolder not exists");
return;
}
try {
FileUtils.cleanDirectory(tempEncryptedFolder);
Log_OC.d(TAG,"tempEncryptedFolder cleared");
} catch (IOException exception) {
Log_OC.d(TAG,"Error caught at clearTempEncryptedFolder: " + exception);
}
}
public static File createTempEncryptedFolder(String accountName) {
File tempEncryptedFolder = new File(FileStorageUtils.getTemporalEncryptedFolderPath(accountName));
if (!tempEncryptedFolder.exists()) {
boolean isTempEncryptedFolderCreated = tempEncryptedFolder.mkdirs();
Log_OC.d(TAG, "tempEncryptedFolder created" + isTempEncryptedFolderCreated);
} else {
Log_OC.d(TAG, "tempEncryptedFolder already exists");
}
return tempEncryptedFolder;
}
public void saveNewFile(OCFile newFile) { public void saveNewFile(OCFile newFile) {
String remoteParentPath = new File(newFile.getRemotePath()).getParent(); String remoteParentPath = new File(newFile.getRemotePath()).getParent();
remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ? remoteParentPath = remoteParentPath.endsWith(OCFile.PATH_SEPARATOR) ?
@ -1704,6 +1738,7 @@ public class FileDataStorageManager {
} }
} }
@SuppressFBWarnings("PSC")
public void saveConflict(OCFile ocFile, String etagInConflict) { public void saveConflict(OCFile ocFile, String etagInConflict) {
ContentValues cv = new ContentValues(); ContentValues cv = new ContentValues();
if (!ocFile.isDown()) { if (!ocFile.isDown()) {
@ -2297,6 +2332,59 @@ public class FileDataStorageManager {
} }
} }
public String getFolderName(String path) {
return "/" + path.split("/")[1] + "/";
}
public String retrieveRemotePathConsideringEncryption(OCFile file) {
if (file == null) {
throw new NullPointerException("file cannot be null");
}
String remotePath = file.getRemotePath();
if (file.isEncrypted()) {
remotePath = getEncryptedRemotePath(file.getRemotePath());
}
return remotePath;
}
public String getEncryptedRemotePath(String decryptedRemotePath) {
String folderName = getFolderName(decryptedRemotePath);
if (folderName == null) {
throw new NullPointerException("folderName cannot be null");
}
OCFile folder = getFileByDecryptedRemotePath(folderName);
List<OCFile> files = getAllFilesRecursivelyInsideFolder(folder);
List<Pair<String, String>> decryptedFileNamesAndEncryptedRemotePaths = getDecryptedFileNamesAndEncryptedRemotePaths(files);
String decryptedFileName = decryptedRemotePath.substring( decryptedRemotePath.lastIndexOf('/') + 1);
for (Pair<String, String> item : decryptedFileNamesAndEncryptedRemotePaths) {
if (item.getFirst().equals(decryptedFileName)) {
return item.getSecond();
}
}
return null;
}
@SuppressFBWarnings("OCP")
private List<Pair<String, String>> getDecryptedFileNamesAndEncryptedRemotePaths(List<OCFile> fileList) {
List<Pair<String, String>> result = new ArrayList<>();
for (OCFile file : fileList) {
if (file.isEncrypted()) {
Pair<String, String> fileNameAndEncryptedRemotePath = new Pair<>(file.getDecryptedFileName(), file.getRemotePath());
result.add(fileNameAndEncryptedRemotePath);
}
}
return result;
}
public void removeLocalFiles(User user, FileDataStorageManager storageManager) { public void removeLocalFiles(User user, FileDataStorageManager storageManager) {
File tempDir = new File(FileStorageUtils.getTemporalPath(user.getAccountName())); File tempDir = new File(FileStorageUtils.getTemporalPath(user.getAccountName()));
File saveDir = new File(FileStorageUtils.getSavePath(user.getAccountName())); File saveDir = new File(FileStorageUtils.getSavePath(user.getAccountName()));

View file

@ -107,6 +107,7 @@ public class FilesystemDataProvider {
public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean isFolder, SyncedFolder syncedFolder) { public void storeOrUpdateFileValue(String localPath, long modifiedAt, boolean isFolder, SyncedFolder syncedFolder) {
// takes multiple milliseconds to query data from database (around 75% of execution time) (6ms)
FileSystemDataSet data = getFilesystemDataSet(localPath, syncedFolder); FileSystemDataSet data = getFilesystemDataSet(localPath, syncedFolder);
int isFolderValue = 0; int isFolderValue = 0;
@ -145,7 +146,7 @@ public class FilesystemDataProvider {
} }
} }
// updating data takes multiple milliseconds (around 25% of exec time) (2 ms)
int result = contentResolver.update( int result = contentResolver.update(
ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM, ProviderMeta.ProviderTableMeta.CONTENT_URI_FILESYSTEM,
cv, cv,

View file

@ -21,6 +21,7 @@ import java.io.Serializable;
public class SyncedFolder implements Serializable, Cloneable { public class SyncedFolder implements Serializable, Cloneable {
public static final long UNPERSISTED_ID = Long.MIN_VALUE; public static final long UNPERSISTED_ID = Long.MIN_VALUE;
public static final long EMPTY_ENABLED_TIMESTAMP_MS = -1; public static final long EMPTY_ENABLED_TIMESTAMP_MS = -1;
public static final long NOT_SCANNED_YET = -1;
private static final long serialVersionUID = -793476118299906429L; private static final long serialVersionUID = -793476118299906429L;
@ -41,6 +42,7 @@ public class SyncedFolder implements Serializable, Cloneable {
private boolean hidden; private boolean hidden;
private SubFolderRule subfolderRule; private SubFolderRule subfolderRule;
private boolean excludeHidden; private boolean excludeHidden;
private long lastScanTimestampMs;
/** /**
* constructor for new, to be persisted entity. * constructor for new, to be persisted entity.
@ -75,7 +77,8 @@ public class SyncedFolder implements Serializable, Cloneable {
MediaFolderType type, MediaFolderType type,
boolean hidden, boolean hidden,
SubFolderRule subFolderRule, SubFolderRule subFolderRule,
boolean excludeHidden) { boolean excludeHidden,
long lastScanTimestampMs) {
this(UNPERSISTED_ID, this(UNPERSISTED_ID,
localPath, localPath,
remotePath, remotePath,
@ -91,7 +94,8 @@ public class SyncedFolder implements Serializable, Cloneable {
type, type,
hidden, hidden,
subFolderRule, subFolderRule,
excludeHidden); excludeHidden,
lastScanTimestampMs);
} }
/** /**
@ -114,7 +118,8 @@ public class SyncedFolder implements Serializable, Cloneable {
MediaFolderType type, MediaFolderType type,
boolean hidden, boolean hidden,
SubFolderRule subFolderRule, SubFolderRule subFolderRule,
boolean excludeHidden) { boolean excludeHidden,
long lastScanTimestampMs) {
this.id = id; this.id = id;
this.localPath = localPath; this.localPath = localPath;
this.remotePath = remotePath; this.remotePath = remotePath;
@ -130,6 +135,7 @@ public class SyncedFolder implements Serializable, Cloneable {
this.hidden = hidden; this.hidden = hidden;
this.subfolderRule = subFolderRule; this.subfolderRule = subFolderRule;
this.excludeHidden = excludeHidden; this.excludeHidden = excludeHidden;
this.lastScanTimestampMs = lastScanTimestampMs;
} }
/** /**
@ -271,4 +277,8 @@ public class SyncedFolder implements Serializable, Cloneable {
public boolean containsFile(String filePath){ public boolean containsFile(String filePath){
return filePath.contains(localPath); return filePath.contains(localPath);
} }
public long getLastScanTimestampMs() { return lastScanTimestampMs; }
public void setLastScanTimestampMs(long lastScanTimestampMs) { this.lastScanTimestampMs = lastScanTimestampMs; }
} }

View file

@ -60,7 +60,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
MediaFolderType type, MediaFolderType type,
boolean hidden, boolean hidden,
SubFolderRule subFolderRule, SubFolderRule subFolderRule,
boolean excludeHidden) { boolean excludeHidden,
long lastScanTimestampMs) {
super(id, super(id,
localPath, localPath,
remotePath, remotePath,
@ -76,7 +77,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
type, type,
hidden, hidden,
subFolderRule, subFolderRule,
excludeHidden); excludeHidden,
lastScanTimestampMs);
this.filePaths = filePaths; this.filePaths = filePaths;
this.folderName = folderName; this.folderName = folderName;
this.numberOfFiles = numberOfFiles; this.numberOfFiles = numberOfFiles;
@ -98,7 +100,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
MediaFolderType type, MediaFolderType type,
boolean hidden, boolean hidden,
SubFolderRule subFolderRule, SubFolderRule subFolderRule,
boolean excludeHidden) { boolean excludeHidden,
long lastScanTimestampMs) {
super(id, super(id,
localPath, localPath,
remotePath, remotePath,
@ -114,7 +117,8 @@ public class SyncedFolderDisplayItem extends SyncedFolder {
type, type,
hidden, hidden,
subFolderRule, subFolderRule,
excludeHidden); excludeHidden,
lastScanTimestampMs);
this.folderName = folderName; this.folderName = folderName;
} }

View file

@ -360,7 +360,9 @@ public class SyncedFolderProvider extends Observable {
SubFolderRule subFolderRule = SubFolderRule.values()[cursor.getInt( SubFolderRule subFolderRule = SubFolderRule.values()[cursor.getInt(
cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE))]; cursor.getColumnIndexOrThrow(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE))];
boolean excludeHidden = cursor.getInt(cursor.getColumnIndexOrThrow( boolean excludeHidden = cursor.getInt(cursor.getColumnIndexOrThrow(
ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN)) == 1; ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_EXCLUDE_HIDDEN)) == 1;
long lastScanTimestampMs = cursor.getLong(cursor.getColumnIndexOrThrow(
ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS));
syncedFolder = new SyncedFolder(id, syncedFolder = new SyncedFolder(id,
@ -378,7 +380,8 @@ public class SyncedFolderProvider extends Observable {
type, type,
hidden, hidden,
subFolderRule, subFolderRule,
excludeHidden); excludeHidden,
lastScanTimestampMs);
} }
return syncedFolder; return syncedFolder;
} }
@ -407,8 +410,8 @@ public class SyncedFolderProvider extends Observable {
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_TYPE, syncedFolder.getType().id); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_TYPE, syncedFolder.getType().id);
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN, syncedFolder.isHidden()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_HIDDEN, syncedFolder.isHidden());
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE, syncedFolder.getSubfolderRule().ordinal()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_SUBFOLDER_RULE, syncedFolder.getSubfolderRule().ordinal());
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_EXCLUDE_HIDDEN, syncedFolder.isExcludeHidden()); cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_EXCLUDE_HIDDEN, syncedFolder.isExcludeHidden());
cv.put(ProviderMeta.ProviderTableMeta.SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS, syncedFolder.getLastScanTimestampMs());
return cv; return cv;
} }

View file

@ -25,7 +25,7 @@ import java.util.List;
*/ */
public class ProviderMeta { public class ProviderMeta {
public static final String DB_NAME = "filelist"; public static final String DB_NAME = "filelist";
public static final int DB_VERSION = 80; public static final int DB_VERSION = 81;
private ProviderMeta() { private ProviderMeta() {
// No instance // No instance
@ -293,7 +293,8 @@ public class ProviderMeta {
public static final String SYNCED_FOLDER_NAME_COLLISION_POLICY = "name_collision_policy"; public static final String SYNCED_FOLDER_NAME_COLLISION_POLICY = "name_collision_policy";
public static final String SYNCED_FOLDER_HIDDEN = "hidden"; public static final String SYNCED_FOLDER_HIDDEN = "hidden";
public static final String SYNCED_FOLDER_SUBFOLDER_RULE = "sub_folder_rule"; public static final String SYNCED_FOLDER_SUBFOLDER_RULE = "sub_folder_rule";
public static final String SYNCED_EXCLUDE_HIDDEN = "exclude_hidden"; public static final String SYNCED_FOLDER_EXCLUDE_HIDDEN = "exclude_hidden";
public static final String SYNCED_FOLDER_LAST_SCAN_TIMESTAMP_MS = "last_scan_timestamp_ms";
// Columns of external links table // Columns of external links table
public static final String EXTERNAL_LINKS_ICON_URL = "icon_url"; public static final String EXTERNAL_LINKS_ICON_URL = "icon_url";

View file

@ -58,15 +58,14 @@ import java.util.Vector;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR; import static com.owncloud.android.datamodel.OCFile.PATH_SEPARATOR;
/** /**
* Remote operation performing the synchronization of the list of files contained in a folder identified with its * Remote operation performing the synchronization of the list of files contained in a folder identified with its remote
* remote path. * path. Fetches the list and properties of the files contained in the given folder, including their properties, and
* Fetches the list and properties of the files contained in the given folder, including their properties, and updates * updates the local database with them. Does NOT enter in the child folders to synchronize their contents also.
* the local database with them.
* Does NOT enter in the child folders to synchronize their contents also.
*/ */
@SuppressWarnings("PMD.AvoidDuplicateLiterals") @SuppressWarnings("PMD.AvoidDuplicateLiterals")
public class RefreshFolderOperation extends RemoteOperation { public class RefreshFolderOperation extends RemoteOperation {
@ -74,37 +73,53 @@ public class RefreshFolderOperation extends RemoteOperation {
private static final String TAG = RefreshFolderOperation.class.getSimpleName(); private static final String TAG = RefreshFolderOperation.class.getSimpleName();
public static final String EVENT_SINGLE_FOLDER_CONTENTS_SYNCED = public static final String EVENT_SINGLE_FOLDER_CONTENTS_SYNCED =
RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_CONTENTS_SYNCED"; RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_CONTENTS_SYNCED";
public static final String EVENT_SINGLE_FOLDER_SHARES_SYNCED = public static final String EVENT_SINGLE_FOLDER_SHARES_SYNCED =
RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_SHARES_SYNCED"; RefreshFolderOperation.class.getName() + ".EVENT_SINGLE_FOLDER_SHARES_SYNCED";
/** Time stamp for the synchronization process in progress */ /**
* Time stamp for the synchronization process in progress
*/
private long mCurrentSyncTime; private long mCurrentSyncTime;
/** Remote folder to synchronize */ /**
* Remote folder to synchronize
*/
private OCFile mLocalFolder; private OCFile mLocalFolder;
/** Access to the local database */ /**
* Access to the local database
*/
private FileDataStorageManager mStorageManager; private FileDataStorageManager mStorageManager;
/** Account where the file to synchronize belongs */ /**
* Account where the file to synchronize belongs
*/
private User user; private User user;
/** Android context; necessary to send requests to the download service */ /**
* Android context; necessary to send requests to the download service
*/
private Context mContext; private Context mContext;
/** Files and folders contained in the synchronized folder after a successful operation */ /**
* Files and folders contained in the synchronized folder after a successful operation
*/
private List<OCFile> mChildren; private List<OCFile> mChildren;
/** Counter of conflicts found between local and remote files */ /**
* Counter of conflicts found between local and remote files
*/
private int mConflictsFound; private int mConflictsFound;
/** Counter of failed operations in synchronization of kept-in-sync files */ /**
* Counter of failed operations in synchronization of kept-in-sync files
*/
private int mFailsInKeptInSyncFound; private int mFailsInKeptInSyncFound;
/** /**
* Map of remote and local paths to files that where locally stored in a location * Map of remote and local paths to files that where locally stored in a location out of the ownCloud folder and
* out of the ownCloud folder and couldn't be copied automatically into it * couldn't be copied automatically into it
**/ **/
private Map<String, String> mForgottenLocalFiles; private Map<String, String> mForgottenLocalFiles;
@ -113,10 +128,14 @@ public class RefreshFolderOperation extends RemoteOperation {
*/ */
private boolean mSyncFullAccount; private boolean mSyncFullAccount;
/** 'True' means that the remote folder changed and should be fetched */ /**
* 'True' means that the remote folder changed and should be fetched
*/
private boolean mRemoteFolderChanged; private boolean mRemoteFolderChanged;
/** 'True' means that Etag will be ignored */ /**
* 'True' means that Etag will be ignored
*/
private boolean mIgnoreETag; private boolean mIgnoreETag;
/** /**
@ -131,16 +150,14 @@ public class RefreshFolderOperation extends RemoteOperation {
/** /**
* Creates a new instance of {@link RefreshFolderOperation}. * Creates a new instance of {@link RefreshFolderOperation}.
* *
* @param folder Folder to synchronize. * @param folder Folder to synchronize.
* @param currentSyncTime Time stamp for the synchronization process in progress. * @param currentSyncTime Time stamp for the synchronization process in progress.
* @param syncFullAccount 'True' means that this operation is part of a full account * @param syncFullAccount 'True' means that this operation is part of a full account synchronization.
* synchronization. * @param ignoreETag 'True' means that the content of the remote folder should be fetched and updated even
* @param ignoreETag 'True' means that the content of the remote folder should * though the 'eTag' did not change.
* be fetched and updated even though the 'eTag' did not * @param dataStorageManager Interface with the local database.
* change. * @param user ownCloud account where the folder is located.
* @param dataStorageManager Interface with the local database. * @param context Application context.
* @param user ownCloud account where the folder is located.
* @param context Application context.
*/ */
public RefreshFolderOperation(OCFile folder, public RefreshFolderOperation(OCFile folder,
long currentSyncTime, long currentSyncTime,
@ -196,8 +213,8 @@ public class RefreshFolderOperation extends RemoteOperation {
} }
/** /**
* Returns the list of files and folders contained in the synchronized folder, * Returns the list of files and folders contained in the synchronized folder, if called after synchronization is
* if called after synchronization is complete. * complete.
* *
* @return List of files and folders contained in the synchronized folder. * @return List of files and folders contained in the synchronized folder.
*/ */
@ -207,7 +224,7 @@ public class RefreshFolderOperation extends RemoteOperation {
/** /**
* Performs the synchronization. * Performs the synchronization.
* * <p>
* {@inheritDoc} * {@inheritDoc}
*/ */
@Override @Override
@ -246,7 +263,7 @@ public class RefreshFolderOperation extends RemoteOperation {
if (!mSyncFullAccount && mRemoteFolderChanged) { if (!mSyncFullAccount && mRemoteFolderChanged) {
sendLocalBroadcast( sendLocalBroadcast(
EVENT_SINGLE_FOLDER_CONTENTS_SYNCED, mLocalFolder.getRemotePath(), result EVENT_SINGLE_FOLDER_CONTENTS_SYNCED, mLocalFolder.getRemotePath(), result
); );
} }
if (result.isSuccess() && !mSyncFullAccount && !mOnlyFileMetadata) { if (result.isSuccess() && !mSyncFullAccount && !mOnlyFileMetadata) {
@ -256,7 +273,7 @@ public class RefreshFolderOperation extends RemoteOperation {
if (!mSyncFullAccount) { if (!mSyncFullAccount) {
sendLocalBroadcast( sendLocalBroadcast(
EVENT_SINGLE_FOLDER_SHARES_SYNCED, mLocalFolder.getRemotePath(), result EVENT_SINGLE_FOLDER_SHARES_SYNCED, mLocalFolder.getRemotePath(), result
); );
} }
return result; return result;
@ -371,7 +388,7 @@ public class RefreshFolderOperation extends RemoteOperation {
result = new RemoteOperationResult(ResultCode.OK); result = new RemoteOperationResult(ResultCode.OK);
Log_OC.i(TAG, "Checked " + user.getAccountName() + remotePath + " : " + Log_OC.i(TAG, "Checked " + user.getAccountName() + remotePath + " : " +
(mRemoteFolderChanged ? "changed" : "not changed")); (mRemoteFolderChanged ? "changed" : "not changed"));
} else { } else {
// check failed // check failed
@ -380,10 +397,10 @@ public class RefreshFolderOperation extends RemoteOperation {
} }
if (result.isException()) { if (result.isException()) {
Log_OC.e(TAG, "Checked " + user.getAccountName() + remotePath + " : " + Log_OC.e(TAG, "Checked " + user.getAccountName() + remotePath + " : " +
result.getLogMessage(), result.getException()); result.getLogMessage(), result.getException());
} else { } else {
Log_OC.e(TAG, "Checked " + user.getAccountName() + remotePath + " : " + Log_OC.e(TAG, "Checked " + user.getAccountName() + remotePath + " : " +
result.getLogMessage()); result.getLogMessage());
} }
} }
@ -425,9 +442,9 @@ public class RefreshFolderOperation extends RemoteOperation {
/** /**
* Synchronizes the data retrieved from the server about the contents of the target folder * Synchronizes the data retrieved from the server about the contents of the target folder with the current data in
* with the current data in the local database. * the local database.
* * <p>
* Grants that mChildren is updated with fresh data after execution. * Grants that mChildren is updated with fresh data after execution.
* *
* @param folderAndFiles Remote folder and children files in Folder * @param folderAndFiles Remote folder and children files in Folder
@ -553,6 +570,7 @@ public class RefreshFolderOperation extends RemoteOperation {
updatedFiles.add(updatedFile); updatedFiles.add(updatedFile);
} }
// save updated contents in local database // save updated contents in local database
// update file name for encrypted files // update file name for encrypted files
if (e2EVersion == E2EVersion.V1_2) { if (e2EVersion == E2EVersion.V1_2) {
@ -584,6 +602,37 @@ public class RefreshFolderOperation extends RemoteOperation {
return metadata; return metadata;
} }
@SuppressFBWarnings("CE")
private static void setMimeTypeAndDecryptedRemotePath(OCFile updatedFile, FileDataStorageManager storageManager, String decryptedFileName, String mimetype) {
OCFile parentFile = storageManager.getFileById(updatedFile.getParentId());
if (parentFile == null) {
throw new NullPointerException("parentFile cannot be null");
}
String decryptedRemotePath;
if (decryptedFileName != null) {
decryptedRemotePath = parentFile.getDecryptedRemotePath() + decryptedFileName;
} else {
decryptedRemotePath = parentFile.getRemotePath() + updatedFile.getFileName();
}
if (updatedFile.isFolder()) {
decryptedRemotePath += "/";
}
updatedFile.setDecryptedRemotePath(decryptedRemotePath);
if (mimetype == null || mimetype.isEmpty()) {
if (updatedFile.isFolder()) {
updatedFile.setMimeType(MimeType.DIRECTORY);
} else {
updatedFile.setMimeType("application/octet-stream");
}
} else {
updatedFile.setMimeType(mimetype);
}
}
public static void updateFileNameForEncryptedFileV1(FileDataStorageManager storageManager, public static void updateFileNameForEncryptedFileV1(FileDataStorageManager storageManager,
@NonNull DecryptedFolderMetadataFileV1 metadata, @NonNull DecryptedFolderMetadataFileV1 metadata,
OCFile updatedFile) { OCFile updatedFile) {
@ -597,28 +646,16 @@ public class RefreshFolderOperation extends RemoteOperation {
} else { } else {
com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFile decryptedFile = com.owncloud.android.datamodel.e2e.v1.decrypted.DecryptedFile decryptedFile =
metadata.getFiles().get(updatedFile.getFileName()); metadata.getFiles().get(updatedFile.getFileName());
if (decryptedFile == null) {
throw new NullPointerException("decryptedFile cannot be null");
}
decryptedFileName = decryptedFile.getEncrypted().getFilename(); decryptedFileName = decryptedFile.getEncrypted().getFilename();
mimetype = decryptedFile.getEncrypted().getMimetype(); mimetype = decryptedFile.getEncrypted().getMimetype();
} }
setMimeTypeAndDecryptedRemotePath(updatedFile, storageManager, decryptedFileName, mimetype);
OCFile parentFile = storageManager.getFileById(updatedFile.getParentId());
String decryptedRemotePath = parentFile.getDecryptedRemotePath() + decryptedFileName;
if (updatedFile.isFolder()) {
decryptedRemotePath += "/";
}
updatedFile.setDecryptedRemotePath(decryptedRemotePath);
if (mimetype == null || mimetype.isEmpty()) {
if (updatedFile.isFolder()) {
updatedFile.setMimeType(MimeType.DIRECTORY);
} else {
updatedFile.setMimeType("application/octet-stream");
}
} else {
updatedFile.setMimeType(mimetype);
}
} catch (NullPointerException e) { } catch (NullPointerException e) {
Log_OC.e(TAG, "DecryptedMetadata for file " + updatedFile.getFileId() + " not found!"); Log_OC.e(TAG, "DecryptedMetadata for file " + updatedFile.getFileId() + " not found!");
} }
@ -636,28 +673,16 @@ public class RefreshFolderOperation extends RemoteOperation {
mimetype = MimeType.DIRECTORY; mimetype = MimeType.DIRECTORY;
} else { } else {
DecryptedFile decryptedFile = metadata.getMetadata().getFiles().get(updatedFile.getFileName()); DecryptedFile decryptedFile = metadata.getMetadata().getFiles().get(updatedFile.getFileName());
if (decryptedFile == null) {
throw new NullPointerException("decryptedFile cannot be null");
}
decryptedFileName = decryptedFile.getFilename(); decryptedFileName = decryptedFile.getFilename();
mimetype = decryptedFile.getMimetype(); mimetype = decryptedFile.getMimetype();
} }
setMimeTypeAndDecryptedRemotePath(updatedFile, storageManager, decryptedFileName, mimetype);
OCFile parentFile = storageManager.getFileById(updatedFile.getParentId());
String decryptedRemotePath = parentFile.getDecryptedRemotePath() + decryptedFileName;
if (updatedFile.isFolder()) {
decryptedRemotePath += "/";
}
updatedFile.setDecryptedRemotePath(decryptedRemotePath);
if (mimetype == null || mimetype.isEmpty()) {
if (updatedFile.isFolder()) {
updatedFile.setMimeType(MimeType.DIRECTORY);
} else {
updatedFile.setMimeType("application/octet-stream");
}
} else {
updatedFile.setMimeType(mimetype);
}
} catch (NullPointerException e) { } catch (NullPointerException e) {
Log_OC.e(TAG, "DecryptedMetadata for file " + updatedFile.getFileId() + " not found!"); Log_OC.e(TAG, "DecryptedMetadata for file " + updatedFile.getFileId() + " not found!");
} }
@ -668,8 +693,8 @@ public class RefreshFolderOperation extends RemoteOperation {
updatedFile.setFileId(localFile.getFileId()); updatedFile.setFileId(localFile.getFileId());
updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData()); updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
updatedFile.setModificationTimestampAtLastSyncForData( updatedFile.setModificationTimestampAtLastSyncForData(
localFile.getModificationTimestampAtLastSyncForData() localFile.getModificationTimestampAtLastSyncForData()
); );
if (localFile.isEncrypted()) { if (localFile.isEncrypted()) {
if (mLocalFolder.getStoragePath() == null) { if (mLocalFolder.getStoragePath() == null) {
updatedFile.setStoragePath(FileStorageUtils.getDefaultSavePathFor(user.getAccountName(), mLocalFolder) + updatedFile.setStoragePath(FileStorageUtils.getDefaultSavePathFor(user.getAccountName(), mLocalFolder) +
@ -685,7 +710,7 @@ public class RefreshFolderOperation extends RemoteOperation {
// eTag will not be updated unless file CONTENTS are synchronized // eTag will not be updated unless file CONTENTS are synchronized
if (!updatedFile.isFolder() && localFile.isDown() && if (!updatedFile.isFolder() && localFile.isDown() &&
!updatedFile.getEtag().equals(localFile.getEtag())) { !updatedFile.getEtag().equals(localFile.getEtag())) {
updatedFile.setEtagInConflict(updatedFile.getEtag()); updatedFile.setEtagInConflict(updatedFile.getEtag());
} }
@ -695,8 +720,8 @@ public class RefreshFolderOperation extends RemoteOperation {
updatedFile.setFileLength(remoteFile.getFileLength()); updatedFile.setFileLength(remoteFile.getFileLength());
updatedFile.setMountType(remoteFile.getMountType()); updatedFile.setMountType(remoteFile.getMountType());
} else if (remoteFolderChanged && MimeTypeUtil.isImage(remoteFile) && } else if (remoteFolderChanged && MimeTypeUtil.isImage(remoteFile) &&
remoteFile.getModificationTimestamp() != remoteFile.getModificationTimestamp() !=
localFile.getModificationTimestamp()) { localFile.getModificationTimestamp()) {
updatedFile.setUpdateThumbnailNeeded(true); updatedFile.setUpdateThumbnailNeeded(true);
Log_OC.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server"); Log_OC.d(TAG, "Image " + remoteFile.getFileName() + " updated on the server");
} }
@ -713,6 +738,7 @@ public class RefreshFolderOperation extends RemoteOperation {
} }
@NonNull @NonNull
@SuppressFBWarnings("OCP")
public static Map<String, OCFile> prefillLocalFilesMap(Object metadata, List<OCFile> localFiles) { public static Map<String, OCFile> prefillLocalFilesMap(Object metadata, List<OCFile> localFiles) {
Map<String, OCFile> localFilesMap = Maps.newHashMapWithExpectedSize(localFiles.size()); Map<String, OCFile> localFilesMap = Maps.newHashMapWithExpectedSize(localFiles.size());
@ -731,13 +757,12 @@ public class RefreshFolderOperation extends RemoteOperation {
} }
/** /**
* Performs a list of synchronization operations, determining if a download or upload is needed * Performs a list of synchronization operations, determining if a download or upload is needed or if exists
* or if exists conflict due to changes both in local and remote contents of the each file. * conflict due to changes both in local and remote contents of the each file.
* <p>
* If download or upload is needed, request the operation to the corresponding service and goes on.
* *
* If download or upload is needed, request the operation to the corresponding service and goes * @param filesToSyncContents Synchronization operations to execute.
* on.
*
* @param filesToSyncContents Synchronization operations to execute.
*/ */
private void startContentSynchronizations(List<SynchronizeFileOperation> filesToSyncContents) { private void startContentSynchronizations(List<SynchronizeFileOperation> filesToSyncContents) {
RemoteOperationResult contentsResult; RemoteOperationResult contentsResult;
@ -750,10 +775,10 @@ public class RefreshFolderOperation extends RemoteOperation {
mFailsInKeptInSyncFound++; mFailsInKeptInSyncFound++;
if (contentsResult.getException() != null) { if (contentsResult.getException() != null) {
Log_OC.e(TAG, "Error while synchronizing favourites : " Log_OC.e(TAG, "Error while synchronizing favourites : "
+ contentsResult.getLogMessage(), contentsResult.getException()); + contentsResult.getLogMessage(), contentsResult.getException());
} else { } else {
Log_OC.e(TAG, "Error while synchronizing favourites : " Log_OC.e(TAG, "Error while synchronizing favourites : "
+ contentsResult.getLogMessage()); + contentsResult.getLogMessage());
} }
} }
} // won't let these fails break the synchronization process } // won't let these fails break the synchronization process
@ -763,9 +788,9 @@ public class RefreshFolderOperation extends RemoteOperation {
/** /**
* Syncs the Share resources for the files contained in the folder refreshed (children, not deeper descendants). * Syncs the Share resources for the files contained in the folder refreshed (children, not deeper descendants).
* *
* @param client Handler of a session with an OC server. * @param client Handler of a session with an OC server.
* @return The result of the remote operation retrieving the Share resources in the folder refreshed by * @return The result of the remote operation retrieving the Share resources in the folder refreshed by the
* the operation. * operation.
*/ */
private RemoteOperationResult refreshSharesForFolder(OwnCloudClient client) { private RemoteOperationResult refreshSharesForFolder(OwnCloudClient client) {
RemoteOperationResult result; RemoteOperationResult result;
@ -793,12 +818,10 @@ public class RefreshFolderOperation extends RemoteOperation {
} }
/** /**
* Sends a message to any application component interested in the progress * Sends a message to any application component interested in the progress of the synchronization.
* of the synchronization.
* *
* @param event broadcast event (Intent Action) * @param event broadcast event (Intent Action)
* @param dirRemotePath Remote path of a folder that was just synchronized * @param dirRemotePath Remote path of a folder that was just synchronized (with or without success)
* (with or without success)
* @param result remote operation result * @param result remote operation result
*/ */
private void sendLocalBroadcast(String event, String dirRemotePath, RemoteOperationResult result) { private void sendLocalBroadcast(String event, String dirRemotePath, RemoteOperationResult result) {

View file

@ -442,6 +442,7 @@ public class UploadFileOperation extends SyncOperation {
File temporalFile = null; File temporalFile = null;
File originalFile = new File(mOriginalStoragePath); File originalFile = new File(mOriginalStoragePath);
File expectedFile = null; File expectedFile = null;
File encryptedTempFile = null;
FileLock fileLock = null; FileLock fileLock = null;
long size; long size;
@ -552,7 +553,7 @@ public class UploadFileOperation extends SyncOperation {
byte[] iv = EncryptionUtils.randomBytes(EncryptionUtils.ivLength); byte[] iv = EncryptionUtils.randomBytes(EncryptionUtils.ivLength);
Cipher cipher = EncryptionUtils.getCipher(Cipher.ENCRYPT_MODE, key, iv); Cipher cipher = EncryptionUtils.getCipher(Cipher.ENCRYPT_MODE, key, iv);
File file = new File(mFile.getStoragePath()); File file = new File(mFile.getStoragePath());
EncryptedFile encryptedFile = EncryptionUtils.encryptFile(file, cipher); EncryptedFile encryptedFile = EncryptionUtils.encryptFile(user.getAccountName(), file, cipher);
// new random file name, check if it exists in metadata // new random file name, check if it exists in metadata
String encryptedFileName = EncryptionUtils.generateUid(); String encryptedFileName = EncryptionUtils.generateUid();
@ -567,9 +568,7 @@ public class UploadFileOperation extends SyncOperation {
} }
} }
File encryptedTempFile = encryptedFile.getEncryptedFile(); encryptedTempFile = encryptedFile.getEncryptedFile();
/***** E2E *****/
FileChannel channel = null; FileChannel channel = null;
try { try {
@ -712,8 +711,6 @@ public class UploadFileOperation extends SyncOperation {
user, user,
getStorageManager()); getStorageManager());
} }
encryptedTempFile.delete();
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Log_OC.d(TAG, mFile.getStoragePath() + " not exists anymore"); Log_OC.d(TAG, mFile.getStoragePath() + " not exists anymore");
@ -755,6 +752,13 @@ public class UploadFileOperation extends SyncOperation {
if (unlockFolderResult != null && !unlockFolderResult.isSuccess()) { if (unlockFolderResult != null && !unlockFolderResult.isSuccess()) {
result = unlockFolderResult; result = unlockFolderResult;
} }
if (encryptedTempFile != null) {
boolean isTempEncryptedFileDeleted = encryptedTempFile.delete();
Log_OC.e(TAG, "isTempEncryptedFileDeleted: " + isTempEncryptedFileDeleted);
} else {
Log_OC.e(TAG, "Encrypted temp file cannot be found");
}
} }
if (result.isSuccess()) { if (result.isSuccess()) {

View file

@ -21,6 +21,7 @@ import com.nextcloud.client.jobs.upload.UploadNotificationManager
import com.nextcloud.model.HTTPStatusCodes import com.nextcloud.model.HTTPStatusCodes
import com.nextcloud.utils.extensions.getParcelableArgument import com.nextcloud.utils.extensions.getParcelableArgument
import com.owncloud.android.R import com.owncloud.android.R
import com.owncloud.android.datamodel.FileDataStorageManager
import com.owncloud.android.datamodel.OCFile import com.owncloud.android.datamodel.OCFile
import com.owncloud.android.datamodel.UploadsStorageManager import com.owncloud.android.datamodel.UploadsStorageManager
import com.owncloud.android.db.OCUpload import com.owncloud.android.db.OCUpload
@ -42,6 +43,10 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
@Inject @Inject
var uploadsStorageManager: UploadsStorageManager? = null var uploadsStorageManager: UploadsStorageManager? = null
@JvmField
@Inject
var fileStorageManager: FileDataStorageManager? = null
private var conflictUploadId: Long = 0 private var conflictUploadId: Long = 0
private var existingFile: OCFile? = null private var existingFile: OCFile? = null
private var newFile: OCFile? = null private var newFile: OCFile? = null
@ -159,8 +164,8 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
return return
} }
if (existingFile == null) { if (existingFile == null) {
// fetch info of existing file from server val remotePath = fileStorageManager?.retrieveRemotePathConsideringEncryption(newFile) ?: return
val operation = ReadFileRemoteOperation(newFile!!.remotePath) val operation = ReadFileRemoteOperation(remotePath)
@Suppress("TooGenericExceptionCaught") @Suppress("TooGenericExceptionCaught")
Thread { Thread {
@ -169,7 +174,7 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
if (result.isSuccess) { if (result.isSuccess) {
existingFile = FileStorageUtils.fillOCFile(result.data[0] as RemoteFile) existingFile = FileStorageUtils.fillOCFile(result.data[0] as RemoteFile)
existingFile?.lastSyncDateForProperties = System.currentTimeMillis() existingFile?.lastSyncDateForProperties = System.currentTimeMillis()
startDialog() startDialog(remotePath)
} else { } else {
Log_OC.e(TAG, "ReadFileRemoteOp returned failure with code: " + result.httpCode) Log_OC.e(TAG, "ReadFileRemoteOp returned failure with code: " + result.httpCode)
showErrorAndFinish(result.httpCode) showErrorAndFinish(result.httpCode)
@ -180,11 +185,12 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
} }
}.start() }.start()
} else { } else {
startDialog() val remotePath = fileStorageManager?.retrieveRemotePathConsideringEncryption(existingFile) ?: return
startDialog(remotePath)
} }
} }
private fun startDialog() { private fun startDialog(remotePath: String) {
val userOptional = user val userOptional = user
if (!userOptional.isPresent) { if (!userOptional.isPresent) {
Log_OC.e(TAG, "User not present") Log_OC.e(TAG, "User not present")
@ -197,7 +203,7 @@ class ConflictsResolveActivity : FileActivity(), OnConflictDecisionMadeListener
if (prev != null) { if (prev != null) {
fragmentTransaction.remove(prev) fragmentTransaction.remove(prev)
} }
if (existingFile != null && storageManager.fileExists(newFile?.remotePath)) { if (existingFile != null && storageManager.fileExists(remotePath)) {
val dialog = ConflictsResolveDialog.newInstance( val dialog = ConflictsResolveDialog.newInstance(
existingFile, existingFile,
newFile, newFile,

View file

@ -286,10 +286,10 @@ public abstract class DrawerActivity extends ToolbarActivity
public void updateHeader() { public void updateHeader() {
int primaryColor = themeColorUtils.unchangedPrimaryColor(getAccount(), this); int primaryColor = themeColorUtils.unchangedPrimaryColor(getAccount(), this);
boolean isClientBranded = getResources().getBoolean(R.bool.is_branded_client);
if (getAccount() != null && if (getAccount() != null &&
getCapabilities().getServerBackground() != null && getCapabilities().getServerBackground() != null && !isClientBranded) {
!getResources().getBoolean(R.bool.is_branded_client)) {
OCCapability capability = getCapabilities(); OCCapability capability = getCapabilities();
String logo = capability.getServerLogo(); String logo = capability.getServerLogo();
@ -339,47 +339,57 @@ public abstract class DrawerActivity extends ToolbarActivity
} }
// hide ecosystem apps according to user preference or in branded client // hide ecosystem apps according to user preference or in branded client
LinearLayout ecosystemApps = mNavigationViewHeader.findViewById(R.id.drawer_ecosystem_apps); LinearLayout banner = mNavigationViewHeader.findViewById(R.id.drawer_ecosystem_apps);
if (getResources().getBoolean(R.bool.is_branded_client) || !preferences.isShowEcosystemApps()) { boolean shouldHideTopBanner = isClientBranded || !preferences.isShowEcosystemApps();
ecosystemApps.setVisibility(View.GONE);
if (shouldHideTopBanner) {
hideTopBanner(banner);
} else { } else {
LinearLayout notesView = ecosystemApps.findViewById(R.id.drawer_ecosystem_notes); showTopBanner(banner, primaryColor);
LinearLayout talkView = ecosystemApps.findViewById(R.id.drawer_ecosystem_talk);
LinearLayout moreView = ecosystemApps.findViewById(R.id.drawer_ecosystem_more);
LinearLayout assistantView = ecosystemApps.findViewById(R.id.drawer_ecosystem_assistant);
notesView.setOnClickListener(v -> openAppOrStore("it.niedermann.owncloud.notes"));
talkView.setOnClickListener(v -> openAppOrStore("com.nextcloud.talk2"));
moreView.setOnClickListener(v -> openAppStore("Nextcloud", true));
assistantView.setOnClickListener(v -> startComposeActivity(ComposeDestination.AssistantScreen, R.string.assistant_screen_top_bar_title, -1));
if (getCapabilities() != null && getCapabilities().getAssistant().isTrue()) {
assistantView.setVisibility(View.VISIBLE);
} else {
assistantView.setVisibility(View.GONE);
}
List<LinearLayout> views = Arrays.asList(notesView, talkView, moreView, assistantView);
int iconColor;
if (Hct.fromInt(primaryColor).getTone() < 80.0) {
iconColor = Color.WHITE;
} else {
iconColor = getColor(R.color.grey_800_transparent);
}
for (LinearLayout view : views) {
ImageView imageView = (ImageView) view.getChildAt(0);
imageView.setImageTintList(ColorStateList.valueOf(iconColor));
GradientDrawable background = (GradientDrawable) imageView.getBackground();
background.setStroke(DisplayUtils.convertDpToPixel(1, this), iconColor);
TextView textView = (TextView) view.getChildAt(1);
textView.setTextColor(iconColor);
}
ecosystemApps.setVisibility(View.VISIBLE);
} }
} }
private void hideTopBanner(LinearLayout banner) {
banner.setVisibility(View.GONE);
}
private void showTopBanner(LinearLayout banner, int primaryColor) {
LinearLayout notesView = banner.findViewById(R.id.drawer_ecosystem_notes);
LinearLayout talkView = banner.findViewById(R.id.drawer_ecosystem_talk);
LinearLayout moreView = banner.findViewById(R.id.drawer_ecosystem_more);
LinearLayout assistantView = banner.findViewById(R.id.drawer_ecosystem_assistant);
notesView.setOnClickListener(v -> openAppOrStore("it.niedermann.owncloud.notes"));
talkView.setOnClickListener(v -> openAppOrStore("com.nextcloud.talk2"));
moreView.setOnClickListener(v -> openAppStore("Nextcloud", true));
assistantView.setOnClickListener(v -> startComposeActivity(ComposeDestination.AssistantScreen, R.string.assistant_screen_top_bar_title, -1));
if (getCapabilities() != null && getCapabilities().getAssistant().isTrue()) {
assistantView.setVisibility(View.VISIBLE);
} else {
assistantView.setVisibility(View.GONE);
}
List<LinearLayout> views = Arrays.asList(notesView, talkView, moreView, assistantView);
int iconColor;
if (Hct.fromInt(primaryColor).getTone() < 80.0) {
iconColor = Color.WHITE;
} else {
iconColor = getColor(R.color.grey_800_transparent);
}
for (LinearLayout view : views) {
ImageView imageView = (ImageView) view.getChildAt(0);
imageView.setImageTintList(ColorStateList.valueOf(iconColor));
GradientDrawable background = (GradientDrawable) imageView.getBackground();
background.setStroke(DisplayUtils.convertDpToPixel(1, this), iconColor);
TextView textView = (TextView) view.getChildAt(1);
textView.setTextColor(iconColor);
}
banner.setVisibility(View.VISIBLE);
}
/** /**
* Open specified app and, if not installed redirect to corresponding download. * Open specified app and, if not installed redirect to corresponding download.
* *
@ -463,9 +473,7 @@ public abstract class DrawerActivity extends ToolbarActivity
DrawerMenuUtil.filterGroupfoldersMenuItem(menu, capability); DrawerMenuUtil.filterGroupfoldersMenuItem(menu, capability);
DrawerMenuUtil.filterAssistantMenuItem(menu, capability, getResources()); DrawerMenuUtil.filterAssistantMenuItem(menu, capability, getResources());
DrawerMenuUtil.setupHomeMenuItem(menu, getResources()); DrawerMenuUtil.setupHomeMenuItem(menu, getResources());
DrawerMenuUtil.removeMenuItem(menu, R.id.nav_community, !getResources().getBoolean(R.bool.participate_enabled));
DrawerMenuUtil.removeMenuItem(menu, R.id.nav_community,
!getResources().getBoolean(R.bool.participate_enabled));
DrawerMenuUtil.removeMenuItem(menu, R.id.nav_shared, !getResources().getBoolean(R.bool.shared_enabled)); DrawerMenuUtil.removeMenuItem(menu, R.id.nav_shared, !getResources().getBoolean(R.bool.shared_enabled));
DrawerMenuUtil.removeMenuItem(menu, R.id.nav_logout, !getResources().getBoolean(R.bool.show_drawer_logout)); DrawerMenuUtil.removeMenuItem(menu, R.id.nav_logout, !getResources().getBoolean(R.bool.show_drawer_logout));
} }
@ -494,10 +502,17 @@ public abstract class DrawerActivity extends ToolbarActivity
MainApp.showOnlyPersonalFiles(itemId == R.id.nav_personal_files); MainApp.showOnlyPersonalFiles(itemId == R.id.nav_personal_files);
Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class); Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (this instanceof ComposeActivity) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
intent.setAction(FileDisplayActivity.ALL_FILES); intent.setAction(FileDisplayActivity.ALL_FILES);
intent.putExtra(FileDisplayActivity.DRAWER_MENU_ID, menuItem.getItemId()); intent.putExtra(FileDisplayActivity.DRAWER_MENU_ID, menuItem.getItemId());
startActivity(intent); startActivity(intent);
} }
closeDrawer();
} else if (itemId == R.id.nav_favorites) { } else if (itemId == R.id.nav_favorites) {
handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH), handleSearchEvents(new SearchEvent("", SearchRemoteOperation.SearchType.FAVORITE_SEARCH),
menuItem.getItemId()); menuItem.getItemId());
@ -520,7 +535,8 @@ public abstract class DrawerActivity extends ToolbarActivity
startActivity(CommunityActivity.class); startActivity(CommunityActivity.class);
} else if (itemId == R.id.nav_logout) { } else if (itemId == R.id.nav_logout) {
mCheckedMenuItem = -1; mCheckedMenuItem = -1;
menuItem.setChecked(false); MenuItem isNewMenuItemChecked = menuItem.setChecked(false);
Log_OC.d(TAG,"onNavigationItemClicked nav_logout setChecked " + isNewMenuItemChecked);
final Optional<User> optionalUser = getUser(); final Optional<User> optionalUser = getUser();
if (optionalUser.isPresent()) { if (optionalUser.isPresent()) {
UserInfoActivity.openAccountRemovalDialog(optionalUser.get(), getSupportFragmentManager()); UserInfoActivity.openAccountRemovalDialog(optionalUser.get(), getSupportFragmentManager());
@ -627,6 +643,11 @@ public abstract class DrawerActivity extends ToolbarActivity
private void launchActivityForSearch(SearchEvent searchEvent, int menuItemId) { private void launchActivityForSearch(SearchEvent searchEvent, int menuItemId) {
Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class); Intent intent = new Intent(getApplicationContext(), FileDisplayActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (this instanceof ComposeActivity) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
intent.setAction(Intent.ACTION_SEARCH); intent.setAction(Intent.ACTION_SEARCH);
intent.putExtra(OCFileListFragment.SEARCH_EVENT, searchEvent); intent.putExtra(OCFileListFragment.SEARCH_EVENT, searchEvent);
intent.putExtra(FileDisplayActivity.DRAWER_MENU_ID, menuItemId); intent.putExtra(FileDisplayActivity.DRAWER_MENU_ID, menuItemId);
@ -673,6 +694,14 @@ public abstract class DrawerActivity extends ToolbarActivity
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START); return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.START);
} }
public void toggleDrawer() {
if (isDrawerOpen()) {
closeDrawer();
} else {
openDrawer();
}
}
/** /**
* closes the drawer. * closes the drawer.
*/ */
@ -1115,6 +1144,11 @@ public abstract class DrawerActivity extends ToolbarActivity
MainApp.showOnlyPersonalFiles(onlyPersonalFiles); MainApp.showOnlyPersonalFiles(onlyPersonalFiles);
Intent fileDisplayActivity = new Intent(getApplicationContext(), FileDisplayActivity.class); Intent fileDisplayActivity = new Intent(getApplicationContext(), FileDisplayActivity.class);
fileDisplayActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); fileDisplayActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (this instanceof ComposeActivity) {
fileDisplayActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
}
fileDisplayActivity.setAction(FileDisplayActivity.ALL_FILES); fileDisplayActivity.setAction(FileDisplayActivity.ALL_FILES);
startActivity(fileDisplayActivity); startActivity(fileDisplayActivity);
} }
@ -1122,7 +1156,8 @@ public abstract class DrawerActivity extends ToolbarActivity
@Override @Override
public void avatarGenerated(Drawable avatarDrawable, Object callContext) { public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
if (callContext instanceof MenuItem menuItem) { if (callContext instanceof MenuItem menuItem) {
menuItem.setIcon(avatarDrawable); MenuItem newIcon = menuItem.setIcon(avatarDrawable);
Log_OC.d(TAG,"avatarGenerated new icon: " + newIcon);
} else if (callContext instanceof ImageView imageView) { } else if (callContext instanceof ImageView imageView) {
imageView.setImageDrawable(avatarDrawable); imageView.setImageDrawable(avatarDrawable);
} else if (callContext instanceof MaterialButton materialButton) { } else if (callContext instanceof MaterialButton materialButton) {

View file

@ -54,7 +54,6 @@ import com.nextcloud.client.jobs.download.FileDownloadHelper;
import com.nextcloud.client.jobs.download.FileDownloadWorker; import com.nextcloud.client.jobs.download.FileDownloadWorker;
import com.nextcloud.client.jobs.upload.FileUploadHelper; import com.nextcloud.client.jobs.upload.FileUploadHelper;
import com.nextcloud.client.jobs.upload.FileUploadWorker; import com.nextcloud.client.jobs.upload.FileUploadWorker;
import com.nextcloud.client.jobs.upload.UploadNotificationManager;
import com.nextcloud.client.media.PlayerServiceConnection; import com.nextcloud.client.media.PlayerServiceConnection;
import com.nextcloud.client.network.ClientFactory; import com.nextcloud.client.network.ClientFactory;
import com.nextcloud.client.network.ConnectivityService; import com.nextcloud.client.network.ConnectivityService;
@ -878,18 +877,24 @@ public class FileDisplayActivity extends FileActivity
requestUploadOfFilesFromFileSystem(basePath, filePaths, resultCode); requestUploadOfFilesFromFileSystem(basePath, filePaths, resultCode);
} }
private String[] getRemotePaths(String directory, String[] filePaths, String localBasePath) {
String[] remotePaths = new String[filePaths.length];
for (int j = 0; j < remotePaths.length; j++) {
String relativePath = StringUtils.removePrefix(filePaths[j], localBasePath);
remotePaths[j] = directory + relativePath;
}
return remotePaths;
}
private void requestUploadOfFilesFromFileSystem(String localBasePath, String[] filePaths, int resultCode) { private void requestUploadOfFilesFromFileSystem(String localBasePath, String[] filePaths, int resultCode) {
if (localBasePath != null && filePaths != null) { if (localBasePath != null && filePaths != null) {
if (!localBasePath.endsWith("/")) { if (!localBasePath.endsWith("/")) {
localBasePath = localBasePath + "/"; localBasePath = localBasePath + "/";
} }
String[] remotePaths = new String[filePaths.length];
String remotePathBase = getCurrentDir().getRemotePath(); String remotePathBase = getCurrentDir().getRemotePath();
for (int j = 0; j < remotePaths.length; j++) { String[] decryptedRemotePaths = getRemotePaths(remotePathBase, filePaths, localBasePath);
String relativePath = StringUtils.removePrefix(filePaths[j], localBasePath);
remotePaths[j] = remotePathBase + relativePath;
}
int behaviour = switch (resultCode) { int behaviour = switch (resultCode) {
case UploadFilesActivity.RESULT_OK_AND_MOVE -> FileUploadWorker.LOCAL_BEHAVIOUR_MOVE; case UploadFilesActivity.RESULT_OK_AND_MOVE -> FileUploadWorker.LOCAL_BEHAVIOUR_MOVE;
@ -899,7 +904,7 @@ public class FileDisplayActivity extends FileActivity
FileUploadHelper.Companion.instance().uploadNewFiles(getUser().orElseThrow(RuntimeException::new), FileUploadHelper.Companion.instance().uploadNewFiles(getUser().orElseThrow(RuntimeException::new),
filePaths, filePaths,
remotePaths, decryptedRemotePaths,
behaviour, behaviour,
true, true,
UploadFileOperation.CREATED_BY_USER, UploadFileOperation.CREATED_BY_USER,

View file

@ -387,7 +387,8 @@ class SyncedFoldersActivity :
syncedFolder.type, syncedFolder.type,
syncedFolder.isHidden, syncedFolder.isHidden,
syncedFolder.subfolderRule, syncedFolder.subfolderRule,
syncedFolder.isExcludeHidden syncedFolder.isExcludeHidden,
syncedFolder.lastScanTimestampMs
) )
} }
@ -418,7 +419,8 @@ class SyncedFoldersActivity :
mediaFolder.type, mediaFolder.type,
syncedFolder.isHidden, syncedFolder.isHidden,
syncedFolder.subfolderRule, syncedFolder.subfolderRule,
syncedFolder.isExcludeHidden syncedFolder.isExcludeHidden,
syncedFolder.lastScanTimestampMs
) )
} }
@ -448,7 +450,8 @@ class SyncedFoldersActivity :
mediaFolder.type, mediaFolder.type,
false, false,
SubFolderRule.YEAR_MONTH, SubFolderRule.YEAR_MONTH,
false false,
SyncedFolder.NOT_SCANNED_YET
) )
} }
@ -541,7 +544,8 @@ class SyncedFoldersActivity :
MediaFolderType.CUSTOM, MediaFolderType.CUSTOM,
false, false,
SubFolderRule.YEAR_MONTH, SubFolderRule.YEAR_MONTH,
false false,
SyncedFolder.NOT_SCANNED_YET
) )
onSyncFolderSettingsClick(0, emptyCustomFolder) onSyncFolderSettingsClick(0, emptyCustomFolder)
} else { } else {
@ -658,7 +662,8 @@ class SyncedFoldersActivity :
syncedFolder.type, syncedFolder.type,
syncedFolder.isHidden, syncedFolder.isHidden,
syncedFolder.subFolderRule, syncedFolder.subFolderRule,
syncedFolder.isExcludeHidden syncedFolder.isExcludeHidden,
SyncedFolder.NOT_SCANNED_YET
) )
saveOrUpdateSyncedFolder(newCustomFolder) saveOrUpdateSyncedFolder(newCustomFolder)
adapter.addSyncFolderItem(newCustomFolder) adapter.addSyncFolderItem(newCustomFolder)

View file

@ -104,6 +104,22 @@ public abstract class ToolbarActivity extends BaseActivity implements Injectable
viewThemeUtils.material.colorMaterialTextButton(mSwitchAccountButton); viewThemeUtils.material.colorMaterialTextButton(mSwitchAccountButton);
} }
public void setupToolbarShowOnlyMenuButtonAndTitle(String title, View.OnClickListener toggleDrawer) {
setupToolbar(false, false);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowTitleEnabled(false);
}
LinearLayout toolbar = findViewById(R.id.toolbar_linear_layout);
MaterialButton menuButton = findViewById(R.id.toolbar_menu_button);
MaterialTextView titleTextView = findViewById(R.id.toolbar_title);
titleTextView.setText(title);
toolbar.setVisibility(View.VISIBLE);
menuButton.setOnClickListener(toggleDrawer);
}
public void setupToolbar() { public void setupToolbar() {
setupToolbar(false, false); setupToolbar(false, false);
} }
@ -278,7 +294,7 @@ public abstract class ToolbarActivity extends BaseActivity implements Injectable
public void clearToolbarSubtitle() { public void clearToolbarSubtitle() {
ActionBar actionBar = getSupportActionBar(); ActionBar actionBar = getSupportActionBar();
if(actionBar != null){ if (actionBar != null) {
actionBar.setSubtitle(null); actionBar.setSubtitle(null);
} }
} }

View file

@ -141,9 +141,11 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
if (itemId == R.id.action_upload_list_failed_clear) { if (itemId == R.id.action_upload_list_failed_clear) {
uploadsStorageManager.clearFailedButNotDelayedUploads(); uploadsStorageManager.clearFailedButNotDelayedUploads();
clearTempEncryptedFolder();
loadUploadItemsFromDb(); loadUploadItemsFromDb();
} else { } else if (itemId == R.id.action_upload_list_failed_retry) {
// FIXME For e2e resume is not working
new Thread(() -> { new Thread(() -> {
FileUploadHelper.Companion.instance().retryFailedUploads( FileUploadHelper.Companion.instance().retryFailedUploads(
uploadsStorageManager, uploadsStorageManager,
@ -152,10 +154,11 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
powerManagementService); powerManagementService);
parentActivity.runOnUiThread(this::loadUploadItemsFromDb); parentActivity.runOnUiThread(this::loadUploadItemsFromDb);
}).start(); }).start();
} }
return true; return true;
}); });
failedPopup.show(); failedPopup.show();
} }
@ -169,6 +172,7 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
if (itemId == R.id.action_upload_list_cancelled_clear) { if (itemId == R.id.action_upload_list_cancelled_clear) {
uploadsStorageManager.clearCancelledUploadsForCurrentAccount(); uploadsStorageManager.clearCancelledUploadsForCurrentAccount();
loadUploadItemsFromDb(); loadUploadItemsFromDb();
clearTempEncryptedFolder();
} else if (itemId == R.id.action_upload_list_cancelled_resume) { } else if (itemId == R.id.action_upload_list_cancelled_resume) {
retryCancelledUploads(); retryCancelledUploads();
} }
@ -179,6 +183,12 @@ public class UploadListAdapter extends SectionedRecyclerViewAdapter<SectionedVie
popup.show(); popup.show();
} }
private void clearTempEncryptedFolder() {
Optional<User> user = parentActivity.getUser();
user.ifPresent(value -> FileDataStorageManager.clearTempEncryptedFolder(value.getAccountName()));
}
// FIXME For e2e resume is not working
private void retryCancelledUploads() { private void retryCancelledUploads() {
new Thread(() -> { new Thread(() -> {
boolean showNotExistMessage = FileUploadHelper.Companion.instance().retryCancelledUploads( boolean showNotExistMessage = FileUploadHelper.Companion.instance().retryCancelledUploads(

View file

@ -27,7 +27,7 @@ public final class DrawerMenuUtil {
User user, User user,
Resources resources) { Resources resources) {
if (user.isAnonymous()) { if (user.isAnonymous()) {
filterMenuItems(menu, R.id.nav_gallery, R.id.nav_favorites); removeMenuItem(menu, R.id.nav_gallery, R.id.nav_favorites);
} }
if (!resources.getBoolean(R.bool.recently_modified_enabled)) { if (!resources.getBoolean(R.bool.recently_modified_enabled)) {
@ -38,26 +38,29 @@ public final class DrawerMenuUtil {
public static void filterTrashbinMenuItem(Menu menu, @Nullable OCCapability capability) { public static void filterTrashbinMenuItem(Menu menu, @Nullable OCCapability capability) {
if (capability != null && capability.getFilesUndelete().isFalse() || if (capability != null && capability.getFilesUndelete().isFalse() ||
capability != null && capability.getFilesUndelete().isUnknown()) { capability != null && capability.getFilesUndelete().isUnknown()) {
filterMenuItems(menu, R.id.nav_trashbin); removeMenuItem(menu, R.id.nav_trashbin);
} }
} }
public static void filterActivityMenuItem(Menu menu, @Nullable OCCapability capability) { public static void filterActivityMenuItem(Menu menu, @Nullable OCCapability capability) {
if (capability != null && capability.getActivity().isFalse()) { if (capability != null && capability.getActivity().isFalse()) {
filterMenuItems(menu, R.id.nav_activity); removeMenuItem(menu, R.id.nav_activity);
} }
} }
public static void filterAssistantMenuItem(Menu menu, @Nullable OCCapability capability, Resources resources) { public static void filterAssistantMenuItem(Menu menu, @Nullable OCCapability capability, Resources resources) {
boolean showCondition = capability != null && capability.getAssistant().isTrue() && !resources.getBoolean(R.bool.is_branded_client); if (resources.getBoolean(R.bool.is_branded_client)) {
if (!showCondition) { if (capability != null && capability.getAssistant().isFalse()) {
filterMenuItems(menu, R.id.nav_assistant); removeMenuItem(menu, R.id.nav_assistant);
}
} else {
removeMenuItem(menu, R.id.nav_assistant);
} }
} }
public static void filterGroupfoldersMenuItem(Menu menu, @Nullable OCCapability capability) { public static void filterGroupfoldersMenuItem(Menu menu, @Nullable OCCapability capability) {
if (capability != null && !capability.getGroupfolders().isTrue()) { if (capability != null && !capability.getGroupfolders().isTrue()) {
filterMenuItems(menu, R.id.nav_groupfolders); removeMenuItem(menu, R.id.nav_groupfolders);
} }
} }
@ -74,7 +77,7 @@ public final class DrawerMenuUtil {
} }
} }
private static void filterMenuItems(Menu menu, int... menuIds) { private static void removeMenuItem(Menu menu, int... menuIds) {
if (menuIds != null) { if (menuIds != null) {
for (int menuId : menuIds) { for (int menuId : menuIds) {
menu.removeItem(menuId); menu.removeItem(menuId);

View file

@ -547,12 +547,12 @@ public final class EncryptionUtils {
return Base64.decode(string, Base64.NO_WRAP); return Base64.decode(string, Base64.NO_WRAP);
} }
public static EncryptedFile encryptFile(File file, Cipher cipher) throws InvalidParameterSpecException { public static EncryptedFile encryptFile(String accountName, File file, Cipher cipher) throws InvalidParameterSpecException, IOException {
// FIXME this won't work on low or write-protected storage File tempEncryptedFolder = FileDataStorageManager.createTempEncryptedFolder(accountName);
File encryptedFile = new File(file.getAbsolutePath() + ".enc.jpg"); File tempEncryptedFile = File.createTempFile(file.getName(), null, tempEncryptedFolder);
encryptFileWithGivenCipher(file, encryptedFile, cipher); encryptFileWithGivenCipher(file, tempEncryptedFile, cipher);
String authenticationTagString = getAuthenticationTag(cipher); String authenticationTagString = getAuthenticationTag(cipher);
return new EncryptedFile(encryptedFile, authenticationTagString); return new EncryptedFile(tempEncryptedFile, authenticationTagString);
} }
public static String getAuthenticationTag(Cipher cipher) throws InvalidParameterSpecException { public static String getAuthenticationTag(Cipher cipher) throws InvalidParameterSpecException {
@ -569,7 +569,7 @@ public final class EncryptionUtils {
} }
public static void encryptFileWithGivenCipher(File inputFile, File encryptedFile, Cipher cipher) { public static void encryptFileWithGivenCipher(File inputFile, File encryptedFile, Cipher cipher) {
try( FileInputStream inputStream = new FileInputStream(inputFile); try (FileInputStream inputStream = new FileInputStream(inputFile);
FileOutputStream fileOutputStream = new FileOutputStream(encryptedFile); FileOutputStream fileOutputStream = new FileOutputStream(encryptedFile);
CipherOutputStream outputStream = new CipherOutputStream(fileOutputStream, cipher)) { CipherOutputStream outputStream = new CipherOutputStream(fileOutputStream, cipher)) {
byte[] buffer = new byte[4096]; byte[] buffer = new byte[4096];

View file

@ -106,6 +106,17 @@ public final class FileStorageUtils {
// that can be in the accountName since 0.1.190B // that can be in the accountName since 0.1.190B
} }
public static String getTemporalEncryptedFolderPath(String accountName) {
return MainApp
.getAppContext()
.getFilesDir()
.getAbsolutePath()
+ File.separator
+ accountName
+ File.separator
+ "temp_encrypted_folder";
}
/** /**
* Get absolute path to tmp folder inside app folder for given accountName. * Get absolute path to tmp folder inside app folder for given accountName.
*/ */

View file

@ -20,7 +20,6 @@ import com.nextcloud.client.device.BatteryStatus;
import com.nextcloud.client.device.PowerManagementService; import com.nextcloud.client.device.PowerManagementService;
import com.nextcloud.client.jobs.BackgroundJobManager; import com.nextcloud.client.jobs.BackgroundJobManager;
import com.nextcloud.client.jobs.upload.FileUploadHelper; import com.nextcloud.client.jobs.upload.FileUploadHelper;
import com.nextcloud.client.jobs.upload.FileUploadWorker;
import com.nextcloud.client.network.ConnectivityService; import com.nextcloud.client.network.ConnectivityService;
import com.owncloud.android.MainApp; import com.owncloud.android.MainApp;
import com.owncloud.android.datamodel.FilesystemDataProvider; import com.owncloud.android.datamodel.FilesystemDataProvider;
@ -55,6 +54,59 @@ public final class FilesSyncHelper {
// utility class -> private constructor // utility class -> private constructor
} }
private static void insertCustomFolderIntoDB(Path path,
SyncedFolder syncedFolder,
FilesystemDataProvider filesystemDataProvider,
long lastCheck,
long thisCheck) {
final long enabledTimestampMs = syncedFolder.getEnabledTimestampMs();
try {
FileUtil.walkFileTree(path, new SimpleFileVisitor<>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
File file = path.toFile();
if (syncedFolder.isExcludeHidden() && file.isHidden()) {
// exclude hidden file or folder
return FileVisitResult.CONTINUE;
}
if (attrs.lastModifiedTime().toMillis() < lastCheck) {
// skip files that were already checked
return FileVisitResult.CONTINUE;
}
if (syncedFolder.isExisting() || attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) {
// storeOrUpdateFileValue takes a few ms
// -> Rest of this file check takes not even 1 ms.
filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
attrs.lastModifiedTime().toMillis(),
file.isDirectory(), syncedFolder);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
if (syncedFolder.isExcludeHidden() && dir.compareTo(Paths.get(syncedFolder.getLocalPath())) != 0 && dir.toFile().isHidden()) {
return null;
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
});
syncedFolder.setLastScanTimestampMs(thisCheck);
} catch (IOException e) {
Log_OC.e(TAG, "Something went wrong while indexing files for auto upload", e);
}
}
private static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder) { private static void insertAllDBEntriesForSyncedFolder(SyncedFolder syncedFolder) {
final Context context = MainApp.getAppContext(); final Context context = MainApp.getAppContext();
final ContentResolver contentResolver = context.getContentResolver(); final ContentResolver contentResolver = context.getContentResolver();
@ -63,55 +115,33 @@ public final class FilesSyncHelper {
if (syncedFolder.isEnabled() && (syncedFolder.isExisting() || enabledTimestampMs >= 0)) { if (syncedFolder.isEnabled() && (syncedFolder.isExisting() || enabledTimestampMs >= 0)) {
MediaFolderType mediaType = syncedFolder.getType(); MediaFolderType mediaType = syncedFolder.getType();
final long lastCheckTimestampMs = syncedFolder.getLastScanTimestampMs();
final long thisCheckTimestampMs = System.currentTimeMillis();
Log_OC.d(TAG,"File-sync start check folder "+syncedFolder.getLocalPath());
long startTime = System.nanoTime();
if (mediaType == MediaFolderType.IMAGE) { if (mediaType == MediaFolderType.IMAGE) {
FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.INTERNAL_CONTENT_URI FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.INTERNAL_CONTENT_URI,
, syncedFolder); syncedFolder,
lastCheckTimestampMs, thisCheckTimestampMs);
FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, FilesSyncHelper.insertContentIntoDB(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
syncedFolder); syncedFolder,
lastCheckTimestampMs, thisCheckTimestampMs);
} else if (mediaType == MediaFolderType.VIDEO) { } else if (mediaType == MediaFolderType.VIDEO) {
FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.INTERNAL_CONTENT_URI, FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.INTERNAL_CONTENT_URI,
syncedFolder); syncedFolder,
lastCheckTimestampMs, thisCheckTimestampMs);
FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, FilesSyncHelper.insertContentIntoDB(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
syncedFolder); syncedFolder,
lastCheckTimestampMs, thisCheckTimestampMs);
} else { } else {
try {
FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver); FilesystemDataProvider filesystemDataProvider = new FilesystemDataProvider(contentResolver);
Path path = Paths.get(syncedFolder.getLocalPath()); Path path = Paths.get(syncedFolder.getLocalPath());
FilesSyncHelper.insertCustomFolderIntoDB(path, syncedFolder, filesystemDataProvider, lastCheckTimestampMs, thisCheckTimestampMs);
FileUtil.walkFileTree(path, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
File file = path.toFile();
if (syncedFolder.isExcludeHidden() && file.isHidden()) {
// exclude hidden file or folder
return FileVisitResult.CONTINUE;
}
if (syncedFolder.isExisting() || attrs.lastModifiedTime().toMillis() >= enabledTimestampMs) {
filesystemDataProvider.storeOrUpdateFileValue(path.toAbsolutePath().toString(),
attrs.lastModifiedTime().toMillis(),
file.isDirectory(), syncedFolder);
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
if (syncedFolder.isExcludeHidden() && dir.compareTo(Paths.get(syncedFolder.getLocalPath())) != 0 && dir.toFile().isHidden()) {
return null;
}
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc) {
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
Log_OC.e(TAG, "Something went wrong while indexing files for auto upload", e);
}
} }
Log_OC.d(TAG,"File-sync finished full check for custom folder "+syncedFolder.getLocalPath()+" within "+(System.nanoTime() - startTime)+ "ns");
} }
} }
@ -160,7 +190,8 @@ public final class FilesSyncHelper {
return filePath; return filePath;
} }
private static void insertContentIntoDB(Uri uri, SyncedFolder syncedFolder) { private static void insertContentIntoDB(Uri uri, SyncedFolder syncedFolder,
long lastCheckTimestampMs, long thisCheckTimestampMs) {
final Context context = MainApp.getAppContext(); final Context context = MainApp.getAppContext();
final ContentResolver contentResolver = context.getContentResolver(); final ContentResolver contentResolver = context.getContentResolver();
@ -192,13 +223,22 @@ public final class FilesSyncHelper {
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
contentPath = cursor.getString(column_index_data); contentPath = cursor.getString(column_index_data);
isFolder = new File(contentPath).isDirectory(); isFolder = new File(contentPath).isDirectory();
if (syncedFolder.isExisting() || cursor.getLong(column_index_date_modified) >= enabledTimestampMs / 1000.0) {
if (syncedFolder.getLastScanTimestampMs() != SyncedFolder.NOT_SCANNED_YET &&
cursor.getLong(column_index_date_modified) < (lastCheckTimestampMs / 1000)) {
continue;
}
if (syncedFolder.isExisting() || cursor.getLong(column_index_date_modified) >= enabledTimestampMs / 1000) {
// storeOrUpdateFileValue takes a few ms
// -> Rest of this file check takes not even 1 ms.
filesystemDataProvider.storeOrUpdateFileValue(contentPath, filesystemDataProvider.storeOrUpdateFileValue(contentPath,
cursor.getLong(column_index_date_modified), isFolder, cursor.getLong(column_index_date_modified), isFolder,
syncedFolder); syncedFolder);
} }
} }
cursor.close(); cursor.close();
syncedFolder.setLastScanTimestampMs(thisCheckTimestampMs);
} }
} }

View file

@ -1,15 +0,0 @@
<!--
~ Nextcloud - Android Client
~
~ SPDX-FileCopyrightText: 2018-2024 Google LLC
~ SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="m296,615 l-56,-56 240,-240 240,240 -56,56 -184,-184 -184,184Z" />
</vector>

View file

@ -114,6 +114,42 @@
</RelativeLayout> </RelativeLayout>
<LinearLayout
android:id="@+id/toolbar_linear_layout"
android:visibility="gone"
tools:visibility="visible"
android:orientation="horizontal"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.button.MaterialButton
android:id="@+id/toolbar_menu_button"
style="@style/Widget.AppTheme.Button.IconButton"
android:layout_width="48dp"
android:layout_height="48dp"
app:cornerRadius="@dimen/button_corner_radius"
app:icon="@drawable/ic_menu"
app:iconTint="@color/black" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/toolbar_title"
android:gravity="center"
android:textColor="@color/black"
android:lines="1"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="48dp"/>
</LinearLayout>
<!-- home/search toolbar --> <!-- home/search toolbar -->
<com.google.android.material.card.MaterialCardView <com.google.android.material.card.MaterialCardView
android:id="@+id/home_toolbar" android:id="@+id/home_toolbar"

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">فشل إنشاء الحساب</string> <string name="account_creation_failed">فشل إنشاء الحساب</string>
<string name="account_icon">أيقونة الحساب </string> <string name="account_icon">أيقونة الحساب </string>
<string name="account_not_found">الحساب غير موجود </string> <string name="account_not_found">الحساب غير موجود </string>
<string name="action_clear_failed_uploads">مسح الملفات التي فشل رفعها</string>
<string name="action_edit">تعديل</string> <string name="action_edit">تعديل</string>
<string name="action_empty_notifications">إزالة جميع التنبيهات</string> <string name="action_empty_notifications">إزالة جميع التنبيهات</string>
<string name="action_empty_trashbin">تفريغ سلة المهملات</string> <string name="action_empty_trashbin">تفريغ سلة المهملات</string>
@ -57,6 +56,7 @@
<string name="assistant_screen_task_types_error_state_message">تعذّر جلب أنواع المهام. قم رجاءً بالتحقُّق من اتصالك بالإنترنت.</string> <string name="assistant_screen_task_types_error_state_message">تعذّر جلب أنواع المهام. قم رجاءً بالتحقُّق من اتصالك بالإنترنت.</string>
<string name="assistant_screen_top_bar_title">المُساعِد</string> <string name="assistant_screen_top_bar_title">المُساعِد</string>
<string name="assistant_screen_unknown_task_status_text">غير معروف</string> <string name="assistant_screen_unknown_task_status_text">غير معروف</string>
<string name="assistant_task_detail_screen_output_button_title">المُخرَجَات</string>
<string name="associated_account_not_found">الحساب المرتبط غير موجود!</string> <string name="associated_account_not_found">الحساب المرتبط غير موجود!</string>
<string name="auth_access_failed">فشل الوصول لـ: %1$s</string> <string name="auth_access_failed">فشل الوصول لـ: %1$s</string>
<string name="auth_account_does_not_exist">هذا الحساب لم تتم إضافته في هذا الجهاز بعد</string> <string name="auth_account_does_not_exist">هذا الحساب لم تتم إضافته في هذا الجهاز بعد</string>
@ -171,7 +171,6 @@
<string name="confirmation_remove_folder_alert">هل توَدُّ حقاً حذف %1$s وما يحتويه؟</string> <string name="confirmation_remove_folder_alert">هل توَدُّ حقاً حذف %1$s وما يحتويه؟</string>
<string name="confirmation_remove_folders_alert">هل توَدُّ حقاً حذف العناصر المختارة وما يحتوّه؟</string> <string name="confirmation_remove_folders_alert">هل توَدُّ حقاً حذف العناصر المختارة وما يحتوّه؟</string>
<string name="confirmation_remove_local">محلياً فقط</string> <string name="confirmation_remove_local">محلياً فقط</string>
<string name="conflict_dialog_error">خطأ في إنشاء حوار التعارض!</string>
<string name="conflict_file_headline">ملف متضارب %1$s </string> <string name="conflict_file_headline">ملف متضارب %1$s </string>
<string name="conflict_local_file">ملف محلي</string> <string name="conflict_local_file">ملف محلي</string>
<string name="conflict_message_description">إذا قمت باختيار كلا الاصدارين, الملف المحلي سيحتوي على رقم ملحق باسم الملف.</string> <string name="conflict_message_description">إذا قمت باختيار كلا الاصدارين, الملف المحلي سيحتوي على رقم ملحق باسم الملف.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Account creation failed</string> <string name="account_creation_failed">Account creation failed</string>
<string name="account_icon">Account icon</string> <string name="account_icon">Account icon</string>
<string name="account_not_found">Account not found!</string> <string name="account_not_found">Account not found!</string>
<string name="action_clear_failed_uploads">Clear failed uploads</string>
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_empty_notifications">Clear all notifications</string> <string name="action_empty_notifications">Clear all notifications</string>
<string name="action_empty_trashbin">Empty trash bin</string> <string name="action_empty_trashbin">Empty trash bin</string>
@ -57,6 +56,8 @@
<string name="assistant_screen_task_types_error_state_message">Unable to fetch task types, please check your internet connection.</string> <string name="assistant_screen_task_types_error_state_message">Unable to fetch task types, please check your internet connection.</string>
<string name="assistant_screen_top_bar_title">Assistant</string> <string name="assistant_screen_top_bar_title">Assistant</string>
<string name="assistant_screen_unknown_task_status_text">Unknown</string> <string name="assistant_screen_unknown_task_status_text">Unknown</string>
<string name="assistant_task_detail_screen_input_button_title">Input</string>
<string name="assistant_task_detail_screen_output_button_title">Output</string>
<string name="associated_account_not_found">Associated account not found!</string> <string name="associated_account_not_found">Associated account not found!</string>
<string name="auth_access_failed">Access failed: %1$s</string> <string name="auth_access_failed">Access failed: %1$s</string>
<string name="auth_account_does_not_exist">The account is not added on this device yet</string> <string name="auth_account_does_not_exist">The account is not added on this device yet</string>
@ -171,7 +172,6 @@
<string name="confirmation_remove_folder_alert">Do you really want to delete %1$s and its content?</string> <string name="confirmation_remove_folder_alert">Do you really want to delete %1$s and its content?</string>
<string name="confirmation_remove_folders_alert">Do you really want to delete the selected items and their contents?</string> <string name="confirmation_remove_folders_alert">Do you really want to delete the selected items and their contents?</string>
<string name="confirmation_remove_local">Local only</string> <string name="confirmation_remove_local">Local only</string>
<string name="conflict_dialog_error">Error creating conflict dialogue!</string>
<string name="conflict_file_headline">Conflicting file %1$s</string> <string name="conflict_file_headline">Conflicting file %1$s</string>
<string name="conflict_local_file">Local file</string> <string name="conflict_local_file">Local file</string>
<string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string> <string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Създаването на профила се провали</string> <string name="account_creation_failed">Създаването на профила се провали</string>
<string name="account_icon">Профил</string> <string name="account_icon">Профил</string>
<string name="account_not_found">Няма намерен профил!</string> <string name="account_not_found">Няма намерен профил!</string>
<string name="action_clear_failed_uploads">Изчисти провалените качвания</string>
<string name="action_edit">Променяне</string> <string name="action_edit">Променяне</string>
<string name="action_empty_notifications">Премахнете известията</string> <string name="action_empty_notifications">Премахнете известията</string>
<string name="action_empty_trashbin">Изпразване на кошчето</string> <string name="action_empty_trashbin">Изпразване на кошчето</string>
@ -153,7 +152,6 @@
<string name="confirmation_remove_folder_alert">Наистина ли желаете %1$s и съдържанието ѝ да бъдат изтрито?</string> <string name="confirmation_remove_folder_alert">Наистина ли желаете %1$s и съдържанието ѝ да бъдат изтрито?</string>
<string name="confirmation_remove_folders_alert">Наистина ли желаете избраните елементи и съдържанието им да бъдат премахнати?</string> <string name="confirmation_remove_folders_alert">Наистина ли желаете избраните елементи и съдържанието им да бъдат премахнати?</string>
<string name="confirmation_remove_local">Само локално</string> <string name="confirmation_remove_local">Само локално</string>
<string name="conflict_dialog_error">Грешка при създаване на диалог за конфликт!</string>
<string name="conflict_file_headline">Несъвместим файл %1$s</string> <string name="conflict_file_headline">Несъвместим файл %1$s</string>
<string name="conflict_local_file">Локален файл</string> <string name="conflict_local_file">Локален файл</string>
<string name="conflict_message_description">Ако изберете и двете версии, ще бъде добавен номер към името на локалния файл.</string> <string name="conflict_message_description">Ако изберете и двете версии, ще бъде добавен номер към името на локалния файл.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">C\'hwitet eo bet ar c\'houiñ eus anr c\'hont</string> <string name="account_creation_failed">C\'hwitet eo bet ar c\'houiñ eus anr c\'hont</string>
<string name="account_icon">Ikonenn kont</string> <string name="account_icon">Ikonenn kont</string>
<string name="account_not_found">N\'o ket bet kavet ar c\'hont</string> <string name="account_not_found">N\'o ket bet kavet ar c\'hont</string>
<string name="action_clear_failed_uploads">Lemmel ar pellgasoù chwitet</string>
<string name="action_edit">Cheñch</string> <string name="action_edit">Cheñch</string>
<string name="action_empty_notifications">Lemmel toud ar c\'hemenadennoù</string> <string name="action_empty_notifications">Lemmel toud ar c\'hemenadennoù</string>
<string name="action_send_share">Kas/Rannan</string> <string name="action_send_share">Kas/Rannan</string>
@ -136,7 +135,6 @@
<string name="confirmation_remove_folder_alert">Sur oc\'h lemel %1$s ha pep tra a zo barzh ?</string> <string name="confirmation_remove_folder_alert">Sur oc\'h lemel %1$s ha pep tra a zo barzh ?</string>
<string name="confirmation_remove_folders_alert">Sur oc\'h lemel an traoù choazet ha pep tra a zo barzh ?</string> <string name="confirmation_remove_folders_alert">Sur oc\'h lemel an traoù choazet ha pep tra a zo barzh ?</string>
<string name="confirmation_remove_local">E-berzh nemetken</string> <string name="confirmation_remove_local">E-berzh nemetken</string>
<string name="conflict_dialog_error">Ur fazi en deus krouet divizoù diemglev !</string>
<string name="conflict_message_description">Ma choazit an daou stumm, ar restr diabarzh en do un niver ouzhpennet war e anv.</string> <string name="conflict_message_description">Ma choazit an daou stumm, ar restr diabarzh en do un niver ouzhpennet war e anv.</string>
<string name="contactlist_item_icon">Skeudenn implijer evit ar roll darempredoù</string> <string name="contactlist_item_icon">Skeudenn implijer evit ar roll darempredoù</string>
<string name="contactlist_no_permission">Oaetre ebet roet, netra a zo bet emporzhiet.</string> <string name="contactlist_no_permission">Oaetre ebet roet, netra a zo bet emporzhiet.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Ha fallat la creació del compte</string> <string name="account_creation_failed">Ha fallat la creació del compte</string>
<string name="account_icon">Icona del compte</string> <string name="account_icon">Icona del compte</string>
<string name="account_not_found">No s\'ha trobat el compte!</string> <string name="account_not_found">No s\'ha trobat el compte!</string>
<string name="action_clear_failed_uploads">Esborra les pujades amb errors</string>
<string name="action_edit">Edita</string> <string name="action_edit">Edita</string>
<string name="action_empty_notifications">Neteja totes les notificacions</string> <string name="action_empty_notifications">Neteja totes les notificacions</string>
<string name="action_empty_trashbin">Buida la paperera</string> <string name="action_empty_trashbin">Buida la paperera</string>
@ -152,7 +151,6 @@
<string name="confirmation_remove_folder_alert">Esteu segur que voleu suprimir %1$s i els seus continguts?</string> <string name="confirmation_remove_folder_alert">Esteu segur que voleu suprimir %1$s i els seus continguts?</string>
<string name="confirmation_remove_folders_alert">Esteu segur que voleu suprimir els elements seleccionats i el seu contingut?</string> <string name="confirmation_remove_folders_alert">Esteu segur que voleu suprimir els elements seleccionats i el seu contingut?</string>
<string name="confirmation_remove_local">Només local</string> <string name="confirmation_remove_local">Només local</string>
<string name="conflict_dialog_error">Error creant diàleg de conflicte!</string>
<string name="conflict_file_headline">Fitxer en conflicte %1$s</string> <string name="conflict_file_headline">Fitxer en conflicte %1$s</string>
<string name="conflict_local_file">Fitxer local</string> <string name="conflict_local_file">Fitxer local</string>
<string name="conflict_message_description">Si seleccioneu ambdues versions, s\'afegirà un numero al nom del fitxer local.</string> <string name="conflict_message_description">Si seleccioneu ambdues versions, s\'afegirà un numero al nom del fitxer local.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Vytvoření účtu se nezdařilo</string> <string name="account_creation_failed">Vytvoření účtu se nezdařilo</string>
<string name="account_icon">Ikona účtu</string> <string name="account_icon">Ikona účtu</string>
<string name="account_not_found">Účet nenalezen!</string> <string name="account_not_found">Účet nenalezen!</string>
<string name="action_clear_failed_uploads">Vyčistit nezdařená nahrávání</string>
<string name="action_edit">Upravit</string> <string name="action_edit">Upravit</string>
<string name="action_empty_notifications">Vyčistit všechna upozornění</string> <string name="action_empty_notifications">Vyčistit všechna upozornění</string>
<string name="action_empty_trashbin">Vyprázdnit koš</string> <string name="action_empty_trashbin">Vyprázdnit koš</string>
@ -43,6 +42,7 @@
<string name="assistant_screen_successful_task_text">Dokončeno</string> <string name="assistant_screen_successful_task_text">Dokončeno</string>
<string name="assistant_screen_task_delete_success_message">Úloha úspěšně smazána</string> <string name="assistant_screen_task_delete_success_message">Úloha úspěšně smazána</string>
<string name="assistant_screen_unknown_task_status_text">Neznámé</string> <string name="assistant_screen_unknown_task_status_text">Neznámé</string>
<string name="assistant_task_detail_screen_output_button_title">Výstup</string>
<string name="associated_account_not_found">Související účet nenalezen!</string> <string name="associated_account_not_found">Související účet nenalezen!</string>
<string name="auth_access_failed">Přístup se nezdařil: %1$s</string> <string name="auth_access_failed">Přístup se nezdařil: %1$s</string>
<string name="auth_account_does_not_exist">Účet zatím není na tomto zařízení přidán</string> <string name="auth_account_does_not_exist">Účet zatím není na tomto zařízení přidán</string>
@ -157,7 +157,6 @@
<string name="confirmation_remove_folder_alert">Opravdu chcete %1$s a jeho obsah odstranit?</string> <string name="confirmation_remove_folder_alert">Opravdu chcete %1$s a jeho obsah odstranit?</string>
<string name="confirmation_remove_folders_alert">Opravdu chcete vybrané položky a jejich obsah odstranit?</string> <string name="confirmation_remove_folders_alert">Opravdu chcete vybrané položky a jejich obsah odstranit?</string>
<string name="confirmation_remove_local">Pouze místní</string> <string name="confirmation_remove_local">Pouze místní</string>
<string name="conflict_dialog_error">Chyba při vytváření dialogu ke konfliktu!</string>
<string name="conflict_file_headline">Kolidující soubor %1$s</string> <string name="conflict_file_headline">Kolidující soubor %1$s</string>
<string name="conflict_local_file">Místní soubor</string> <string name="conflict_local_file">Místní soubor</string>
<string name="conflict_message_description">Pokud zvolíte obě verze, k názvu místního souboru bude připojeno číslo.</string> <string name="conflict_message_description">Pokud zvolíte obě verze, k názvu místního souboru bude připojeno číslo.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Fejl ved oprettelse af konto</string> <string name="account_creation_failed">Fejl ved oprettelse af konto</string>
<string name="account_icon">Kontoikon</string> <string name="account_icon">Kontoikon</string>
<string name="account_not_found">Konto blev ikke fundet.</string> <string name="account_not_found">Konto blev ikke fundet.</string>
<string name="action_clear_failed_uploads">Fjern fejlede uploads</string>
<string name="action_edit">Redigér</string> <string name="action_edit">Redigér</string>
<string name="action_empty_notifications">Ryd alle notifikationer</string> <string name="action_empty_notifications">Ryd alle notifikationer</string>
<string name="action_empty_trashbin">Tøm papirkurv</string> <string name="action_empty_trashbin">Tøm papirkurv</string>
@ -165,7 +164,6 @@
<string name="confirmation_remove_folder_alert">Er du sikker på at du vil slette %1$s med indhold?</string> <string name="confirmation_remove_folder_alert">Er du sikker på at du vil slette %1$s med indhold?</string>
<string name="confirmation_remove_folders_alert">Er du sikker på at du vil slette de valgte artikler med indhold?</string> <string name="confirmation_remove_folders_alert">Er du sikker på at du vil slette de valgte artikler med indhold?</string>
<string name="confirmation_remove_local">Kun lokal</string> <string name="confirmation_remove_local">Kun lokal</string>
<string name="conflict_dialog_error">Fejl ved skabelse af konfliktdialog</string>
<string name="conflict_file_headline">Fil i konflikt %1$s</string> <string name="conflict_file_headline">Fil i konflikt %1$s</string>
<string name="conflict_local_file">Lokal fil</string> <string name="conflict_local_file">Lokal fil</string>
<string name="conflict_message_description">Hvis du vælger begge versioner, vil den lokale fil få tilføjet et nummer til sit navn.</string> <string name="conflict_message_description">Hvis du vælger begge versioner, vil den lokale fil få tilføjet et nummer til sit navn.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Kontoerstellung fehlgeschlagen</string> <string name="account_creation_failed">Kontoerstellung fehlgeschlagen</string>
<string name="account_icon">Konto-Icon</string> <string name="account_icon">Konto-Icon</string>
<string name="account_not_found">Kein Konto gefunden</string> <string name="account_not_found">Kein Konto gefunden</string>
<string name="action_clear_failed_uploads">Fehlgeschlagene Uploads entfernen</string>
<string name="action_edit">Bearbeiten</string> <string name="action_edit">Bearbeiten</string>
<string name="action_empty_notifications">Alle Benachrichtigungen löschen</string> <string name="action_empty_notifications">Alle Benachrichtigungen löschen</string>
<string name="action_empty_trashbin">Papierkorb leeren</string> <string name="action_empty_trashbin">Papierkorb leeren</string>
@ -57,6 +56,8 @@
<string name="assistant_screen_task_types_error_state_message">Die Aufgabentypen können nicht abgerufen werden. Bitte überprüfen Sie Ihre Internetverbindung.</string> <string name="assistant_screen_task_types_error_state_message">Die Aufgabentypen können nicht abgerufen werden. Bitte überprüfen Sie Ihre Internetverbindung.</string>
<string name="assistant_screen_top_bar_title">Assistent</string> <string name="assistant_screen_top_bar_title">Assistent</string>
<string name="assistant_screen_unknown_task_status_text">Unbekannt</string> <string name="assistant_screen_unknown_task_status_text">Unbekannt</string>
<string name="assistant_task_detail_screen_input_button_title">Eingabe</string>
<string name="assistant_task_detail_screen_output_button_title">Ausgabe</string>
<string name="associated_account_not_found">Verknüpftes Konto nicht gefunden!</string> <string name="associated_account_not_found">Verknüpftes Konto nicht gefunden!</string>
<string name="auth_access_failed">Zugriffsfehler: %1$s</string> <string name="auth_access_failed">Zugriffsfehler: %1$s</string>
<string name="auth_account_does_not_exist">Das Konto ist bislang auf dem Gerät nicht vorhanden</string> <string name="auth_account_does_not_exist">Das Konto ist bislang auf dem Gerät nicht vorhanden</string>
@ -171,7 +172,6 @@
<string name="confirmation_remove_folder_alert">Wollen Sie %1$s und deren Inhalte wirklich löschen?</string> <string name="confirmation_remove_folder_alert">Wollen Sie %1$s und deren Inhalte wirklich löschen?</string>
<string name="confirmation_remove_folders_alert">Möchten Sie die ausgewählten Elemente und deren inhalt wirklich löschen?</string> <string name="confirmation_remove_folders_alert">Möchten Sie die ausgewählten Elemente und deren inhalt wirklich löschen?</string>
<string name="confirmation_remove_local">Nur lokal</string> <string name="confirmation_remove_local">Nur lokal</string>
<string name="conflict_dialog_error">Fehler beim Erstellen des Konfliktdialoges</string>
<string name="conflict_file_headline">Konflikt-Datei %1$s</string> <string name="conflict_file_headline">Konflikt-Datei %1$s</string>
<string name="conflict_local_file">Lokale Datei</string> <string name="conflict_local_file">Lokale Datei</string>
<string name="conflict_message_description">Falls beide Versionen gewählt werden, wird bei der lokalen Datei eine Zahl am Ende des Dateinamens hinzugefügt.</string> <string name="conflict_message_description">Falls beide Versionen gewählt werden, wird bei der lokalen Datei eine Zahl am Ende des Dateinamens hinzugefügt.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Αποτυχία δημιουργίας λογαριασμού</string> <string name="account_creation_failed">Αποτυχία δημιουργίας λογαριασμού</string>
<string name="account_icon">Εικονίδιο λογαριασμού</string> <string name="account_icon">Εικονίδιο λογαριασμού</string>
<string name="account_not_found">Δεν βρέθηκε λογαριασμός!</string> <string name="account_not_found">Δεν βρέθηκε λογαριασμός!</string>
<string name="action_clear_failed_uploads">Εκκαθάριση αποτυχημένων μεταφορτώσεων</string>
<string name="action_edit">Επεξεργασία</string> <string name="action_edit">Επεξεργασία</string>
<string name="action_empty_notifications">Εκκαθάριση ειδοποιήσεων</string> <string name="action_empty_notifications">Εκκαθάριση ειδοποιήσεων</string>
<string name="action_empty_trashbin">Άδειασμα απορριμάτων</string> <string name="action_empty_trashbin">Άδειασμα απορριμάτων</string>
@ -151,7 +150,6 @@
<string name="confirmation_remove_folder_alert">Θέλετε σίγουρα να διαγράψετε το %1$s και τα περιεχόμενά του;</string> <string name="confirmation_remove_folder_alert">Θέλετε σίγουρα να διαγράψετε το %1$s και τα περιεχόμενά του;</string>
<string name="confirmation_remove_folders_alert">Θέλετε να διαγράψετε τα επιλεγμένα αντικείμενα και τα περιεχόμενά τους;</string> <string name="confirmation_remove_folders_alert">Θέλετε να διαγράψετε τα επιλεγμένα αντικείμενα και τα περιεχόμενά τους;</string>
<string name="confirmation_remove_local">Μόνο τοπικά</string> <string name="confirmation_remove_local">Μόνο τοπικά</string>
<string name="conflict_dialog_error">Σφάλμα δημιουργίας αναφοράς διένεξης!</string>
<string name="conflict_file_headline">Αρχείο σε αντίφαση %1$s</string> <string name="conflict_file_headline">Αρχείο σε αντίφαση %1$s</string>
<string name="conflict_local_file">Τοπικό αρχείο</string> <string name="conflict_local_file">Τοπικό αρχείο</string>
<string name="conflict_message_description">Εάν επιλέξετε και τις δύο εκδόσεις, στο όνομα του τοπικού αρχείου θα προστεθεί ένας αριθμός.</string> <string name="conflict_message_description">Εάν επιλέξετε και τις δύο εκδόσεις, στο όνομα του τοπικού αρχείου θα προστεθεί ένας αριθμός.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Kreado de konto malsukcesis</string> <string name="account_creation_failed">Kreado de konto malsukcesis</string>
<string name="account_icon">Konta piktogramo</string> <string name="account_icon">Konta piktogramo</string>
<string name="account_not_found">Konto ne trovita!</string> <string name="account_not_found">Konto ne trovita!</string>
<string name="action_clear_failed_uploads">Vakigi malsukcesajn alŝutojn</string>
<string name="action_edit">Modifi</string> <string name="action_edit">Modifi</string>
<string name="action_empty_notifications">Forviŝi ĉiujn sciigojn</string> <string name="action_empty_notifications">Forviŝi ĉiujn sciigojn</string>
<string name="action_empty_trashbin">Malpleni rubujon</string> <string name="action_empty_trashbin">Malpleni rubujon</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Falló la creación de la carpeta</string> <string name="account_creation_failed">Falló la creación de la carpeta</string>
<string name="account_icon">Icono de cuenta</string> <string name="account_icon">Icono de cuenta</string>
<string name="account_not_found">Cuenta no encontrada!</string> <string name="account_not_found">Cuenta no encontrada!</string>
<string name="action_clear_failed_uploads">Borrar subidas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Borrar todas las notificaciones</string> <string name="action_empty_notifications">Borrar todas las notificaciones</string>
<string name="action_empty_trashbin">Vaciar la papelera</string> <string name="action_empty_trashbin">Vaciar la papelera</string>
@ -150,7 +149,6 @@
<string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y su contenido?</string> <string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y su contenido?</string>
<string name="confirmation_remove_folders_alert">¿Realmente desea eliminar los elementos seleccionados y sus contenidos?</string> <string name="confirmation_remove_folders_alert">¿Realmente desea eliminar los elementos seleccionados y sus contenidos?</string>
<string name="confirmation_remove_local">Sólo local</string> <string name="confirmation_remove_local">Sólo local</string>
<string name="conflict_dialog_error">¡Error al crear el diálogo de conflicto!</string>
<string name="conflict_file_headline">Archivo en conflicto %1$s</string> <string name="conflict_file_headline">Archivo en conflicto %1$s</string>
<string name="conflict_local_file">Archivo local</string> <string name="conflict_local_file">Archivo local</string>
<string name="conflict_message_description">Si selecciona ambas versiones, se le agregará un número al nombre del archivo copiado.</string> <string name="conflict_message_description">Si selecciona ambas versiones, se le agregará un número al nombre del archivo copiado.</string>

View file

@ -5,7 +5,6 @@
<string name="about_version">versión %1$s</string> <string name="about_version">versión %1$s</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_send_share">Enviar/Compartir</string> <string name="action_send_share">Enviar/Compartir</string>
<string name="action_switch_grid_view">Vista de cuadrícula</string> <string name="action_switch_grid_view">Vista de cuadrícula</string>

View file

@ -6,7 +6,6 @@
<string name="account_creation_failed">Fallo en la creación de la cuenta</string> <string name="account_creation_failed">Fallo en la creación de la cuenta</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Borrar todas las notificaciones</string> <string name="action_empty_notifications">Borrar todas las notificaciones</string>
<string name="action_empty_trashbin">Vacíar la papelera</string> <string name="action_empty_trashbin">Vacíar la papelera</string>

View file

@ -5,7 +5,6 @@
<string name="about_version">versión %1$s</string> <string name="about_version">versión %1$s</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_send_share">Enviar/Compartir</string> <string name="action_send_share">Enviar/Compartir</string>
<string name="action_switch_grid_view">Vista de cuadrícula</string> <string name="action_switch_grid_view">Vista de cuadrícula</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Error al crear la cuenta</string> <string name="account_creation_failed">Error al crear la cuenta</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Borrar todas las notificaciones</string> <string name="action_empty_notifications">Borrar todas las notificaciones</string>
<string name="action_send_share">Enviar/Compartir</string> <string name="action_send_share">Enviar/Compartir</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Creación de cuenta fallida</string> <string name="account_creation_failed">Creación de cuenta fallida</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Borrar todas las notificaciones</string> <string name="action_empty_notifications">Borrar todas las notificaciones</string>
<string name="action_empty_trashbin">Eliminar papelera de reciclaje</string> <string name="action_empty_trashbin">Eliminar papelera de reciclaje</string>
@ -153,7 +152,6 @@
<string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y sus contenidos? </string> <string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y sus contenidos? </string>
<string name="confirmation_remove_folders_alert">¿Reamente deseas eliminar los elementos seleccionados y sus contenidos?</string> <string name="confirmation_remove_folders_alert">¿Reamente deseas eliminar los elementos seleccionados y sus contenidos?</string>
<string name="confirmation_remove_local">Sólo local</string> <string name="confirmation_remove_local">Sólo local</string>
<string name="conflict_dialog_error">¡Error al crear el diálogo de conflicto!</string>
<string name="conflict_file_headline">Archivo en conflicto %1$s</string> <string name="conflict_file_headline">Archivo en conflicto %1$s</string>
<string name="conflict_local_file">Archivo local</string> <string name="conflict_local_file">Archivo local</string>
<string name="conflict_message_description">Si selecciona ambas versiones, el archivo local tendrá un número agregado a su nombre.</string> <string name="conflict_message_description">Si selecciona ambas versiones, el archivo local tendrá un número agregado a su nombre.</string>

View file

@ -5,7 +5,6 @@
<string name="about_version">versión %1$s</string> <string name="about_version">versión %1$s</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_send_share">Enviar/Compartir</string> <string name="action_send_share">Enviar/Compartir</string>
<string name="action_switch_grid_view">Vista de cuadrícula</string> <string name="action_switch_grid_view">Vista de cuadrícula</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Falló la creación de la cuenta</string> <string name="account_creation_failed">Falló la creación de la cuenta</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Limpiar todas las notificaciones</string> <string name="action_empty_notifications">Limpiar todas las notificaciones</string>
<string name="action_empty_trashbin">Vaciar la papelera de reciclaje</string> <string name="action_empty_trashbin">Vaciar la papelera de reciclaje</string>
@ -171,7 +170,6 @@
<string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y sus contenidos? </string> <string name="confirmation_remove_folder_alert">¿Realmente quieres eliminar %1$s y sus contenidos? </string>
<string name="confirmation_remove_folders_alert">¿Reamente deseas eliminar los elementos seleccionados y sus contenidos?</string> <string name="confirmation_remove_folders_alert">¿Reamente deseas eliminar los elementos seleccionados y sus contenidos?</string>
<string name="confirmation_remove_local">Sólo local</string> <string name="confirmation_remove_local">Sólo local</string>
<string name="conflict_dialog_error">¡Se presentó un error al crear el diálogo de conflictos!</string>
<string name="conflict_file_headline">Archivo conflictivo %1$s</string> <string name="conflict_file_headline">Archivo conflictivo %1$s</string>
<string name="conflict_local_file">Archivo local</string> <string name="conflict_local_file">Archivo local</string>
<string name="conflict_message_description">Si seleccionas ambas versiones, el archivo local tendrá un número al final del nombre.</string> <string name="conflict_message_description">Si seleccionas ambas versiones, el archivo local tendrá un número al final del nombre.</string>

View file

@ -5,7 +5,6 @@
<string name="about_version">versión %1$s</string> <string name="about_version">versión %1$s</string>
<string name="account_icon">Ícono de la cuenta</string> <string name="account_icon">Ícono de la cuenta</string>
<string name="account_not_found">¡No se encontró la cuenta!</string> <string name="account_not_found">¡No se encontró la cuenta!</string>
<string name="action_clear_failed_uploads">Borrar cargas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_send_share">Enviar/Compartir</string> <string name="action_send_share">Enviar/Compartir</string>
<string name="action_switch_grid_view">Vista de cuadrícula</string> <string name="action_switch_grid_view">Vista de cuadrícula</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Ha fallado la creación de la cuenta</string> <string name="account_creation_failed">Ha fallado la creación de la cuenta</string>
<string name="account_icon">Icono de la cuenta</string> <string name="account_icon">Icono de la cuenta</string>
<string name="account_not_found">¡Cuenta no encontrada!</string> <string name="account_not_found">¡Cuenta no encontrada!</string>
<string name="action_clear_failed_uploads">Borrar subidas fallidas</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Limpiar todas las notificaciones</string> <string name="action_empty_notifications">Limpiar todas las notificaciones</string>
<string name="action_empty_trashbin">Vaciar papelera</string> <string name="action_empty_trashbin">Vaciar papelera</string>
@ -47,6 +46,8 @@
<string name="assistant_screen_task_delete_success_message">¡La tarea fue eliminada exitósamente!</string> <string name="assistant_screen_task_delete_success_message">¡La tarea fue eliminada exitósamente!</string>
<string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Eliminar tarea</string> <string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Eliminar tarea</string>
<string name="assistant_screen_unknown_task_status_text">Desconocido</string> <string name="assistant_screen_unknown_task_status_text">Desconocido</string>
<string name="assistant_task_detail_screen_input_button_title">Entrada</string>
<string name="assistant_task_detail_screen_output_button_title">Salida</string>
<string name="associated_account_not_found">¡Cuenta asociada no encontrada!</string> <string name="associated_account_not_found">¡Cuenta asociada no encontrada!</string>
<string name="auth_access_failed">Acceso fallido: %1$s</string> <string name="auth_access_failed">Acceso fallido: %1$s</string>
<string name="auth_account_does_not_exist">La cuenta no se ha añadido aún en este dispositivo</string> <string name="auth_account_does_not_exist">La cuenta no se ha añadido aún en este dispositivo</string>
@ -160,7 +161,6 @@
<string name="confirmation_remove_folder_alert">¿Realmente deseas eliminar %1$s y todo su contenido?</string> <string name="confirmation_remove_folder_alert">¿Realmente deseas eliminar %1$s y todo su contenido?</string>
<string name="confirmation_remove_folders_alert">¿Estás seguro de que quieres eliminar los elementos seleccionados y sus contenidos?</string> <string name="confirmation_remove_folders_alert">¿Estás seguro de que quieres eliminar los elementos seleccionados y sus contenidos?</string>
<string name="confirmation_remove_local">Solo local</string> <string name="confirmation_remove_local">Solo local</string>
<string name="conflict_dialog_error">¡Error al crear el diálogo de conflicto!</string>
<string name="conflict_file_headline">Conflicto en archivo %1$s</string> <string name="conflict_file_headline">Conflicto en archivo %1$s</string>
<string name="conflict_local_file">Archivo local</string> <string name="conflict_local_file">Archivo local</string>
<string name="conflict_message_description">Si seleccionas ambas versiones, el archivo local tendrá un número añadido a su nombre.</string> <string name="conflict_message_description">Si seleccionas ambas versiones, el archivo local tendrá un número añadido a su nombre.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Konto loomine ebaõnnestus</string> <string name="account_creation_failed">Konto loomine ebaõnnestus</string>
<string name="account_icon">Konto ikoon</string> <string name="account_icon">Konto ikoon</string>
<string name="account_not_found">Kontot ei leitud!</string> <string name="account_not_found">Kontot ei leitud!</string>
<string name="action_clear_failed_uploads">Puhasta ebaõnnestunud üleslaadimised</string>
<string name="action_edit">Redigeeri</string> <string name="action_edit">Redigeeri</string>
<string name="action_empty_notifications">Kustuta kõik teavitused</string> <string name="action_empty_notifications">Kustuta kõik teavitused</string>
<string name="action_empty_trashbin">Tühjenda prügikast</string> <string name="action_empty_trashbin">Tühjenda prügikast</string>
@ -136,7 +135,6 @@
<string name="confirmation_remove_folder_alert">Oled sa kindel, et soovid %1$s ja selle sisu kustutada?</string> <string name="confirmation_remove_folder_alert">Oled sa kindel, et soovid %1$s ja selle sisu kustutada?</string>
<string name="confirmation_remove_folders_alert">Oled sa kindel, et soovid valitud objektid ja nende sisud kustutada?</string> <string name="confirmation_remove_folders_alert">Oled sa kindel, et soovid valitud objektid ja nende sisud kustutada?</string>
<string name="confirmation_remove_local">Ainult kohalik</string> <string name="confirmation_remove_local">Ainult kohalik</string>
<string name="conflict_dialog_error">Konfliktidialoogi loomine ebaõnnestus!</string>
<string name="conflict_local_file">Kohalik fail</string> <string name="conflict_local_file">Kohalik fail</string>
<string name="conflict_message_description">Kui valid mõlemad versioonid, siis lisatakse kohaliku faili nimele number.</string> <string name="conflict_message_description">Kui valid mõlemad versioonid, siis lisatakse kohaliku faili nimele number.</string>
<string name="conflict_server_file">Serveri fail</string> <string name="conflict_server_file">Serveri fail</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Kontuaren sorrerak huts egin du</string> <string name="account_creation_failed">Kontuaren sorrerak huts egin du</string>
<string name="account_icon">Kontuaren ikonoa</string> <string name="account_icon">Kontuaren ikonoa</string>
<string name="account_not_found">Ez da kontua aurkitu!</string> <string name="account_not_found">Ez da kontua aurkitu!</string>
<string name="action_clear_failed_uploads">Garbitu huts egin duten igoerak</string>
<string name="action_edit">Aldatu</string> <string name="action_edit">Aldatu</string>
<string name="action_empty_notifications">Garbitu jakinarazpen guztiak</string> <string name="action_empty_notifications">Garbitu jakinarazpen guztiak</string>
<string name="action_empty_trashbin">Hustu zakarrontzia</string> <string name="action_empty_trashbin">Hustu zakarrontzia</string>
@ -47,6 +46,8 @@
<string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Ezabatu zeregina</string> <string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Ezabatu zeregina</string>
<string name="assistant_screen_top_bar_title">Morroia</string> <string name="assistant_screen_top_bar_title">Morroia</string>
<string name="assistant_screen_unknown_task_status_text">Ezezaguna</string> <string name="assistant_screen_unknown_task_status_text">Ezezaguna</string>
<string name="assistant_task_detail_screen_input_button_title">Sarrera</string>
<string name="assistant_task_detail_screen_output_button_title">Irteera</string>
<string name="associated_account_not_found">Ez da aurkitu lotutako konturik</string> <string name="associated_account_not_found">Ez da aurkitu lotutako konturik</string>
<string name="auth_access_failed">Huts egin du atzitzean: %1$s</string> <string name="auth_access_failed">Huts egin du atzitzean: %1$s</string>
<string name="auth_account_does_not_exist">Kontua ez da gailu honetan gehitu oraindik</string> <string name="auth_account_does_not_exist">Kontua ez da gailu honetan gehitu oraindik</string>
@ -161,7 +162,6 @@
<string name="confirmation_remove_folder_alert">Ziur zaude %1$s eta bere edukia ezabatu nahi duzula?</string> <string name="confirmation_remove_folder_alert">Ziur zaude %1$s eta bere edukia ezabatu nahi duzula?</string>
<string name="confirmation_remove_folders_alert">Ziur zaude hautatutako elementuak eta beren edukiak ezabatu nahi dituzula?</string> <string name="confirmation_remove_folders_alert">Ziur zaude hautatutako elementuak eta beren edukiak ezabatu nahi dituzula?</string>
<string name="confirmation_remove_local">Lokala bakarrik</string> <string name="confirmation_remove_local">Lokala bakarrik</string>
<string name="conflict_dialog_error">Errorea gatazkaren elkarrizketa-koadroa sortzean!</string>
<string name="conflict_file_headline">%1$sfitxategi gatazkatsua</string> <string name="conflict_file_headline">%1$sfitxategi gatazkatsua</string>
<string name="conflict_local_file">Fitxategi lokala</string> <string name="conflict_local_file">Fitxategi lokala</string>
<string name="conflict_message_description">Bi bertsioak hautatzen badituzu, fitxategi lokalaren izenari zenbaki bat gehituko zaio.</string> <string name="conflict_message_description">Bi bertsioak hautatzen badituzu, fitxategi lokalaren izenari zenbaki bat gehituko zaio.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">ایجاد حساب ناموفق بود</string> <string name="account_creation_failed">ایجاد حساب ناموفق بود</string>
<string name="account_icon">آیکون حساب</string> <string name="account_icon">آیکون حساب</string>
<string name="account_not_found">حساب پیدا نشد!</string> <string name="account_not_found">حساب پیدا نشد!</string>
<string name="action_clear_failed_uploads">پاک کردن آپلودهای ناموفق</string>
<string name="action_edit">ویرایش</string> <string name="action_edit">ویرایش</string>
<string name="action_empty_notifications">پاک کردن تمام اعلانها</string> <string name="action_empty_notifications">پاک کردن تمام اعلانها</string>
<string name="action_empty_trashbin">خالی کردن سطل زباله</string> <string name="action_empty_trashbin">خالی کردن سطل زباله</string>
@ -158,7 +157,6 @@
<string name="confirmation_remove_folder_alert">آیا واقعا می خواهید %1$s و محتویات آن را حذف کنید؟</string> <string name="confirmation_remove_folder_alert">آیا واقعا می خواهید %1$s و محتویات آن را حذف کنید؟</string>
<string name="confirmation_remove_folders_alert">آیا واقعاً می‌خواهید موارد انتخاب شده و محتوای آنها حذف شود؟</string> <string name="confirmation_remove_folders_alert">آیا واقعاً می‌خواهید موارد انتخاب شده و محتوای آنها حذف شود؟</string>
<string name="confirmation_remove_local">فقط محلی</string> <string name="confirmation_remove_local">فقط محلی</string>
<string name="conflict_dialog_error">هنگام ساختن دیالوگ مغایرت‌ها خطایی رخ داده است!</string>
<string name="conflict_file_headline">فایل متناقض %1$s</string> <string name="conflict_file_headline">فایل متناقض %1$s</string>
<string name="conflict_local_file">پروندهٔ محلّی</string> <string name="conflict_local_file">پروندهٔ محلّی</string>
<string name="conflict_message_description">اگر هردو نسخه را انتخاب کنید، یک شماره به نام فایل محلی اضافه خواهد شد.</string> <string name="conflict_message_description">اگر هردو نسخه را انتخاب کنید، یک شماره به نام فایل محلی اضافه خواهد شد.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Tilin luonti epäonnistui</string> <string name="account_creation_failed">Tilin luonti epäonnistui</string>
<string name="account_icon">Tilikuvake</string> <string name="account_icon">Tilikuvake</string>
<string name="account_not_found">Tiliä ei löydy!</string> <string name="account_not_found">Tiliä ei löydy!</string>
<string name="action_clear_failed_uploads">Tyhjennä epäonnistuneet lähetykset</string>
<string name="action_edit">Muokkaa</string> <string name="action_edit">Muokkaa</string>
<string name="action_empty_notifications">Hylkää kaikki ilmoitukset</string> <string name="action_empty_notifications">Hylkää kaikki ilmoitukset</string>
<string name="action_empty_trashbin">Tyhjennä roskakori</string> <string name="action_empty_trashbin">Tyhjennä roskakori</string>
@ -158,7 +157,6 @@
<string name="confirmation_remove_folder_alert">Haluatko varmasti poistaa kohteen %1$s ja sen sisällön?</string> <string name="confirmation_remove_folder_alert">Haluatko varmasti poistaa kohteen %1$s ja sen sisällön?</string>
<string name="confirmation_remove_folders_alert">Haluatko varmasti poistaa valitut kohteet ja niiden sisällön?</string> <string name="confirmation_remove_folders_alert">Haluatko varmasti poistaa valitut kohteet ja niiden sisällön?</string>
<string name="confirmation_remove_local">Vain paikallisen</string> <string name="confirmation_remove_local">Vain paikallisen</string>
<string name="conflict_dialog_error">Virhe konfliktitietojen näyttämisessä!</string>
<string name="conflict_file_headline">Ristiriitainen kohde %1$s</string> <string name="conflict_file_headline">Ristiriitainen kohde %1$s</string>
<string name="conflict_local_file">Paikallinen tiedosto</string> <string name="conflict_local_file">Paikallinen tiedosto</string>
<string name="conflict_message_description">Jos valitset molemmat versiot, paikallisen tiedoston nimeen lisätään numero.</string> <string name="conflict_message_description">Jos valitset molemmat versiot, paikallisen tiedoston nimeen lisätään numero.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Échec de création du compte</string> <string name="account_creation_failed">Échec de création du compte</string>
<string name="account_icon">Icône du compte</string> <string name="account_icon">Icône du compte</string>
<string name="account_not_found">Compte introuvable !</string> <string name="account_not_found">Compte introuvable !</string>
<string name="action_clear_failed_uploads">Effacer les téléversements échoués</string>
<string name="action_edit">Modifier</string> <string name="action_edit">Modifier</string>
<string name="action_empty_notifications">Effacer toutes les notifications</string> <string name="action_empty_notifications">Effacer toutes les notifications</string>
<string name="action_empty_trashbin">Vider la corbeille</string> <string name="action_empty_trashbin">Vider la corbeille</string>
@ -57,6 +56,8 @@
<string name="assistant_screen_task_types_error_state_message">Impossible de récupérer les types des tâches, veuillez vérifier votre connexion Internet.</string> <string name="assistant_screen_task_types_error_state_message">Impossible de récupérer les types des tâches, veuillez vérifier votre connexion Internet.</string>
<string name="assistant_screen_top_bar_title">Assistant</string> <string name="assistant_screen_top_bar_title">Assistant</string>
<string name="assistant_screen_unknown_task_status_text">Inconnu</string> <string name="assistant_screen_unknown_task_status_text">Inconnu</string>
<string name="assistant_task_detail_screen_input_button_title">Entrée</string>
<string name="assistant_task_detail_screen_output_button_title">Sortie</string>
<string name="associated_account_not_found">Compte associé introuvable !</string> <string name="associated_account_not_found">Compte associé introuvable !</string>
<string name="auth_access_failed">L\'accès a échoué: %1$s</string> <string name="auth_access_failed">L\'accès a échoué: %1$s</string>
<string name="auth_account_does_not_exist">Le compte n\'est pas encore ajouté sur cet appareil</string> <string name="auth_account_does_not_exist">Le compte n\'est pas encore ajouté sur cet appareil</string>
@ -171,7 +172,6 @@
<string name="confirmation_remove_folder_alert">Voulez-vous vraiment supprimer %1$s et ses contenus ?</string> <string name="confirmation_remove_folder_alert">Voulez-vous vraiment supprimer %1$s et ses contenus ?</string>
<string name="confirmation_remove_folders_alert">Souhaitez-vous vraiment supprimer les éléments sélectionnés ainsi que leurs contenus ?</string> <string name="confirmation_remove_folders_alert">Souhaitez-vous vraiment supprimer les éléments sélectionnés ainsi que leurs contenus ?</string>
<string name="confirmation_remove_local">Local seulement</string> <string name="confirmation_remove_local">Local seulement</string>
<string name="conflict_dialog_error">Une erreur qui crée un dialogue conflictuel !</string>
<string name="conflict_file_headline">Fichier %1$s en conflit</string> <string name="conflict_file_headline">Fichier %1$s en conflit</string>
<string name="conflict_local_file">fichier local</string> <string name="conflict_local_file">fichier local</string>
<string name="conflict_message_description">Si vous sélectionnez les deux versions, le fichier local aura un numéro ajouté à son nom.</string> <string name="conflict_message_description">Si vous sélectionnez les deux versions, le fichier local aura un numéro ajouté à son nom.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Dhfhàillig cruthachadh a chunntais</string> <string name="account_creation_failed">Dhfhàillig cruthachadh a chunntais</string>
<string name="account_icon">Ìomhaigheag a chunntais</string> <string name="account_icon">Ìomhaigheag a chunntais</string>
<string name="account_not_found">Cha deach an cunntas a lorg!</string> <string name="account_not_found">Cha deach an cunntas a lorg!</string>
<string name="action_clear_failed_uploads">Falamhaich na luchdaidhean suas a dhfhàillig</string>
<string name="action_edit">Deasaich</string> <string name="action_edit">Deasaich</string>
<string name="action_empty_notifications">Falamhaich a h-uile brath</string> <string name="action_empty_notifications">Falamhaich a h-uile brath</string>
<string name="action_empty_trashbin">Falamhaich an sgudal</string> <string name="action_empty_trashbin">Falamhaich an sgudal</string>
@ -138,7 +137,6 @@
<string name="confirmation_remove_folder_alert">A bheil thu cinnteach gu bheil thu airson %1$s s a shusbaint a sguabadh às?</string> <string name="confirmation_remove_folder_alert">A bheil thu cinnteach gu bheil thu airson %1$s s a shusbaint a sguabadh às?</string>
<string name="confirmation_remove_folders_alert">A bheil thu cinnteach gu bheil thu airson na nithean a thagh thu s an susbaint a sguabadh às?</string> <string name="confirmation_remove_folders_alert">A bheil thu cinnteach gu bheil thu airson na nithean a thagh thu s an susbaint a sguabadh às?</string>
<string name="confirmation_remove_local">Ionadail a-mhàin</string> <string name="confirmation_remove_local">Ionadail a-mhàin</string>
<string name="conflict_dialog_error">Mearachd le cruthachadh còmhradh na còmhstri!</string>
<string name="conflict_file_headline">Faidhle %1$s ann an còmhstri</string> <string name="conflict_file_headline">Faidhle %1$s ann an còmhstri</string>
<string name="conflict_message_description">Ma thaghas tu an dà thionndadh, thèid àireamh a chur ri ainm an fhaidhle ionadail.</string> <string name="conflict_message_description">Ma thaghas tu an dà thionndadh, thèid àireamh a chur ri ainm an fhaidhle ionadail.</string>
<string name="contactlist_item_icon">Ìomhaigheag a chleachdaiche air liosta an luchd-aithne</string> <string name="contactlist_item_icon">Ìomhaigheag a chleachdaiche air liosta an luchd-aithne</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Produciuse un fallo ao crear a conta</string> <string name="account_creation_failed">Produciuse un fallo ao crear a conta</string>
<string name="account_icon">Icona da conta</string> <string name="account_icon">Icona da conta</string>
<string name="account_not_found">Non se atopou a conta!</string> <string name="account_not_found">Non se atopou a conta!</string>
<string name="action_clear_failed_uploads">Limpar os envíos fallados</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Limpar todas as notificacións</string> <string name="action_empty_notifications">Limpar todas as notificacións</string>
<string name="action_empty_trashbin">Baleirar o lixo</string> <string name="action_empty_trashbin">Baleirar o lixo</string>
@ -43,6 +42,7 @@
<string name="assistant_screen_successful_task_text">Completado</string> <string name="assistant_screen_successful_task_text">Completado</string>
<string name="assistant_screen_task_delete_success_message">A tarefa foi eliminada satisfactoriamente</string> <string name="assistant_screen_task_delete_success_message">A tarefa foi eliminada satisfactoriamente</string>
<string name="assistant_screen_unknown_task_status_text">Descoñecido</string> <string name="assistant_screen_unknown_task_status_text">Descoñecido</string>
<string name="assistant_task_detail_screen_input_button_title">Entrada</string>
<string name="associated_account_not_found">Non se atopou unha conta asociada!</string> <string name="associated_account_not_found">Non se atopou unha conta asociada!</string>
<string name="auth_access_failed">Acceso fallado: %1$s</string> <string name="auth_access_failed">Acceso fallado: %1$s</string>
<string name="auth_account_does_not_exist">A conta aínda non existe no dispositivo</string> <string name="auth_account_does_not_exist">A conta aínda non existe no dispositivo</string>
@ -155,7 +155,6 @@
<string name="confirmation_remove_folder_alert">Confirma que quere eliminar %1$s e todo o seu contido?</string> <string name="confirmation_remove_folder_alert">Confirma que quere eliminar %1$s e todo o seu contido?</string>
<string name="confirmation_remove_folders_alert">Confirma que quere eliminar os elementos seleccionados e o seu contido?</string> <string name="confirmation_remove_folders_alert">Confirma que quere eliminar os elementos seleccionados e o seu contido?</string>
<string name="confirmation_remove_local">Só local</string> <string name="confirmation_remove_local">Só local</string>
<string name="conflict_dialog_error">Produciuse un erro ao crear o diálogo de conflitos!</string>
<string name="conflict_file_headline">Ficheiro en conflito %1$s</string> <string name="conflict_file_headline">Ficheiro en conflito %1$s</string>
<string name="conflict_local_file">Ficheiro local</string> <string name="conflict_local_file">Ficheiro local</string>
<string name="conflict_message_description">Se selecciona ambas versións, o ficheiro local terá un número engadido ao nome.</string> <string name="conflict_message_description">Se selecciona ambas versións, o ficheiro local terá un número engadido ao nome.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Kreiranje korisničkog računa neuspjelo</string> <string name="account_creation_failed">Kreiranje korisničkog računa neuspjelo</string>
<string name="account_icon">Ikona korisničkog računa</string> <string name="account_icon">Ikona korisničkog računa</string>
<string name="account_not_found">Korisnički račun nije pronađen!</string> <string name="account_not_found">Korisnički račun nije pronađen!</string>
<string name="action_clear_failed_uploads">Izbriši neuspješne otpreme</string>
<string name="action_edit">Uredi</string> <string name="action_edit">Uredi</string>
<string name="action_empty_notifications">Izbriši sve obavijesti</string> <string name="action_empty_notifications">Izbriši sve obavijesti</string>
<string name="action_empty_trashbin">Isprazni kantu za smeće</string> <string name="action_empty_trashbin">Isprazni kantu za smeće</string>
@ -145,7 +144,6 @@
<string name="confirmation_remove_folder_alert">Želite li zaista izbrisati %1$s i pripadajući sadržaj?</string> <string name="confirmation_remove_folder_alert">Želite li zaista izbrisati %1$s i pripadajući sadržaj?</string>
<string name="confirmation_remove_folders_alert">Želite li zaista izbrisati odabrane stavke i pripadajući sadržaj?</string> <string name="confirmation_remove_folders_alert">Želite li zaista izbrisati odabrane stavke i pripadajući sadržaj?</string>
<string name="confirmation_remove_local">Samo lokalno</string> <string name="confirmation_remove_local">Samo lokalno</string>
<string name="conflict_dialog_error">Pogreška pri stvaranju dijaloškog okvira o nepodudaranju!</string>
<string name="conflict_file_headline">Nepodudarna datoteka %1$s</string> <string name="conflict_file_headline">Nepodudarna datoteka %1$s</string>
<string name="conflict_local_file">Lokalna datoteka</string> <string name="conflict_local_file">Lokalna datoteka</string>
<string name="conflict_message_description">Ako odaberete obje inačice, lokalna će datoteka uz naziv imati i broj.</string> <string name="conflict_message_description">Ako odaberete obje inačice, lokalna će datoteka uz naziv imati i broj.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">A fiók létrehozása sikertelen</string> <string name="account_creation_failed">A fiók létrehozása sikertelen</string>
<string name="account_icon">Fiók ikon</string> <string name="account_icon">Fiók ikon</string>
<string name="account_not_found">A fiók nem található!</string> <string name="account_not_found">A fiók nem található!</string>
<string name="action_clear_failed_uploads">Sikertelen feltöltések eltávolítása</string>
<string name="action_edit">Szerkesztés</string> <string name="action_edit">Szerkesztés</string>
<string name="action_empty_notifications">Összes értesítés törlése</string> <string name="action_empty_notifications">Összes értesítés törlése</string>
<string name="action_empty_trashbin">Kuka ürítése</string> <string name="action_empty_trashbin">Kuka ürítése</string>
@ -155,7 +154,6 @@
<string name="confirmation_remove_folder_alert">Biztos, hogy törli ezt: %1$s és a tartalmát?</string> <string name="confirmation_remove_folder_alert">Biztos, hogy törli ezt: %1$s és a tartalmát?</string>
<string name="confirmation_remove_folders_alert">Biztos, hogy törli a kiválasztott elemeket és tartalmukat?</string> <string name="confirmation_remove_folders_alert">Biztos, hogy törli a kiválasztott elemeket és tartalmukat?</string>
<string name="confirmation_remove_local">Csak a helyi példány</string> <string name="confirmation_remove_local">Csak a helyi példány</string>
<string name="conflict_dialog_error">Hiba az ütközési párbeszédablak létrehozásakor!</string>
<string name="conflict_file_headline">Ütköző fájl: %1$s</string> <string name="conflict_file_headline">Ütköző fájl: %1$s</string>
<string name="conflict_local_file">Helyi fájl</string> <string name="conflict_local_file">Helyi fájl</string>
<string name="conflict_message_description">Amennyiben mindkét verziót kiválasztja, a helyi fájl nevéhez egy szám lesz hozzáfűzve.</string> <string name="conflict_message_description">Amennyiben mindkét verziót kiválasztja, a helyi fájl nevéhez egy szám lesz hozzáfűzve.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Pembuatan akun gagal</string> <string name="account_creation_failed">Pembuatan akun gagal</string>
<string name="account_icon">Ikon akun</string> <string name="account_icon">Ikon akun</string>
<string name="account_not_found">Akun tidak ditemukan!</string> <string name="account_not_found">Akun tidak ditemukan!</string>
<string name="action_clear_failed_uploads">Bersihkan unggahan gagal.</string>
<string name="action_edit">Sunting</string> <string name="action_edit">Sunting</string>
<string name="action_empty_notifications">Hapus semua notifikasi</string> <string name="action_empty_notifications">Hapus semua notifikasi</string>
<string name="action_empty_trashbin">Kosongkan tempat sampah</string> <string name="action_empty_trashbin">Kosongkan tempat sampah</string>
@ -147,7 +146,6 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
<string name="confirmation_remove_folder_alert">Apakah anda yakin ingin menghapus %1$s beserta isinya?</string> <string name="confirmation_remove_folder_alert">Apakah anda yakin ingin menghapus %1$s beserta isinya?</string>
<string name="confirmation_remove_folders_alert">Apa anda yakin ingin menghapus item yang terpilih beserta isinya?</string> <string name="confirmation_remove_folders_alert">Apa anda yakin ingin menghapus item yang terpilih beserta isinya?</string>
<string name="confirmation_remove_local">Lokal saja</string> <string name="confirmation_remove_local">Lokal saja</string>
<string name="conflict_dialog_error">Galat saat membuat dialog konflik!</string>
<string name="conflict_file_headline">File konflik %1$s</string> <string name="conflict_file_headline">File konflik %1$s</string>
<string name="conflict_local_file">File lokal</string> <string name="conflict_local_file">File lokal</string>
<string name="conflict_message_description">Jika Anda memilih kedua versi, nama dari berkas lokal akan ditambahi angka.</string> <string name="conflict_message_description">Jika Anda memilih kedua versi, nama dari berkas lokal akan ditambahi angka.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Gerð notandaaðgangs mistókst</string> <string name="account_creation_failed">Gerð notandaaðgangs mistókst</string>
<string name="account_icon">Táknmynd fyrir notandaaðgang</string> <string name="account_icon">Táknmynd fyrir notandaaðgang</string>
<string name="account_not_found">Notandaaðgangur fannst ekki!</string> <string name="account_not_found">Notandaaðgangur fannst ekki!</string>
<string name="action_clear_failed_uploads">Hreinsa lista yfir innsendingar sem mistókust</string>
<string name="action_edit">Breyta</string> <string name="action_edit">Breyta</string>
<string name="action_empty_notifications">Hreinsa allar tilkynningar</string> <string name="action_empty_notifications">Hreinsa allar tilkynningar</string>
<string name="action_empty_trashbin">Tæma ruslið</string> <string name="action_empty_trashbin">Tæma ruslið</string>
@ -150,7 +149,6 @@
<string name="confirmation_remove_folder_alert">Ertu viss um að þú viljir eyða %1$s og innihaldi þess?</string> <string name="confirmation_remove_folder_alert">Ertu viss um að þú viljir eyða %1$s og innihaldi þess?</string>
<string name="confirmation_remove_folders_alert">Ertu viss um að þú viljir eyða völdum atriðum og innihaldi þeirra?</string> <string name="confirmation_remove_folders_alert">Ertu viss um að þú viljir eyða völdum atriðum og innihaldi þeirra?</string>
<string name="confirmation_remove_local">Einungis staðvært</string> <string name="confirmation_remove_local">Einungis staðvært</string>
<string name="conflict_dialog_error">Villa við að búa til árekstraglugga!</string>
<string name="conflict_local_file">Skrá á tölvunni</string> <string name="conflict_local_file">Skrá á tölvunni</string>
<string name="conflict_message_description">Ef þú velur báðar útgáfur, þá mun verða bætt tölustaf aftan við heiti afrituðu skrárinnar.</string> <string name="conflict_message_description">Ef þú velur báðar útgáfur, þá mun verða bætt tölustaf aftan við heiti afrituðu skrárinnar.</string>
<string name="conflict_server_file">Skrá á netþjóni</string> <string name="conflict_server_file">Skrá á netþjóni</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Creazione dell\'account non riuscita</string> <string name="account_creation_failed">Creazione dell\'account non riuscita</string>
<string name="account_icon">Icona dell\'account</string> <string name="account_icon">Icona dell\'account</string>
<string name="account_not_found">Account non trovato</string> <string name="account_not_found">Account non trovato</string>
<string name="action_clear_failed_uploads">Cancella caricamenti non riusciti</string>
<string name="action_edit">Modifica</string> <string name="action_edit">Modifica</string>
<string name="action_empty_notifications">Cancella tutte le notifiche</string> <string name="action_empty_notifications">Cancella tutte le notifiche</string>
<string name="action_empty_trashbin">Svuota cestino</string> <string name="action_empty_trashbin">Svuota cestino</string>
@ -153,7 +152,6 @@
<string name="confirmation_remove_folder_alert">Vuoi davvero rimuovere %1$s e il relativo contenuto?</string> <string name="confirmation_remove_folder_alert">Vuoi davvero rimuovere %1$s e il relativo contenuto?</string>
<string name="confirmation_remove_folders_alert">Vuoi davvero eliminare gli elementi selezionati e il loro contenuto?</string> <string name="confirmation_remove_folders_alert">Vuoi davvero eliminare gli elementi selezionati e il loro contenuto?</string>
<string name="confirmation_remove_local">Solo localmente</string> <string name="confirmation_remove_local">Solo localmente</string>
<string name="conflict_dialog_error">Errore di creazione della finestra di conflitto!</string>
<string name="conflict_file_headline">File %1$s in conflitto</string> <string name="conflict_file_headline">File %1$s in conflitto</string>
<string name="conflict_local_file">File locale</string> <string name="conflict_local_file">File locale</string>
<string name="conflict_message_description">Se selezioni entrambe le versioni, il file locale ha un numero aggiunto al suo nome.</string> <string name="conflict_message_description">Se selezioni entrambe le versioni, il file locale ha un numero aggiunto al suo nome.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">יצירת החשבון נכשלה</string> <string name="account_creation_failed">יצירת החשבון נכשלה</string>
<string name="account_icon">סמל חשבון</string> <string name="account_icon">סמל חשבון</string>
<string name="account_not_found">החשבון לא נמצא!</string> <string name="account_not_found">החשבון לא נמצא!</string>
<string name="action_clear_failed_uploads">פינוי העלאות שנכשלו</string>
<string name="action_edit">עריכה</string> <string name="action_edit">עריכה</string>
<string name="action_empty_notifications">פינוי כל ההתראות</string> <string name="action_empty_notifications">פינוי כל ההתראות</string>
<string name="action_empty_trashbin">פינוי סל האשפה</string> <string name="action_empty_trashbin">פינוי סל האשפה</string>
@ -144,7 +143,6 @@
<string name="confirmation_remove_folder_alert">למחוק את %1$s על תוכנו?</string> <string name="confirmation_remove_folder_alert">למחוק את %1$s על תוכנו?</string>
<string name="confirmation_remove_folders_alert">למחוק את הפריטים הנבחרים ואת תוכנם?</string> <string name="confirmation_remove_folders_alert">למחוק את הפריטים הנבחרים ואת תוכנם?</string>
<string name="confirmation_remove_local">מקומי בלבד</string> <string name="confirmation_remove_local">מקומי בלבד</string>
<string name="conflict_dialog_error">שגיאה ביצירת תיבת דו־שיח סתירה!</string>
<string name="conflict_local_file">קובץ מקומי</string> <string name="conflict_local_file">קובץ מקומי</string>
<string name="conflict_message_description">בבחירה של שתי הגרסאות, יתווסף מספר בסוף שמו של הקובץ המקומי.</string> <string name="conflict_message_description">בבחירה של שתי הגרסאות, יתווסף מספר בסוף שמו של הקובץ המקומי.</string>
<string name="conflict_server_file">קובץ בשרת</string> <string name="conflict_server_file">קובץ בשרת</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">アカウントの作成に失敗しました</string> <string name="account_creation_failed">アカウントの作成に失敗しました</string>
<string name="account_icon">アカウントアイコン</string> <string name="account_icon">アカウントアイコン</string>
<string name="account_not_found">アカウントが見つかりません!</string> <string name="account_not_found">アカウントが見つかりません!</string>
<string name="action_clear_failed_uploads">失敗したアップロードのクリア</string>
<string name="action_edit">編集</string> <string name="action_edit">編集</string>
<string name="action_empty_notifications">全ての通知を削除</string> <string name="action_empty_notifications">全ての通知を削除</string>
<string name="action_empty_trashbin">ゴミ箱を空にする</string> <string name="action_empty_trashbin">ゴミ箱を空にする</string>
@ -155,7 +154,6 @@
<string name="confirmation_remove_folder_alert">本当に %1$s を中身も一緒に削除しますか?</string> <string name="confirmation_remove_folder_alert">本当に %1$s を中身も一緒に削除しますか?</string>
<string name="confirmation_remove_folders_alert">本当に選択したアイテムとその内容を削除しますか?</string> <string name="confirmation_remove_folders_alert">本当に選択したアイテムとその内容を削除しますか?</string>
<string name="confirmation_remove_local">ローカルのみ</string> <string name="confirmation_remove_local">ローカルのみ</string>
<string name="conflict_dialog_error">コンフリクトダイアログの作成に失敗しました</string>
<string name="conflict_file_headline">%1$sはすでに存在します</string> <string name="conflict_file_headline">%1$sはすでに存在します</string>
<string name="conflict_local_file">ローカルファイル</string> <string name="conflict_local_file">ローカルファイル</string>
<string name="conflict_message_description">両方のバージョンを選択した場合、ローカルファイルはファイル名に数字が追加されます。</string> <string name="conflict_message_description">両方のバージョンを選択した場合、ローカルファイルはファイル名に数字が追加されます。</string>

View file

@ -1,506 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="about_android">%1$s Android აპლიკაცია</string>
<string name="about_title">ჩვენს შესახებ</string>
<string name="about_version">ვერსია %1$s</string>
<string name="account_icon">ანგარიშის პიქტოგრამა</string>
<string name="account_not_found">ანგარიში ვერ იქნა ნაპოვნი!</string>
<string name="action_clear_failed_uploads">წარუმატებლად დასრულებული ატვირთების გასუფთავება</string>
<string name="action_edit">ცვლილება</string>
<string name="action_send_share">გაგზავნა/გაზიარება</string>
<string name="action_switch_grid_view">ბადისებური ხედი</string>
<string name="action_switch_list_view">ჩამონათვლისებური ხედი</string>
<string name="actionbar_mkdir">ახალი დირექტორია</string>
<string name="actionbar_open_with">გახსნა</string>
<string name="actionbar_search">ძიება</string>
<string name="actionbar_see_details">დეტალები</string>
<string name="actionbar_send_file">გაგზავნა</string>
<string name="actionbar_settings">პარამეტრები</string>
<string name="actionbar_sort">განლაგება</string>
<string name="active_user">აქტიური მომხმარებელი</string>
<string name="activities_no_results_headline">აქტოვობა ჯერ არაა</string>
<string name="activity_chooser_send_file_title">გაგზავნა</string>
<string name="activity_chooser_title">გააგზავნეთ ბმული…</string>
<string name="activity_icon">აქტივობა</string>
<string name="allow_resharing">ხელახალი გაზიარების დაშვება</string>
<string name="assistant_screen_all_task_type">ყველა</string>
<string name="auth_account_does_not_exist">ანგარიში ამ მოწყობილობაზე ჯერ არაა დამატებული</string>
<string name="auth_account_not_new">მოწყობილობაზე ანგარიში ამ მომხმარებლით და სერვერით უკვე არსებობს</string>
<string name="auth_account_not_the_same">შეყვანილი მომხმარებელი არ ემთხვევა ამ ანგარიშის მომხმარებელს</string>
<string name="auth_bad_oc_version_title">სერვერის ამოუცნობი ვერსია</string>
<string name="auth_connection_established">კავშირი დამყარდა</string>
<string name="auth_host_url">სერვერის მისამართი https://...</string>
<string name="auth_incorrect_address_title">სერვერისთვის არასწორი მისამსამართის ფორმატი</string>
<string name="auth_incorrect_path_title">სერვერი ვერ მოიძებნა</string>
<string name="auth_no_net_conn_title">ქსელთან კავშირი არ არის</string>
<string name="auth_nossl_plain_ok_title">დაცული კავშირი არაა ხელმისაწვდომი.</string>
<string name="auth_not_configured_title">არასწორი სერვერის კონფიგურაცია</string>
<string name="auth_oauth_error">წარუმატებელი ავტორიზაცია</string>
<string name="auth_oauth_error_access_denied">წვდომა ავტორიზაციის სერვერის მიერ აიკრძალა</string>
<string name="auth_redirect_non_secure_connection_title">დაცული კავშირი გადამისამართდა დაუცველი მარშრუტით.</string>
<string name="auth_secure_connection">დაცული კავშირი დამყარდა</string>
<string name="auth_ssl_general_error_title">SSL ინიციალიზაცია ვერ მოხერხდა</string>
<string name="auth_ssl_unverified_server_title">SSL სერვერის იდენტობა ვერ დამოწმდა</string>
<string name="auth_testing_connection">კავშირის შემოწმება</string>
<string name="auth_timeout_title">სერვერმა პასუხი დააგვიანია</string>
<string name="auth_unauthorized">არასწორი მომხმარებელი ან პაროლი</string>
<string name="auth_unknown_error_title">წარმოიშვა უცნობი შეცდომა!</string>
<string name="auth_unknown_host_title">ჰოსტი ვერ მოიძებნა</string>
<string name="auth_unsupported_multiaccount">%1$s არ უჭერს მხარს მრავალი ანგარიშის არსებობას</string>
<string name="auth_wrong_connection_title">კავშირი ვერ დამყარდა</string>
<string name="auto_upload_on_wifi">ატვირთვა მხოლოდ შეუზღუდავ Wi-Fi-ზე</string>
<string name="auto_upload_path">/ავტომატური_ატვირთვა</string>
<string name="autoupload_create_new_custom_folder">შექმენით ახალი სპეციფიური დირექტორია</string>
<string name="autoupload_custom_folder">დააყენეთ სპეციფიური დირექტორია</string>
<string name="avatar">ავატარი</string>
<string name="battery_optimization_close">დახურვა</string>
<string name="battery_optimization_disable">გამორთვა</string>
<string name="calendar">კალენდარი</string>
<string name="certificate_load_problem">სერტიპიკატის ჩატვირთვასთან პრობლემაა.</string>
<string name="checkbox">ჩექბოქსი</string>
<string name="clipboard_label">ტექსტი %1$s-იდან დაკოპირდა</string>
<string name="clipboard_no_text_to_copy">ბუფერში გადასატანად ტექსტი მიღებული არაა</string>
<string name="clipboard_unexpected_error">ბუფერში გადატანისას წარმოშვა მოულოდნელი შეცდომა</string>
<string name="common_back">უკან</string>
<string name="common_cancel">გაუქმება</string>
<string name="common_cancel_sync">სინქრონიზაციის შეჩერება</string>
<string name="common_choose_account">აირჩიეთ ანგარიში</string>
<string name="common_confirm">დადასტურება</string>
<string name="common_copy">კოპირება</string>
<string name="common_delete">გაუქმება</string>
<string name="common_error">შეცდომა</string>
<string name="common_error_out_memory">არასაკმარისი მეხსიერება</string>
<string name="common_error_unknown">უცნობი შეცდომა</string>
<string name="common_loading">იტვირთება…</string>
<string name="common_next">შემდეგი</string>
<string name="common_no">არა</string>
<string name="common_ok">კარგი</string>
<string name="common_pending">მოლოდინშია</string>
<string name="common_remove">გაუქმება</string>
<string name="common_rename">გადარქმევა</string>
<string name="common_save">შენახვა</string>
<string name="common_send">გაგზავნა</string>
<string name="common_share">გაზიარება</string>
<string name="common_skip">გამოტოვება</string>
<string name="common_yes">კი</string>
<string name="community_beta_headline">დევ. ვერსიის შემოწმება</string>
<string name="community_beta_text">იმყოფება სისხლდენის ზღვარზე და მოიცავს ყველა დამდეგ ფუნქციას. შეიძლება გამოჩნდეს შეცდომები, ასეთი შემთხვევისას გთხოვთ გვამცნობოთ რეპორტით.</string>
<string name="community_contribute_forum_forum">ფურუმი</string>
<string name="community_contribute_forum_text">დაეხმარეთ სხვებს</string>
<string name="community_contribute_headline">აქტიურად შეიტანეთ წვლილი</string>
<string name="community_contribute_translate_text">აპლიკაცია</string>
<string name="community_contribute_translate_translate">გადათარგმნეთ</string>
<string name="community_dev_direct_download">დეველოპმენტ რელიზის პირდაპირი ჩამოტვირთვა</string>
<string name="community_dev_fdroid">მიიღეთ დეველოპმენტ რელიზი F-Droid აპლიკაციიდან</string>
<string name="community_rc_fdroid">მიიღეთ რელიზ კანდიდატი F-Droid აპლიკაციიდან</string>
<string name="community_rc_play_store">მიიღეთ რელიზ კანდიდატი Google Play-დან</string>
<string name="community_release_candidate_headline">რელიზის კანდიდატი</string>
<string name="community_release_candidate_text">ეს რელიზის კანდიდატი (რკ) დამდეგი რელიზის კადრია და მოსალოდნელია მისი სტაბილურობა. ამის დამოწმებაში დაგვეხმარება ინდივიდუალური მოწყობილობის შემოწმება. შემოწმებისთვის დარეგისტრირდით Play-ზე ან გადახედეთ \"ვერსიის\" სექციას F-Droid-ში.</string>
<string name="community_testing_bug_text">იპოვეთ შეცდომა? უცნაურობა?</string>
<string name="community_testing_headline">დაგვეხმარეთ შემოწმებით</string>
<string name="community_testing_report_text">დაამატეთ მოხსენიება GitHub-ზე</string>
<string name="confirmation_remove_file_alert">ნამდვილად გსურთ %1$s-ის გაუქმება?</string>
<string name="confirmation_remove_files_alert">დარწმუნებული ხართ, რომ გსურთ არჩეული ჩანაწერების გაუქმება?</string>
<string name="confirmation_remove_folder_alert">ნამდვილად გსურთ %1$s-ის და შემცველობის გაუქმება?</string>
<string name="confirmation_remove_folders_alert">დარწმუნებული ხართ, რომ გსურთ არჩეული ჩანაწერებისა და მათი შემცველობის გაუქმება?</string>
<string name="confirmation_remove_local">მხოლოდ ლოკალური</string>
<string name="contactlist_item_icon">მომხმარებლის პიქტოგრამა კონტაქტების სიისთვის</string>
<string name="contactlist_no_permission">უფლებები არაა მოცემული, არაფერი არ იქნა იმპორტირებული.</string>
<string name="contacts">კონტაქტები</string>
<string name="contacts_backup_button">ახალი ბექაფი</string>
<string name="contacts_preferences_backup_scheduled">ბექაფი დაინიშნა და მალე დაიწყება</string>
<string name="contacts_preferences_import_scheduled">იმპორტი დაინიშნა და მალე დაიწყება</string>
<string name="contacts_preferences_no_file_found">ფაილი ვერ იქნა ნაპოვნი</string>
<string name="contacts_preferences_something_strange_happened">თქვენი ბოლო ბექაფი ვერ იქნა ნაპოვნი!</string>
<string name="copied_to_clipboard">კოპირებულია კლიპბორდში</string>
<string name="copy_file_error">ამ ფაილისა თუ დირექტორიის კოპირებისას წარმოიშვა შეცდომა</string>
<string name="copy_file_invalid_into_descendent">დირექტორიის კოპირება მასში არსებულ დირექტორიაში შეუძლებელია</string>
<string name="copy_file_invalid_overwrite">ფაილი დანიშნულ დირექტორიაში უკვე არსებობს</string>
<string name="copy_link">ბმულის კოპირება</string>
<string name="copy_move_to_encrypted_folder_not_supported">ამჟამად კოპირება/გადატანა დაშიფრულ დირექტორიაში არაა მხარდაჭერილი.</string>
<string name="create">შექმნა</string>
<string name="create_dir_fail_msg">დირექტორია ვერ შეიქმნა</string>
<string name="delete_account">ანგარიშის გაუქმება</string>
<string name="deselect_all">ყველას წაშლა</string>
<string name="dev_version_new_version_available">ხელმისაწვდომია ახალი ვერსია</string>
<string name="dev_version_no_new_version_available">ახალი ვერსია არაა ხელმისაწვდომი.</string>
<string name="dialog_close">დახურვა</string>
<string name="digest_algorithm_not_available">თქვენს ტელეფონს ამ ალგორითმის დაიჯესტის მხარდაჭერა არ აქვს. </string>
<string name="disable_new_media_folder_detection_notifications">გამორთვა</string>
<string name="dismiss">დათხოვნა</string>
<string name="done">დასრულებულია</string>
<string name="downloader_download_failed_content">ვერ ჩამოიტვირთა %1$s</string>
<string name="downloader_download_failed_credentials_error">ჩამოტვირთვა ვერ მოხერხდა, ახლიდან გაიარეთ ავტორიზაცია</string>
<string name="downloader_download_failed_ticker">ჩამოტვირთვა ვერ განხორციელდა</string>
<string name="downloader_download_file_not_found">ფაილი სერვერზე ხელმისაწვდომი აღარაა</string>
<string name="downloader_download_in_progress_content">%1$d%% ჩამოტვირთვა %2$s</string>
<string name="downloader_download_succeeded_content">%1$s ჩამოტვირთლია</string>
<string name="downloader_download_succeeded_ticker">ჩამოტვირთულია</string>
<string name="downloader_not_downloaded_yet">ჯერ ვერ ჩამოიტვირთა</string>
<string name="drawer_header_background">მხაზველი დასათაურების ფონური სურათი</string>
<string name="drawer_item_activities">აქტივობები</string>
<string name="drawer_item_all_files">ყველა ფაილი</string>
<string name="drawer_item_favorites">რჩეულები</string>
<string name="drawer_item_home">სახლი</string>
<string name="drawer_item_notifications">შეტყობინებები</string>
<string name="drawer_item_on_device">მოწყობილობაზე</string>
<string name="drawer_item_recently_modified">ახლად შეცვლილი</string>
<string name="drawer_item_shared">გაზიარებული</string>
<string name="drawer_item_trashbin">გაუქმებული ფაილები</string>
<string name="drawer_item_uploads_list">ატვირთვები</string>
<string name="drawer_logout">გასვლა</string>
<string name="drawer_quota">გამოყენებულია %1$s სულ %2$s-იდან </string>
<string name="drawer_synced_folders">ავტო-ატვირთვა</string>
<string name="ecosystem_apps_display_more">უფრო მეტი</string>
<string name="ecosystem_apps_display_notes">ჩანაწერები</string>
<string name="ecosystem_apps_display_talk">საუბარი</string>
<string name="encrypted">დააყენეთ როგორც დაშიფრული</string>
<string name="end_to_end_encryption_confirm_button">შიფრაციის დაყენება</string>
<string name="end_to_end_encryption_dialog_close">დახურვა</string>
<string name="end_to_end_encryption_enter_password">პირადი გასაღების დეშიფრაციისთვის გთხოვთ შეიყვანოთ პაროლი.</string>
<string name="end_to_end_encryption_folder_not_empty">ეს დირექტორია არაა ცარიელი</string>
<string name="end_to_end_encryption_keywords_description">12 სიტყვა ერთად წარმოქმნის ძალიან ძლიერ პაროლს, იძლევა თქვენი დაშიფრული ფაილების ჩვენებისა და მოხმარების უფლებას. გთხოვთ ჩაიწეროთ და შეინახოთ დაცულ ადგილას.</string>
<string name="end_to_end_encryption_passphrase_title">შენიშნეთ თქვენი 12 სიტყვიანი შიფრაციის პაროლი</string>
<string name="end_to_end_encryption_storing_keys">გასაღებების შენახვა</string>
<string name="end_to_end_encryption_title">შიფრაციის დაყენება</string>
<string name="end_to_end_encryption_unsuccessful">გასაღებების შენახვა ვერ მოხერხდა, გთხოვთ სცადოთ ახლიდან.</string>
<string name="end_to_end_encryption_wrong_password">შეცდომა დეშიფრაციისას. არასწორი პაროლი?</string>
<string name="error__upload__local_file_not_copied">%1$s ვერ კოპირდება %2$s ლოკალურ დირექტორიაში</string>
<string name="error_cant_bind_to_operations_service">კრიტიკული შეცდომა: ოპერაციების განხორციელება შეუძლებელია</string>
<string name="etm_accounts">ანგარიშები</string>
<string name="etm_background_job_created">შექმნილია</string>
<string name="etm_background_job_user">მომხმარებელი</string>
<string name="etm_background_jobs">ფონური საქმეები</string>
<string name="etm_transfer_type_download">ჩამოტვირთვა</string>
<string name="etm_transfer_type_upload">ატვირთვა</string>
<string name="favorite">რჩეულებში დამატება</string>
<string name="favorite_icon">რჩეული</string>
<string name="file_delete">წაშლა</string>
<string name="file_icon">ფაილი</string>
<string name="file_list_empty">ატვირთეთ რამე ან გაუწიეთ თქვნს მოწყობილობას სინქრონიზაცია.</string>
<string name="file_list_empty_favorite_headline">რჩეულებში ჯერ არაფერი დამატებულია</string>
<string name="file_list_empty_headline">აქ ფაილები არაა</string>
<string name="file_list_empty_headline_search">ამ დირექტორიაში შედეგები არაა</string>
<string name="file_list_empty_headline_server_search">შედეგები არაა</string>
<string name="file_list_empty_moving">აქ არაფერია. შეგიძლიათ დაამატოთ დირექტორია.</string>
<string name="file_list_empty_recently_modified">გასული 7 დღის განმავლობაში შეცვლილი ფაილ(ებ)ი ვერ იქნა ნაპოვნი</string>
<string name="file_list_empty_search">იქნებ სხვა დირექტორიაშია?</string>
<string name="file_list_empty_shared_headline">ჯერ არაფერი გაზიარებულა</string>
<string name="file_list_folder">დირექტორია</string>
<string name="file_list_loading">იტვირთება…</string>
<string name="file_list_no_app_for_file_type">ამ ფაილთან სამუშაოდ არც ერთი აპლიკაცია არაა დაყანებული.</string>
<string name="file_list_seconds_ago">წამის წინ</string>
<string name="file_migration_directory_already_exists">მონაცემების დირექტორია უკვე არსებობს. აირჩიეთ ერთ-ერთი შემდეგიდან:</string>
<string name="file_migration_failed_dir_already_exists">Nextcloud დირექტორია უკვე არსებობს</string>
<string name="file_migration_failed_not_enough_space">საჭიროა მეტი სივრცე</string>
<string name="file_migration_failed_not_readable">წყარო-ფაილის წაკითხვა ვერ მოხერხდა</string>
<string name="file_migration_failed_not_writable">სამიზნე ფაილში ჩაწერა ვერ მოხერხდა</string>
<string name="file_migration_failed_while_coping">მიგრაციისას წარმოიქმნა შეცდომა</string>
<string name="file_migration_failed_while_updating_index">ინდექსის განახლება ვერ მოხერხდა</string>
<string name="file_migration_ok_finished">დასრულებულია</string>
<string name="file_migration_override_data_folder">ჩანაცვლება</string>
<string name="file_migration_source_not_readable_title">წყარო-დირექტორია ვერ იკითხება!</string>
<string name="file_migration_use_data_folder">მოხმარება</string>
<string name="file_not_found">ფაილი ვერ იქნა ნაპოვნი</string>
<string name="file_not_synced">ფაილის სინქ ვერ მოხერხდა. ნაჩვენებია ბოლო ხელმისაწვდომი ვარიანტი.</string>
<string name="file_rename">სახელის შეცვლა</string>
<string name="filedetails_details">დეტალები</string>
<string name="filedetails_download">ჩამოტვირთვა</string>
<string name="filedetails_export">ექსპორტი</string>
<string name="filedetails_renamed_in_upload_msg">ატვირთვისას ფაილს სახელი შეეცვალა %1$s-ზე</string>
<string name="filedetails_sync_file">სინქ</string>
<string name="filedisplay_no_file_selected">ფაილი არაა არჩეული</string>
<string name="filename_empty">ფაილის სახელი ვერ იქნება ცარიელი</string>
<string name="filename_forbidden_characters">აკრძალული ნიშნები: / \\ &lt; &gt; : \" | ? *</string>
<string name="filename_forbidden_charaters_from_server">ფაილის სახელი შეიცავს მინ. 1 არასწორ ნიშანს</string>
<string name="filename_hint">ფაილის სახელი</string>
<string name="folder_confirm_create">შექმნა</string>
<string name="folder_list_empty_headline">აქ დირექტორიები არაა</string>
<string name="folder_picker_choose_button_text">აირჩიეთ</string>
<string name="folder_picker_move_button_text">გადატანა</string>
<string name="forbidden_permissions">თქვენ არ გაქვთ უფლება, %s</string>
<string name="forbidden_permissions_copy">რომ დააკოპიროთ ეს ფაილი</string>
<string name="forbidden_permissions_create">შექმნათ ეს ფაილი</string>
<string name="forbidden_permissions_delete">გააუქმოთ ეს ფაილი</string>
<string name="forbidden_permissions_move">რომ გადაიტანოთ ეს ფაილი</string>
<string name="forbidden_permissions_rename">შეუცვალოთ ამ ფაილს სახელი</string>
<string name="foreground_service_upload">ფაილების ატვირთვა...</string>
<string name="foreign_files_fail">გარკვეული ფაილების გადატანა ვერ მოხერხდა</string>
<string name="foreign_files_local_text">ლოკალური: %1$s</string>
<string name="foreign_files_move">ყველას გადატანა</string>
<string name="foreign_files_remote_text">დისტანციური: %1$s</string>
<string name="foreign_files_success">ყველა ფაილი გადატანილია</string>
<string name="forward">წინ</string>
<string name="fourHours">4 საათი</string>
<string name="hint_name">სახელი</string>
<string name="hint_password">პაროლი</string>
<string name="instant_upload_on_charging">ატვირთვა მხოლოდ დატენვისას</string>
<string name="instant_upload_path">/მისიერი_ატვირთვა</string>
<string name="invisible">უჩინარი</string>
<string name="link">ბმული</string>
<string name="link_share_allow_upload_and_editing">ატვირთვისა და ცვლილების უფლებების მინიჭება</string>
<string name="link_share_file_drop">ფაილის ჩაგდება (მხოლოდ ატვირთვა)</string>
<string name="list_layout">ჩამოწერილი მაკეტი</string>
<string name="local_file_list_empty">ამ დირექტორიაში ფაილები არაა.</string>
<string name="local_file_not_found_message">ლოკალურ ფაილ-სისტემაში ფაილი ვერ მოიძებნა</string>
<string name="local_folder_list_empty">მომდევნო დირექტორიები არაა.</string>
<string name="log_send_mail_subject">%1$s Android აპლიკაციის ლოგები.</string>
<string name="login">ლოგინი</string>
<string name="logs_menu_refresh">განახლება</string>
<string name="logs_status_loading">იტვირთება…</string>
<string name="logs_title">ლოგები</string>
<string name="manage_space_clear_data">მონაცემების გასუფთავება</string>
<string name="manage_space_description"> %1$s-ის მონაცემებიდან პარამეტრები, მონაცემთა ბაზა და სერტიფიკატები სამუდამოდ წაიშლება.\n\nგადმოწერილი ფაილები დარჩება ხელუხლებელი.\n\nეს პროცესი გასტანს გარკვეულ დროს.</string>
<string name="manage_space_title">მოცულობის მენეჯმენტი</string>
<string name="media_err_io">მედია ფაილის წაკითხვა ვერ მოხერხდა</string>
<string name="media_err_malformed">მედია ფაილს გააჩნია არასწორი კოდირება</string>
<string name="media_err_timeout">ფაილის დაკვრის მცდელობის დრო ამოიწურა</string>
<string name="media_err_unknown">ჩაშენებული მედია დამკვრელი ვერ უკრავს მედია ფაილს</string>
<string name="media_err_unsupported">მედია კოდეკი მხარდაუჭერელია</string>
<string name="media_forward_description">სწრაფი გადახვევის ღილაკი</string>
<string name="media_notif_ticker">%1$s მუსიკის დამკვრელი</string>
<string name="media_play_pause_description">დაკვრის ან პაუზის ღილაკი</string>
<string name="media_rewind_description">გადახვევის ღილაკი</string>
<string name="media_state_playing">%1$s (იკვრება)</string>
<string name="menu_item_sort_by_date_newest_first">ჯერ ახალი</string>
<string name="menu_item_sort_by_date_oldest_first">ჯერ ძველი</string>
<string name="menu_item_sort_by_name_a_z">ა - ჰ</string>
<string name="menu_item_sort_by_name_z_a">ჰ - ა</string>
<string name="menu_item_sort_by_size_biggest_first">ჯერ დიდი</string>
<string name="menu_item_sort_by_size_smallest_first">ჯერ პატარა</string>
<string name="more">მეტი</string>
<string name="move_file_error">ამ ფაილისა თუ დირექტორიის გადატანისას წარმოიშვა შეცდომა</string>
<string name="move_file_invalid_into_descendent">დირექტორიის გადატანა მასში არსებულ დირექტორიაში შეუძლებელია</string>
<string name="move_file_invalid_overwrite">ფაილი დანიშნულ დირექტორიაში უკვე არსებობს</string>
<string name="network_error_socket_exception">სერვერთან დაკავშირებისას წარმოიქმნა შეცდომა</string>
<string name="new_media_folder_photos">ფოტო</string>
<string name="notification_channel_download_description">აჩვენებს გადმოწერის პროგრესს</string>
<string name="notification_channel_download_name_short">ჩამოტვირთვები</string>
<string name="notification_channel_file_sync_description">აჩვენებს ფაილების სინქ. პროგრესს და შედეგებს</string>
<string name="notification_channel_file_sync_name">ფაილების სინქ.</string>
<string name="notification_channel_media_description">მუსიკის დამკვრელის პროგრესი</string>
<string name="notification_channel_media_name">მედია დამკვრელი</string>
<string name="notification_channel_upload_description">აჩვენებს ატვირთვის პროგრესს</string>
<string name="notification_channel_upload_name_short">ატვირთვები</string>
<string name="notifications_no_results_headline">შეტყობინებები არაა</string>
<string name="notifications_no_results_message">გთხოვთ დაბრუნდეთ მოგვინაებით.</string>
<string name="oneHour">1 საათი</string>
<string name="pass_code_configure_your_pass_code">შეიყვანეთ თქვენი პასკოდი</string>
<string name="pass_code_configure_your_pass_code_explanation">პასკოდი მოთხოვნილ იქნება აპლიკაციის ყოველი გაშვებისას</string>
<string name="pass_code_enter_pass_code">გთხოვთ შეიყვანოთ თქვენი პასკოდი</string>
<string name="pass_code_mismatch">პასკოდები ერთმანეთს არ ემთხვევა</string>
<string name="pass_code_reenter_your_pass_code">გთხოვთ თქვენი პასკოდი შეიყვანოთ ახლიდან</string>
<string name="pass_code_remove_your_pass_code">თქვენი პასკოდის გაუქმება</string>
<string name="pass_code_removed">პასკოდი გაუქმდა</string>
<string name="pass_code_stored">პასკოდი შენახულია</string>
<string name="pass_code_wrong">არასწორი პასკოდი</string>
<string name="permission_storage_access">ფაილების ატვირთვისა და გადმოწერისათვის საჭიროა დამატებითი უფლებები.</string>
<string name="picture_set_as_no_app">სურათის დასაყენებლად ვერც ერთი აპლიკაცია ვერ იქნა ნაპოვნი</string>
<string name="placeholder_fileSize">389 კბ</string>
<string name="placeholder_filename">ადგილი.txt</string>
<string name="placeholder_media_time">12:23:45</string>
<string name="placeholder_sentence">ეს არის ადგილი</string>
<string name="placeholder_timestamp">18/05/2012 12:23</string>
<string name="pref_behaviour_entries_delete_file">გაუქმებულია</string>
<string name="pref_behaviour_entries_keep_file">დარჩა ორიგინალ დირექტორიაში</string>
<string name="pref_behaviour_entries_move">გადატანილია აპლიკაციის დირექტორიაში</string>
<string name="prefs_add_account">ანგარიშის დამატება</string>
<string name="prefs_calendar_contacts_no_store_error">არც Google Play-ა დაყენებული, არც F-Droid-ი</string>
<string name="prefs_category_about">ჩვენს შესახებ</string>
<string name="prefs_category_details">დეტალები</string>
<string name="prefs_category_dev">დევ.</string>
<string name="prefs_category_general">ზოგადი</string>
<string name="prefs_category_more">მეტი</string>
<string name="prefs_daily_contact_backup_summary">კონტაქტების ყოველდღიური ბექაფი</string>
<string name="prefs_gpl_v2">GNU ზოგადი ღია ლიცენზია, ვერსია 2</string>
<string name="prefs_help">დახმარება</string>
<string name="prefs_imprint">ბეჭედი</string>
<string name="prefs_instant_upload_path_use_subfolders_title">ქვე-დირექტორიების მოხმარება</string>
<string name="prefs_license">ლიცენზია</string>
<string name="prefs_lock_none">არც ერთი</string>
<string name="prefs_manage_accounts">ანგარიშების მართვა</string>
<string name="prefs_show_hidden_files">დამალული ფაილების ჩვენება</string>
<string name="prefs_sourcecode">მიიღეთ კოდი</string>
<string name="prefs_synced_folders_local_path_title">ლოკალური დირექტორია</string>
<string name="prefs_synced_folders_remote_path_title">დისტანციური დირექტორია</string>
<string name="prefs_theme_title">ვიზუალური თემა</string>
<string name="prefs_value_theme_dark">მუქი</string>
<string name="prefs_value_theme_light">ღია</string>
<string name="preview_image_description">სურათის წინასწარი ჩვენება</string>
<string name="preview_image_error_no_local_file">წინასწარი ჩვენებისთვის ლოკალური ფაილი არაა</string>
<string name="preview_image_error_unknown_format">სურათის ჩვენება შეუძლებელია</string>
<string name="preview_sorry">ბოდიში</string>
<string name="privacy">კონფიდენციალურობა</string>
<string name="push_notifications_not_implemented">Google Play სერვისების მესაკუთრეობრივი დამოკიდებულებების გამო, ფუშ შეტყობინებები გათიშულია.</string>
<string name="push_notifications_old_login">ვადაგასული აუტენტიფიკაციის გამო ფუშ შეტყობინებები არაა. გთხოვთ გაითვალისწინოთ თქვენი ანგარიშის თავიდან დამატება.</string>
<string name="push_notifications_temp_error">ფუშ შეტყობინებები ამჟამად ხელმიუწვდომელია.</string>
<string name="recommend_subject">სცდეთ %1$s თქვენს მოწყობილობაზე!</string>
<string name="recommend_text">გიწვევთ გამოიყენოთ %1$s თქვენს მოწყობილობაზე.\nჩამოტვირთეთ აქედან: %2$s</string>
<string name="recommend_urls">%1$s ან %2$s</string>
<string name="reload">გადატვირთვა</string>
<string name="remove_fail_msg">გაუქმება ვერ მოხერხდა</string>
<string name="remove_push_notification">გაუქმება</string>
<string name="remove_success_msg">გაუქმდა</string>
<string name="rename_dialog_title">შეიყვანეთ ახალი სახელი</string>
<string name="rename_local_fail_msg">ლოკალური ასლის სახელის გადარქმევა ვერ მოხერხდა, სცადეთ სხვა სახელი</string>
<string name="rename_server_fail_msg">გადარქმევა შეუძლებელია, სახელი უკვე დაკავებულია</string>
<string name="reshare_not_allowed">ხელახალი გაზიარება არაა დაშვებული</string>
<string name="resharing_is_not_allowed">ხელახალი გაზიარება არაა ნებადართული</string>
<string name="resized_image_not_possible_download">ზომა-შეცვლილი სურათი არაა ხელმისაწვდომი. გადმოვწეროთ მთლიანი სურათი?</string>
<string name="select_all">ყველას მონიშვნა</string>
<string name="send">გაგზავნა</string>
<string name="set_as">დააყენეთ როგორც</string>
<string name="set_picture_as">გამოიყენეთ სურათი როგორც</string>
<string name="share">გაზიარება</string>
<string name="share_dialog_title">გაზიარება</string>
<string name="share_file">%1$s-ის გაზიარება</string>
<string name="share_group_clarification">%1$s (ჯგუფი)</string>
<string name="share_link">ბმულის გაზიარება</string>
<string name="share_link_empty_password">უნდა შეიყვანოთ პაროლი</string>
<string name="share_link_forbidden_permissions">გააზიაროთ ეს ფაილი</string>
<string name="share_link_password_title">შეიყვანეთ პაროლი</string>
<string name="share_no_expiration_date_label">მიუთითეთ ვადის გასვლის დრო</string>
<string name="share_no_password_title">პაროლის დაყენება</string>
<string name="share_permission_can_edit">შეუძლია შეცვალოს</string>
<string name="share_remote_clarification">%1$s (დისტანციური)</string>
<string name="share_settings">პარამეტრები</string>
<string name="share_via_link_section_title">ბმულის გაზიარება</string>
<string name="shared_icon_shared">გაზიარებული</string>
<string name="sort_by">დაასორტირე</string>
<string name="ssl_validator_btn_details_hide">დამალვა</string>
<string name="ssl_validator_btn_details_see">დეტალები</string>
<string name="ssl_validator_header">სერვერის იდენტურობა ვერ დამოწმდა</string>
<string name="ssl_validator_label_C">ქვეყანა:</string>
<string name="ssl_validator_label_CN">ზოგადი სახელი:</string>
<string name="ssl_validator_label_L">ადგილმდებარეობა:</string>
<string name="ssl_validator_label_O">ორგანიზაცია:</string>
<string name="ssl_validator_label_OU">ორგანიზაციის განყოფილება:</string>
<string name="ssl_validator_label_ST">შტატი:</string>
<string name="ssl_validator_label_certificate_fingerprint">თითის ანაბეჭდი:</string>
<string name="ssl_validator_label_issuer">გაცემულია მიერ:</string>
<string name="ssl_validator_label_signature">ხელმოწერა:</string>
<string name="ssl_validator_label_signature_algorithm">ალგორითმი:</string>
<string name="ssl_validator_label_subject">გაცემულია:</string>
<string name="ssl_validator_label_validity">მოქმედების ვადა:</string>
<string name="ssl_validator_label_validity_from">ვისგან:</string>
<string name="ssl_validator_label_validity_to">ვის:</string>
<string name="ssl_validator_no_info_about_error">- ამ შეცდომაზე ინფორმაცია არაა</string>
<string name="ssl_validator_not_saved">სერტიფიკატის შენახვა ვერ მოხერხდა</string>
<string name="ssl_validator_null_cert">სერტიფიკატის ჩვენება შეუძლებელია.</string>
<string name="ssl_validator_question">გსურთ მაინც ენდოთ ამ სერტიფიკატს?</string>
<string name="ssl_validator_reason_cert_expired">- სერვერის სერტიფიკატი ვადაგასულია</string>
<string name="ssl_validator_reason_cert_not_trusted">- სერვერის სერტიფიკატი არ არის სანდო</string>
<string name="ssl_validator_reason_cert_not_yet_valid">- სერვერის სერტიფიკატის თარიღები მომავალშია</string>
<string name="ssl_validator_reason_hostname_not_verified">- URL არ ემთხვევა სერტიფიკატში არსებულ ჰოსტნეიმს</string>
<string name="storage_description_default">საწყისი</string>
<string name="storage_downloads">ჩამოტვირთვები</string>
<string name="subject_shared_with_you">გაგიზიარდათ \"%1$s\"</string>
<string name="subject_user_shared_with_you">%1$s-სგან გაგიზიარდათ \"%2$s\"</string>
<string name="sync_conflicts_in_favourites_ticker">წარმოიშვა კონფლიქტი </string>
<string name="sync_current_folder_was_removed">დირექტორია %1$s აღარ არსებობს</string>
<string name="sync_fail_content">%1$s სინქ ვერ მოხერხდა</string>
<string name="sync_fail_content_unauthorized">%1$s რესურსის არასწორი პაროლი</string>
<string name="sync_fail_in_favourites_ticker">Kept-in-sync ფაილების შეცდომა</string>
<string name="sync_fail_ticker">სინქრონიზაცია დასრუდლა წარუმატებლად</string>
<string name="sync_fail_ticker_unauthorized">სინქ ვერ მოხერხდა, ახლიდან გაიარეთ ავტორიზაცია</string>
<string name="sync_file_nothing_to_do_msg">ფაილების შემცველობა სინქრონიზირებულია</string>
<string name="sync_foreign_files_forgotten_explanation">როდესაც ერთი ფაილი სინქრონიზირებულია რამოდენიმე ანგარიშთან, 1.3.16 ვერსიაში მონაცემების დაკარგვისგან თავის ასარიდებლად, ამ მოწყობილობით ატვირთული ფაილ(ებ)ი კოპირდება %1$s დირექტორიაში.\n\nამ ცვლილების გამო, აპლიკაციის ძველი ვერსიით ატვირთული ყველა ფაილი დაკოპირდა %2$s დირექტორიაში. თუმცა, შეცდომის გამო სინქრონიზაციისას მოხდა ამ ოპერაციის შეჩერება. შეგიძლიათ ფაილ(ებ)ი დატოვოთ ისე როგორც არის და წაშალოთ ბმული %3$s-სთან, ან გადაიტანოთ ფაილ(ებ)ი %1$s დირექტორიაში და შეინარჩუნოთ ბმული %4$s-ისთვის.\n\nქვემოთ ჩამოწერილია ლოკალური და %5$s-ში არსებული დისტანციური ფაილ(ებ)ი.</string>
<string name="sync_foreign_files_forgotten_ticker">რამოდენიმე ლოკალური ფაილი გამორჩენილია</string>
<string name="sync_in_progress">ამოღებულია ფაილის უახლესი ვერსია.</string>
<string name="sync_status_button">სინქ. სტატუსის ღილაკი</string>
<string name="sync_string_files">ფაილები</string>
<string name="synced_folder_settings_button">პარამეტრების ღილაკი</string>
<string name="synced_folders_configure_folders">დირექტორიების კონფიგურაცია</string>
<string name="synced_folders_new_info">მყისიერი ატვირთვა სრულიად გამოსწორდა. ავტო-ატვირთვას რეკონფიგურაცია გაუწიეთ მთავარი მენიუდან.\n\nისიამოვნეთ ახალი და გაუმჯობესებული ავტო-ატვირთვით.</string>
<string name="synced_folders_preferences_folder_path">%1$s-ისთვის</string>
<string name="synced_folders_type">სახეობა</string>
<string name="tags">ტეგები</string>
<string name="test_server_button">სერვერთან კავშირის შემოწმება</string>
<string name="thirtyMinutes">30 წუთი</string>
<string name="thisWeek">ამ კვირაში</string>
<string name="thumbnail">მინიატურა</string>
<string name="today">დღეს</string>
<string name="trashbin_activity_title">გაუქმებული ფაილები</string>
<string name="trashbin_empty_headline">წაშლილი ფაილები ვერ მოიძებნა</string>
<string name="trashbin_file_remove">სამუდამოდ წაშლა</string>
<string name="unset_encrypted">შიფრაციის გაუქმება</string>
<string name="unshare_link_forbidden_permissions">შეწყვიტოთ ამ ფაილის გაზიარება</string>
<string name="untrusted_domain">წვდომა არასანდო დომენით. დამატებითი ინფორმაციისთვის გთხოვთ იხილოთ დოკუმენტაცია.</string>
<string name="update_link_forbidden_permissions">განაახლოთ ეს გაზიარება</string>
<string name="upload_action_failed_clear">წარუმატებლად დასრულებული ატვირთების გასუფთავება</string>
<string name="upload_action_failed_retry">წარუმატებლად დასრულებული ატვირთების ხელახლა გაშვება</string>
<string name="upload_file_dialog_filename">ფაილის სახელი</string>
<string name="upload_file_dialog_filetype">ფაილის სახეობა</string>
<string name="upload_file_dialog_filetype_googlemap_shortcut">Google Maps იარლიყის ფაილი(%s)</string>
<string name="upload_file_dialog_filetype_internet_shortcut">ინტერნეტ იარლიყის ფაილი(%s)</string>
<string name="upload_file_dialog_filetype_snippet_text">ტექსტ ფაილის ჩამონაჭერი(.txt)</string>
<string name="upload_file_dialog_title">ატვირთვისთვის შეიყვანეთ ფაილის სახელი და სახეობა</string>
<string name="upload_files">ფაილების ატვირთვა</string>
<string name="upload_item_action_button">ელემენტის ატვირთვის ქმედების ღილაკი</string>
<string name="upload_list_delete">წაშლა</string>
<string name="upload_list_empty_headline">არც ერთი ატვირთვა არაა ხელმისაწვდომი.</string>
<string name="upload_list_empty_text_auto_upload">ატვირთეთ რაიმე ან გაააქტიურეთ ავტო-ატვირთვა.</string>
<string name="upload_query_move_foreign_files">არასაკმარისი ადგილი აფერხებს არჩეული ფაილების კოპირებას %1$s დირექტორიაში. გსურთ სანაცვლოდ მათი გადატანა?</string>
<string name="upload_unknown_error">უცნობი შეცდომა</string>
<string name="uploader_btn_alternative_text">აირჩიეთ</string>
<string name="uploader_btn_upload_text">ატვირთვა</string>
<string name="uploader_error_message_no_file_to_upload">მიღებული მონაცემები არ მოიცავდნენ სწორ ფაილს.</string>
<string name="uploader_error_message_read_permission_not_granted">%1$s მომხმარებელს არ აქვს უფლება წაიკითხოს ფაილი.</string>
<string name="uploader_error_message_source_file_not_copied">ფაილის ასლი დროებით დირექტორიაში ვერ შეიქმნა. სცადეთ მისი ახლიდან გაგზავნა.</string>
<string name="uploader_error_message_source_file_not_found">ატვირთვისთვის არჩეული ფაილი ვერ იქნა ნაპოვნი. გთხოვთ დაამოწმოთ ფაილის არსებობა.</string>
<string name="uploader_error_title_no_file_to_upload">ფაილი ატვირთვისთვის არაა</string>
<string name="uploader_info_dirname">დირექტორიის სახელი</string>
<string name="uploader_top_message">აირჩიეთ ატვირთვის დირექტორია</string>
<string name="uploader_upload_failed_content_single">%1$s ვერ აიტვირთა</string>
<string name="uploader_upload_failed_credentials_error">ატვირთვა ვერ მოხერხდა, ახლიდან გაიარეთ ავტორიზაცია</string>
<string name="uploader_upload_failed_ticker">ატვირთვა ვერ განხორციელდა</string>
<string name="uploader_upload_files_behaviour">ატვირთვის ოპციონი:</string>
<string name="uploader_upload_files_behaviour_only_upload">ფაილის საწყის დირექტორიაში დატოვება</string>
<string name="uploader_upload_files_behaviour_upload_and_delete_from_source">ფაილის საწყისი დირექტორიიდან გაუქმება</string>
<string name="uploader_upload_forbidden_permissions">ატვირთოთ ამ დირექტორიაში</string>
<string name="uploader_upload_in_progress_content">%1$d%% ატვირთვა %2$s</string>
<string name="uploader_upload_in_progress_ticker">იტვირთება...</string>
<string name="uploader_upload_succeeded_content_single">ატვირთულია %1$s</string>
<string name="uploader_wrn_no_account_quit_btn_text">გამოსვლა</string>
<string name="uploader_wrn_no_account_setup_btn_text">დაყენება</string>
<string name="uploader_wrn_no_account_text">ანგარიშები %1$s თქვენს მოწყობილობაზე არაა. გთხოვთ დააყენოთ ანგარიში.</string>
<string name="uploader_wrn_no_account_title">ანგარიში ვერ მოიძებნა</string>
<string name="uploads_view_group_current_uploads">მიმდინარე</string>
<string name="uploads_view_group_failed_uploads">ვერ მოხერხებული/მიმდინარე რესტარტი</string>
<string name="uploads_view_group_finished_uploads">ატვირთულია</string>
<string name="uploads_view_group_manually_cancelled_uploads">უარყოფილია</string>
<string name="uploads_view_later_waiting_to_upload">ველოდებით ატვირთვას</string>
<string name="uploads_view_title">ატვირთვები</string>
<string name="uploads_view_upload_status_cancelled">უარყოფილია</string>
<string name="uploads_view_upload_status_conflict">კონფლიქტი</string>
<string name="uploads_view_upload_status_failed_connection_error">კავშირის პრობლემა</string>
<string name="uploads_view_upload_status_failed_credentials_error">შეცდომა უფლებამოსილებებში</string>
<string name="uploads_view_upload_status_failed_file_error">ფაილის შეცდომა</string>
<string name="uploads_view_upload_status_failed_folder_error">დირექტორიის შეცდომა</string>
<string name="uploads_view_upload_status_failed_localfile_error">ლოკალური ფაილი ვერ იქნა ნაპოვნი</string>
<string name="uploads_view_upload_status_failed_permission_error">შეცდომა უფლებებში</string>
<string name="uploads_view_upload_status_failed_ssl_certificate_not_trusted">სერვერის არასანდო სერტიფიკატი</string>
<string name="uploads_view_upload_status_service_interrupted">აპლიკაცია შეჩერდა</string>
<string name="uploads_view_upload_status_succeeded">დასრულებულია</string>
<string name="uploads_view_upload_status_unknown_fail">უცნობი შეცდომა</string>
<string name="uploads_view_upload_status_waiting_exit_power_save_mode">ველოდებით ეკონომიური რეჟიმიდან გამოსვლას</string>
<string name="uploads_view_upload_status_waiting_for_charging">გადახდის მოლოდინშია</string>
<string name="user_icon">მომხმარებელი</string>
<string name="user_info_address">მისამართი</string>
<string name="user_info_email">ელ-ფოსტა</string>
<string name="user_info_phone">ტელეფონის ნომერი</string>
<string name="user_info_twitter">Twitter-ი</string>
<string name="user_info_website">ვებ-საიტი</string>
<string name="user_information_retrieval_error">მოხმარებლის ინფორმაციის მიღებისას წარმოიშვა შეცდომა</string>
<string name="userinfo_no_info_headline">პირადი ინფორმაციის კომპლექტი არაა</string>
<string name="userinfo_no_info_text">დაამატეთ სახელი, ფოტო და საკონტაქტო დეტალები თქვენს პროფილის გვერდზე.</string>
<string name="username">მომხმარებლის სახელი</string>
<string name="version_dev_download">ჩამოტვირთვა</string>
<string name="wait_checking_credentials">მოწმდება შენახული უფლებამოსილებანი</string>
<string name="wait_for_tmp_copy_from_private_storage">ფაილის კოპირება პირადი საცავიდან</string>
<string name="webview_version_check_alert_dialog_positive_button_title">განახლება</string>
<string name="what_s_new_image">რა არის ახალი სურათი</string>
<string name="whats_new_skip">გამოტოვება</string>
<string name="whats_new_title">ახალი %1$s-ში</string>
<string name="write_email">ელ-წერილის გაგზავნა</string>
</resources>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Account creation failed</string> <string name="account_creation_failed">Account creation failed</string>
<string name="account_icon">Account icon</string> <string name="account_icon">Account icon</string>
<string name="account_not_found">Account not found!</string> <string name="account_not_found">Account not found!</string>
<string name="action_clear_failed_uploads">Clear failed uploads</string>
<string name="action_edit">Edit</string> <string name="action_edit">Edit</string>
<string name="action_empty_notifications">Clear all notifications</string> <string name="action_empty_notifications">Clear all notifications</string>
<string name="action_empty_trashbin">Empty trash bin</string> <string name="action_empty_trashbin">Empty trash bin</string>
@ -152,7 +151,6 @@
<string name="confirmation_remove_folder_alert">Do you really want to delete %1$s and the contents thereof?</string> <string name="confirmation_remove_folder_alert">Do you really want to delete %1$s and the contents thereof?</string>
<string name="confirmation_remove_folders_alert">Do you really want to delete the selected items and their contents?</string> <string name="confirmation_remove_folders_alert">Do you really want to delete the selected items and their contents?</string>
<string name="confirmation_remove_local">Local only</string> <string name="confirmation_remove_local">Local only</string>
<string name="conflict_dialog_error">Error creating conflict dialog!</string>
<string name="conflict_file_headline">Conflicting file %1$s</string> <string name="conflict_file_headline">Conflicting file %1$s</string>
<string name="conflict_local_file">Local file</string> <string name="conflict_local_file">Local file</string>
<string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string> <string name="conflict_message_description">If you select both versions, the local file will have a number appended to its name.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">계정 생성에 실패했습니다.</string> <string name="account_creation_failed">계정 생성에 실패했습니다.</string>
<string name="account_icon">계정 아이콘</string> <string name="account_icon">계정 아이콘</string>
<string name="account_not_found">계정을 찾을 수 없습니다!</string> <string name="account_not_found">계정을 찾을 수 없습니다!</string>
<string name="action_clear_failed_uploads">실패한 업로드 삭제</string>
<string name="action_edit">편집</string> <string name="action_edit">편집</string>
<string name="action_empty_notifications">모든 알림 지우기</string> <string name="action_empty_notifications">모든 알림 지우기</string>
<string name="action_empty_trashbin">휴지통 비우기</string> <string name="action_empty_trashbin">휴지통 비우기</string>
@ -154,7 +153,6 @@
<string name="confirmation_remove_folder_alert">%1$s 및 포함된 모든 내용을 삭제하시겠습니까?</string> <string name="confirmation_remove_folder_alert">%1$s 및 포함된 모든 내용을 삭제하시겠습니까?</string>
<string name="confirmation_remove_folders_alert">선택한 항목과 포함된 내용을 삭제하시겠습니까?</string> <string name="confirmation_remove_folders_alert">선택한 항목과 포함된 내용을 삭제하시겠습니까?</string>
<string name="confirmation_remove_local">로컬만</string> <string name="confirmation_remove_local">로컬만</string>
<string name="conflict_dialog_error">다이얼로그의 충돌로 인한 오류</string>
<string name="conflict_file_headline">충돌하는 파일 %1$s</string> <string name="conflict_file_headline">충돌하는 파일 %1$s</string>
<string name="conflict_local_file">로컬 파일</string> <string name="conflict_local_file">로컬 파일</string>
<string name="conflict_message_description">두 버전을 모두 선택하면 기존 파일 이름에 번호가 추가됩니다.</string> <string name="conflict_message_description">두 버전을 모두 선택하면 기존 파일 이름에 번호가 추가됩니다.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">ການສ້າງບັນຊີບໍ່ສຳເລັດ</string> <string name="account_creation_failed">ການສ້າງບັນຊີບໍ່ສຳເລັດ</string>
<string name="account_icon">ໄອຄອນບັນຊີ</string> <string name="account_icon">ໄອຄອນບັນຊີ</string>
<string name="account_not_found">ບໍ່ພົບບັນຊີ!</string> <string name="account_not_found">ບໍ່ພົບບັນຊີ!</string>
<string name="action_clear_failed_uploads">ການອັບໂຫຼດບໍ່ສຳເລັດ</string>
<string name="action_edit">ແກ້ໄຂ</string> <string name="action_edit">ແກ້ໄຂ</string>
<string name="action_empty_notifications">ລ້າງການແຈ້ງເຕືອນທັງຫມົດ</string> <string name="action_empty_notifications">ລ້າງການແຈ້ງເຕືອນທັງຫມົດ</string>
<string name="action_empty_trashbin">ລ້າງຖັງຂີ້ເຫຍື່ອ</string> <string name="action_empty_trashbin">ລ້າງຖັງຂີ້ເຫຍື່ອ</string>
@ -145,7 +144,6 @@
<string name="confirmation_remove_folder_alert">ທ່ານຕ້ອງການ ລຶບ%1$s ແລະ ເນື້ອຫາບໍ?</string> <string name="confirmation_remove_folder_alert">ທ່ານຕ້ອງການ ລຶບ%1$s ແລະ ເນື້ອຫາບໍ?</string>
<string name="confirmation_remove_folders_alert">ທ່ານຕ້ອງການລຶບລາຍການທີ່ເລືອກ ແລະ ເນື້ອຫາແທ້ບໍ?</string> <string name="confirmation_remove_folders_alert">ທ່ານຕ້ອງການລຶບລາຍການທີ່ເລືອກ ແລະ ເນື້ອຫາແທ້ບໍ?</string>
<string name="confirmation_remove_local">ຊ່ອງເກັບຢ່າງດຽວ</string> <string name="confirmation_remove_local">ຊ່ອງເກັບຢ່າງດຽວ</string>
<string name="conflict_dialog_error">ຄວາມຜິດພາດໃນການສ້າງການສົນທະນາຜິດພາດ!</string>
<string name="conflict_file_headline">ຟາຍຜິດພາດ%1$s</string> <string name="conflict_file_headline">ຟາຍຜິດພາດ%1$s</string>
<string name="conflict_message_description">ຖ້າທ່ານເລືອກເອົາທັງສອງເວີຊັ້ນ, ບ່ອນເກັບຟາຍຈະມີຈໍານວນສະສົມ</string> <string name="conflict_message_description">ຖ້າທ່ານເລືອກເອົາທັງສອງເວີຊັ້ນ, ບ່ອນເກັບຟາຍຈະມີຈໍານວນສະສົມ</string>
<string name="contactlist_item_icon">ລາຍການໄອຄອນຜູ້ຕິດຕໍ່</string> <string name="contactlist_item_icon">ລາຍການໄອຄອນຜູ້ຕິດຕໍ່</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Paskyros sukūrimas nepavyko</string> <string name="account_creation_failed">Paskyros sukūrimas nepavyko</string>
<string name="account_icon">Paskyros piktograma</string> <string name="account_icon">Paskyros piktograma</string>
<string name="account_not_found">Paskyra nerasta!</string> <string name="account_not_found">Paskyra nerasta!</string>
<string name="action_clear_failed_uploads">Išvalyti nepavykusius įkėlimus</string>
<string name="action_edit">Taisyti</string> <string name="action_edit">Taisyti</string>
<string name="action_empty_notifications">Išvalyti visus pranešimus</string> <string name="action_empty_notifications">Išvalyti visus pranešimus</string>
<string name="action_empty_trashbin">Išvalyti šiukšlinę</string> <string name="action_empty_trashbin">Išvalyti šiukšlinę</string>
@ -147,7 +146,6 @@
<string name="confirmation_remove_folder_alert">Ar tikrai norite ištrinti %1$s ir jo turinį?</string> <string name="confirmation_remove_folder_alert">Ar tikrai norite ištrinti %1$s ir jo turinį?</string>
<string name="confirmation_remove_folders_alert">Ar tikrai norite ištrinti pažymėtus elementus ir jų turinį?</string> <string name="confirmation_remove_folders_alert">Ar tikrai norite ištrinti pažymėtus elementus ir jų turinį?</string>
<string name="confirmation_remove_local">Tik vietiniai</string> <string name="confirmation_remove_local">Tik vietiniai</string>
<string name="conflict_dialog_error">Klaida kuriant konflikto dialogą!</string>
<string name="conflict_file_headline">Nesuderinamas failas%1$s</string> <string name="conflict_file_headline">Nesuderinamas failas%1$s</string>
<string name="conflict_local_file">Vietinis failas</string> <string name="conflict_local_file">Vietinis failas</string>
<string name="conflict_message_description">Jei pasirinksite abi versijas, vietinis failas prie pavadinimo turės numerį.</string> <string name="conflict_message_description">Jei pasirinksite abi versijas, vietinis failas prie pavadinimo turės numerį.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Konta izveidošana neizdevās</string> <string name="account_creation_failed">Konta izveidošana neizdevās</string>
<string name="account_icon">Konta ikona</string> <string name="account_icon">Konta ikona</string>
<string name="account_not_found">Konts nav atrasts!</string> <string name="account_not_found">Konts nav atrasts!</string>
<string name="action_clear_failed_uploads">Notīrīt neizdevušās augšupielādes</string>
<string name="action_edit">Rediģēt</string> <string name="action_edit">Rediģēt</string>
<string name="action_empty_notifications">Notīrīt visus paziņojumus</string> <string name="action_empty_notifications">Notīrīt visus paziņojumus</string>
<string name="action_empty_trashbin">Izdzēst miskastes saturu</string> <string name="action_empty_trashbin">Izdzēst miskastes saturu</string>
@ -123,7 +122,6 @@
<string name="confirmation_remove_folder_alert">Vai tiešām vēlaties izdzēst %1$s un tā saturu?</string> <string name="confirmation_remove_folder_alert">Vai tiešām vēlaties izdzēst %1$s un tā saturu?</string>
<string name="confirmation_remove_folders_alert">Vai tiešām vēlies dzēst izvēlētos objektus un to saturu?</string> <string name="confirmation_remove_folders_alert">Vai tiešām vēlies dzēst izvēlētos objektus un to saturu?</string>
<string name="confirmation_remove_local">Tikai lokālos</string> <string name="confirmation_remove_local">Tikai lokālos</string>
<string name="conflict_dialog_error">Kļūda veidojot konfliktu dialogu!</string>
<string name="contactlist_item_icon">Lietotāja ikona kontaktpersonu sarakstam</string> <string name="contactlist_item_icon">Lietotāja ikona kontaktpersonu sarakstam</string>
<string name="contactlist_no_permission">Nav dota atļauja, importēšana neizdevās</string> <string name="contactlist_no_permission">Nav dota atļauja, importēšana neizdevās</string>
<string name="contacts">Kontakti</string> <string name="contacts">Kontakti</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Неуспешно креирање на сметка</string> <string name="account_creation_failed">Неуспешно креирање на сметка</string>
<string name="account_icon">Икона за сметката</string> <string name="account_icon">Икона за сметката</string>
<string name="account_not_found">Сметката не е пројандена!</string> <string name="account_not_found">Сметката не е пројандена!</string>
<string name="action_clear_failed_uploads">Исчисти ги неуспешните прикачувања</string>
<string name="action_edit">Уреди</string> <string name="action_edit">Уреди</string>
<string name="action_empty_notifications">Исчисти ги сите известувања</string> <string name="action_empty_notifications">Исчисти ги сите известувања</string>
<string name="action_empty_trashbin">Испразни ја корпата со отпадоци</string> <string name="action_empty_trashbin">Испразни ја корпата со отпадоци</string>
@ -144,7 +143,6 @@
<string name="confirmation_remove_folder_alert">али си сигурен дека сакаш да ја избришеш %1$s и содржината во истата?</string> <string name="confirmation_remove_folder_alert">али си сигурен дека сакаш да ја избришеш %1$s и содржината во истата?</string>
<string name="confirmation_remove_folders_alert">Дали си сигурен дека сакаш да ја избришеш означената ставкаи содржината во неа?</string> <string name="confirmation_remove_folders_alert">Дали си сигурен дека сакаш да ја избришеш означената ставкаи содржината во неа?</string>
<string name="confirmation_remove_local">Само локално</string> <string name="confirmation_remove_local">Само локално</string>
<string name="conflict_dialog_error">Грешка при креирање конфликтен извештај!</string>
<string name="conflict_file_headline">Датотеки со конфликт %1$s</string> <string name="conflict_file_headline">Датотеки со конфликт %1$s</string>
<string name="conflict_local_file">Локална датотека</string> <string name="conflict_local_file">Локална датотека</string>
<string name="conflict_message_description">Ако ги одберете и двете верзии, локалната датотека ќе има број додаден на нејзиното име.</string> <string name="conflict_message_description">Ако ги одберете и двете верзии, локалната датотека ќе има број додаден на нејзиното име.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Oppretting av konto mislyktes</string> <string name="account_creation_failed">Oppretting av konto mislyktes</string>
<string name="account_icon">Kontoikon</string> <string name="account_icon">Kontoikon</string>
<string name="account_not_found">Konto ble ikke funnet!</string> <string name="account_not_found">Konto ble ikke funnet!</string>
<string name="action_clear_failed_uploads">Fjern feilede opplastinger</string>
<string name="action_edit">Rediger</string> <string name="action_edit">Rediger</string>
<string name="action_empty_notifications">Slett alle varsel</string> <string name="action_empty_notifications">Slett alle varsel</string>
<string name="action_empty_trashbin">Tøm papirkurv</string> <string name="action_empty_trashbin">Tøm papirkurv</string>
@ -57,6 +56,8 @@
<string name="assistant_screen_task_types_error_state_message">Kan ikke hente oppgavetyper, vennligst sjekk internettforbindelsen din.</string> <string name="assistant_screen_task_types_error_state_message">Kan ikke hente oppgavetyper, vennligst sjekk internettforbindelsen din.</string>
<string name="assistant_screen_top_bar_title">Assistent</string> <string name="assistant_screen_top_bar_title">Assistent</string>
<string name="assistant_screen_unknown_task_status_text">Ukjent</string> <string name="assistant_screen_unknown_task_status_text">Ukjent</string>
<string name="assistant_task_detail_screen_input_button_title">Inndata</string>
<string name="assistant_task_detail_screen_output_button_title">Utdata</string>
<string name="associated_account_not_found">Tilknyttet bruker ikke funnet!</string> <string name="associated_account_not_found">Tilknyttet bruker ikke funnet!</string>
<string name="auth_access_failed">Tilgang mislyktes: %1$s</string> <string name="auth_access_failed">Tilgang mislyktes: %1$s</string>
<string name="auth_account_does_not_exist">Kontoen er ikke lagt til på denne enheten enda</string> <string name="auth_account_does_not_exist">Kontoen er ikke lagt til på denne enheten enda</string>
@ -171,7 +172,6 @@
<string name="confirmation_remove_folder_alert">Ønsker du virkelig å slette %1$s og dets innhold?</string> <string name="confirmation_remove_folder_alert">Ønsker du virkelig å slette %1$s og dets innhold?</string>
<string name="confirmation_remove_folders_alert">Vil du virkelig fjerne de valgte elementene og dets innhold?</string> <string name="confirmation_remove_folders_alert">Vil du virkelig fjerne de valgte elementene og dets innhold?</string>
<string name="confirmation_remove_local">Kun lokalt</string> <string name="confirmation_remove_local">Kun lokalt</string>
<string name="conflict_dialog_error">Feil ved oppretting av konfliktdialog!</string>
<string name="conflict_file_headline">Konflikt med%1$s</string> <string name="conflict_file_headline">Konflikt med%1$s</string>
<string name="conflict_local_file">Lokal fil</string> <string name="conflict_local_file">Lokal fil</string>
<string name="conflict_message_description">Hvis du velger begge versjonene vil den lokale filen få et tall lagt til på slutten av navnet.</string> <string name="conflict_message_description">Hvis du velger begge versjonene vil den lokale filen få et tall lagt til på slutten av navnet.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Account aanmaken mislukt</string> <string name="account_creation_failed">Account aanmaken mislukt</string>
<string name="account_icon">Accountpictogram</string> <string name="account_icon">Accountpictogram</string>
<string name="account_not_found">Account niet gevonden!</string> <string name="account_not_found">Account niet gevonden!</string>
<string name="action_clear_failed_uploads">Wis mislukte uploads</string>
<string name="action_edit">Bewerken</string> <string name="action_edit">Bewerken</string>
<string name="action_empty_notifications">Handel alle meldingen af</string> <string name="action_empty_notifications">Handel alle meldingen af</string>
<string name="action_empty_trashbin">Prullenbak legen</string> <string name="action_empty_trashbin">Prullenbak legen</string>
@ -167,7 +166,6 @@
<string name="confirmation_remove_folder_alert">Wil je %1$s en de inhoud ervan werkelijk verwijderen?</string> <string name="confirmation_remove_folder_alert">Wil je %1$s en de inhoud ervan werkelijk verwijderen?</string>
<string name="confirmation_remove_folders_alert">Wil je de geselecteerde objecten en hun inhoud echt verwijderen?</string> <string name="confirmation_remove_folders_alert">Wil je de geselecteerde objecten en hun inhoud echt verwijderen?</string>
<string name="confirmation_remove_local">Alleen lokaal</string> <string name="confirmation_remove_local">Alleen lokaal</string>
<string name="conflict_dialog_error">Fout bij het maken van conflictdialoog!</string>
<string name="conflict_file_headline">Conflicterend bestand%1$s</string> <string name="conflict_file_headline">Conflicterend bestand%1$s</string>
<string name="conflict_local_file">Lokaal bestand</string> <string name="conflict_local_file">Lokaal bestand</string>
<string name="conflict_message_description">Als je beide versies selecteert, zal het lokale bestand een nummer aan de naam toegevoegd krijgen.</string> <string name="conflict_message_description">Als je beide versies selecteert, zal het lokale bestand een nummer aan de naam toegevoegd krijgen.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Błąd tworzenia konta</string> <string name="account_creation_failed">Błąd tworzenia konta</string>
<string name="account_icon">Ikona konta</string> <string name="account_icon">Ikona konta</string>
<string name="account_not_found">Nie znaleziono konta!</string> <string name="account_not_found">Nie znaleziono konta!</string>
<string name="action_clear_failed_uploads">Wyczyść nieudane wysyłanie</string>
<string name="action_edit">Edytuj</string> <string name="action_edit">Edytuj</string>
<string name="action_empty_notifications">Wyczyść wszystkie powiadomienia</string> <string name="action_empty_notifications">Wyczyść wszystkie powiadomienia</string>
<string name="action_empty_trashbin">Opróżnij kosz</string> <string name="action_empty_trashbin">Opróżnij kosz</string>
@ -153,7 +152,6 @@
<string name="confirmation_remove_folder_alert">Czy na pewno chcesz usunąć %1$s wraz z zawartością?</string> <string name="confirmation_remove_folder_alert">Czy na pewno chcesz usunąć %1$s wraz z zawartością?</string>
<string name="confirmation_remove_folders_alert">Czy na pewno chcesz usunąć wybrane pozycje i ich zawartość?</string> <string name="confirmation_remove_folders_alert">Czy na pewno chcesz usunąć wybrane pozycje i ich zawartość?</string>
<string name="confirmation_remove_local">Tylko lokalnie</string> <string name="confirmation_remove_local">Tylko lokalnie</string>
<string name="conflict_dialog_error">Błąd podczas tworzenia dialogu konfliktu!</string>
<string name="conflict_file_headline">Plik powodujący konflikt %1$s</string> <string name="conflict_file_headline">Plik powodujący konflikt %1$s</string>
<string name="conflict_local_file">Plik lokalny</string> <string name="conflict_local_file">Plik lokalny</string>
<string name="conflict_message_description">Jeśli wybierzesz obie wersje, to do nazwy pliku lokalnego zostanie dodany numer.</string> <string name="conflict_message_description">Jeśli wybierzesz obie wersje, to do nazwy pliku lokalnego zostanie dodany numer.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Falha ao criar conta</string> <string name="account_creation_failed">Falha ao criar conta</string>
<string name="account_icon">Ícone da conta</string> <string name="account_icon">Ícone da conta</string>
<string name="account_not_found">Conta não encontrada!</string> <string name="account_not_found">Conta não encontrada!</string>
<string name="action_clear_failed_uploads">Apagar envios com falha</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Apagar todas as notificações</string> <string name="action_empty_notifications">Apagar todas as notificações</string>
<string name="action_empty_trashbin">Esvaziar lixeira </string> <string name="action_empty_trashbin">Esvaziar lixeira </string>
@ -57,6 +56,8 @@
<string name="assistant_screen_task_types_error_state_message">Não foi possível buscar os tipos de tarefas. Verifique sua conexão com a Internet.</string> <string name="assistant_screen_task_types_error_state_message">Não foi possível buscar os tipos de tarefas. Verifique sua conexão com a Internet.</string>
<string name="assistant_screen_top_bar_title">Assistente</string> <string name="assistant_screen_top_bar_title">Assistente</string>
<string name="assistant_screen_unknown_task_status_text">Desconhecido</string> <string name="assistant_screen_unknown_task_status_text">Desconhecido</string>
<string name="assistant_task_detail_screen_input_button_title">Entrada</string>
<string name="assistant_task_detail_screen_output_button_title">Saída</string>
<string name="associated_account_not_found">Conta associada não encontrada!</string> <string name="associated_account_not_found">Conta associada não encontrada!</string>
<string name="auth_access_failed">O acesso falhou: %1$s</string> <string name="auth_access_failed">O acesso falhou: %1$s</string>
<string name="auth_account_does_not_exist">A conta ainda não está adicionada neste dispositivo</string> <string name="auth_account_does_not_exist">A conta ainda não está adicionada neste dispositivo</string>
@ -171,7 +172,6 @@
<string name="confirmation_remove_folder_alert">Quer realmente excluir %1$s e seu conteúdo?</string> <string name="confirmation_remove_folder_alert">Quer realmente excluir %1$s e seu conteúdo?</string>
<string name="confirmation_remove_folders_alert">Quer realmente excluir os itens selecionados e seus conteúdos?</string> <string name="confirmation_remove_folders_alert">Quer realmente excluir os itens selecionados e seus conteúdos?</string>
<string name="confirmation_remove_local">Somente local</string> <string name="confirmation_remove_local">Somente local</string>
<string name="conflict_dialog_error">Erro ao criar diálogo de conflito!</string>
<string name="conflict_file_headline">Arquivo conflitante %1$s</string> <string name="conflict_file_headline">Arquivo conflitante %1$s</string>
<string name="conflict_local_file">Arquivo local</string> <string name="conflict_local_file">Arquivo local</string>
<string name="conflict_message_description">Se você selecionar as duas versões, o arquivo local terá um número anexado ao seu nome.</string> <string name="conflict_message_description">Se você selecionar as duas versões, o arquivo local terá um número anexado ao seu nome.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Criação de conta falhou</string> <string name="account_creation_failed">Criação de conta falhou</string>
<string name="account_icon">Ícone de conta</string> <string name="account_icon">Ícone de conta</string>
<string name="account_not_found">Conta não encontrada!</string> <string name="account_not_found">Conta não encontrada!</string>
<string name="action_clear_failed_uploads">Limpar envios falhados</string>
<string name="action_edit">Editar</string> <string name="action_edit">Editar</string>
<string name="action_empty_notifications">Limpar todas as notifcações</string> <string name="action_empty_notifications">Limpar todas as notifcações</string>
<string name="action_empty_trashbin">Esvaziar a reciclagem</string> <string name="action_empty_trashbin">Esvaziar a reciclagem</string>
@ -150,7 +149,6 @@
<string name="confirmation_remove_folder_alert">Deseja realmente apagar %1$s e o seu conteúdo?</string> <string name="confirmation_remove_folder_alert">Deseja realmente apagar %1$s e o seu conteúdo?</string>
<string name="confirmation_remove_folders_alert">Quer realmente apagar os itens seleccionados e os seus conteúdos?</string> <string name="confirmation_remove_folders_alert">Quer realmente apagar os itens seleccionados e os seus conteúdos?</string>
<string name="confirmation_remove_local">Apenas localmente</string> <string name="confirmation_remove_local">Apenas localmente</string>
<string name="conflict_dialog_error">Erro ao criar a janela de conflito!</string>
<string name="conflict_file_headline">Ficheiro em conflito %1$s</string> <string name="conflict_file_headline">Ficheiro em conflito %1$s</string>
<string name="conflict_local_file">Ficheiro local</string> <string name="conflict_local_file">Ficheiro local</string>
<string name="conflict_message_description">Se selecionou ambas as versões, o ficheiro local terá um número acrescentado ao seu nome.</string> <string name="conflict_message_description">Se selecionou ambas as versões, o ficheiro local terá um número acrescentado ao seu nome.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Eroare la crearea contului</string> <string name="account_creation_failed">Eroare la crearea contului</string>
<string name="account_icon">Iconița contului</string> <string name="account_icon">Iconița contului</string>
<string name="account_not_found">Contul nu a fost găsit!</string> <string name="account_not_found">Contul nu a fost găsit!</string>
<string name="action_clear_failed_uploads">Elimină încărcările eșuate</string>
<string name="action_edit">Editare</string> <string name="action_edit">Editare</string>
<string name="action_empty_notifications">Elimină toate notificările</string> <string name="action_empty_notifications">Elimină toate notificările</string>
<string name="action_empty_trashbin">Golește coșul de gunoi</string> <string name="action_empty_trashbin">Golește coșul de gunoi</string>
@ -150,7 +149,6 @@
<string name="confirmation_remove_folder_alert">Sigur vreți să eliminați %1$s și conținutul său?</string> <string name="confirmation_remove_folder_alert">Sigur vreți să eliminați %1$s și conținutul său?</string>
<string name="confirmation_remove_folders_alert">Doriți să ștergeți elementele selectate și conținutul lor?</string> <string name="confirmation_remove_folders_alert">Doriți să ștergeți elementele selectate și conținutul lor?</string>
<string name="confirmation_remove_local">Doar local</string> <string name="confirmation_remove_local">Doar local</string>
<string name="conflict_dialog_error">Eroare la crearea dialogului pentru conflict!</string>
<string name="conflict_file_headline">Conflict cu fișierul %1$s</string> <string name="conflict_file_headline">Conflict cu fișierul %1$s</string>
<string name="conflict_local_file">Fișier local</string> <string name="conflict_local_file">Fișier local</string>
<string name="conflict_message_description">Dacă selectezi ambele variante, atunci fișierul local va avea un număr adăugat la numele său.</string> <string name="conflict_message_description">Dacă selectezi ambele variante, atunci fișierul local va avea un număr adăugat la numele său.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Ошибка создания учетной записи</string> <string name="account_creation_failed">Ошибка создания учетной записи</string>
<string name="account_icon">Значок учётной записи</string> <string name="account_icon">Значок учётной записи</string>
<string name="account_not_found">Учётная запись не найдена!</string> <string name="account_not_found">Учётная запись не найдена!</string>
<string name="action_clear_failed_uploads">Убрать неудавшиеся загрузки</string>
<string name="action_edit">Редактировать</string> <string name="action_edit">Редактировать</string>
<string name="action_empty_notifications">Удалить все уведомления</string> <string name="action_empty_notifications">Удалить все уведомления</string>
<string name="action_empty_trashbin">Очистить корзину</string> <string name="action_empty_trashbin">Очистить корзину</string>
@ -158,7 +157,6 @@
<string name="confirmation_remove_folder_alert">Действительно удалить «%1$s» и его содержимое?</string> <string name="confirmation_remove_folder_alert">Действительно удалить «%1$s» и его содержимое?</string>
<string name="confirmation_remove_folders_alert">Действительно удалить выбранные объекты и их содержимое?</string> <string name="confirmation_remove_folders_alert">Действительно удалить выбранные объекты и их содержимое?</string>
<string name="confirmation_remove_local">Только локально</string> <string name="confirmation_remove_local">Только локально</string>
<string name="conflict_dialog_error">Не удалось создать диалоговое окно разрешения конфликта синхронизации.</string>
<string name="conflict_file_headline">Конфликт версий файла «%1$s»</string> <string name="conflict_file_headline">Конфликт версий файла «%1$s»</string>
<string name="conflict_local_file">Локальный файл</string> <string name="conflict_local_file">Локальный файл</string>
<string name="conflict_message_description">Если вы выберете обе версии, локальный файл будет иметь номер, добавленный к его имени.</string> <string name="conflict_message_description">Если вы выберете обе версии, локальный файл будет иметь номер, добавленный к его имени.</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Errore in sa creatzione de su contu</string> <string name="account_creation_failed">Errore in sa creatzione de su contu</string>
<string name="account_icon">Icona de su contu</string> <string name="account_icon">Icona de su contu</string>
<string name="account_not_found">Contu no agatadu!</string> <string name="account_not_found">Contu no agatadu!</string>
<string name="action_clear_failed_uploads">Boga·nche is carrigamentos faddidos</string>
<string name="action_edit">Modìfica</string> <string name="action_edit">Modìfica</string>
<string name="action_empty_notifications">Boga·nche totu is notìficas</string> <string name="action_empty_notifications">Boga·nche totu is notìficas</string>
<string name="action_empty_trashbin">Bòida s\'àliga</string> <string name="action_empty_trashbin">Bòida s\'àliga</string>
@ -144,7 +143,6 @@
<string name="confirmation_remove_folder_alert">A beru boles cantzellare %1$s e is cuntenutos suos?</string> <string name="confirmation_remove_folder_alert">A beru boles cantzellare %1$s e is cuntenutos suos?</string>
<string name="confirmation_remove_folders_alert">A beru boles cantzellare is elementos seberados e is cuntenutos issoro?</string> <string name="confirmation_remove_folders_alert">A beru boles cantzellare is elementos seberados e is cuntenutos issoro?</string>
<string name="confirmation_remove_local">Locale isceti</string> <string name="confirmation_remove_local">Locale isceti</string>
<string name="conflict_dialog_error">Errore creende una bentana de cunflitu!</string>
<string name="conflict_file_headline">Archìviu in cunflitu %1$s</string> <string name="conflict_file_headline">Archìviu in cunflitu %1$s</string>
<string name="conflict_message_description">Si seletzionas ambas is versiones, s\'archìviu locale at a tènnere unu nùmeru in agiunta a su nùmene.</string> <string name="conflict_message_description">Si seletzionas ambas is versiones, s\'archìviu locale at a tènnere unu nùmeru in agiunta a su nùmene.</string>
<string name="contactlist_item_icon">Icona utente pro lista de cuntatos</string> <string name="contactlist_item_icon">Icona utente pro lista de cuntatos</string>

View file

@ -7,7 +7,6 @@
<string name="account_creation_failed">Vytvorenie účtu sa nepodarilo</string> <string name="account_creation_failed">Vytvorenie účtu sa nepodarilo</string>
<string name="account_icon">Ikona účtu</string> <string name="account_icon">Ikona účtu</string>
<string name="account_not_found">Účet sa nenašiel!</string> <string name="account_not_found">Účet sa nenašiel!</string>
<string name="action_clear_failed_uploads">Odstrániť zlyhané nahrávania</string>
<string name="action_edit">Upraviť</string> <string name="action_edit">Upraviť</string>
<string name="action_empty_notifications">Odstrániť všetky upozornenia</string> <string name="action_empty_notifications">Odstrániť všetky upozornenia</string>
<string name="action_empty_trashbin">Vyprázdniť kôš</string> <string name="action_empty_trashbin">Vyprázdniť kôš</string>
@ -171,7 +170,6 @@
<string name="confirmation_remove_folder_alert">Naozaj chcete odstrániť %1$s a jeho obsah?</string> <string name="confirmation_remove_folder_alert">Naozaj chcete odstrániť %1$s a jeho obsah?</string>
<string name="confirmation_remove_folders_alert">Naozaj chcete odstrániť vybraté položky a ich obsah?</string> <string name="confirmation_remove_folders_alert">Naozaj chcete odstrániť vybraté položky a ich obsah?</string>
<string name="confirmation_remove_local">Iba lokálne</string> <string name="confirmation_remove_local">Iba lokálne</string>
<string name="conflict_dialog_error">Chyba pri vytváraní konfliktného dialógového okna!</string>
<string name="conflict_file_headline">Konfliktný súbor %1$s</string> <string name="conflict_file_headline">Konfliktný súbor %1$s</string>
<string name="conflict_local_file">Lokálny súbor</string> <string name="conflict_local_file">Lokálny súbor</string>
<string name="conflict_message_description">Ak vyberiete obe verzie, miestny súbor bude mať k svojmu názvu pridané číslo.</string> <string name="conflict_message_description">Ak vyberiete obe verzie, miestny súbor bude mať k svojmu názvu pridané číslo.</string>

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