mirror of
https://github.com/nextcloud/android.git
synced 2024-12-19 15:33:00 +03:00
Merge remote-tracking branch 'origin/master' into dev
This commit is contained in:
commit
3cdd2f0fa2
45 changed files with 1914 additions and 34 deletions
2
.github/workflows/pr-feedback.yml
vendored
2
.github/workflows/pr-feedback.yml
vendored
|
@ -46,5 +46,5 @@ jobs:
|
|||
(If you believe you should not receive this message, you can add yourself to the [blocklist](https://github.com/nextcloud/.github/blob/master/non-community-usernames.txt).)
|
||||
days-before-feedback: 14
|
||||
start-date: '2024-04-30'
|
||||
exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }},nextcloud-command,nextcloud-android-bot'
|
||||
exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }}'
|
||||
exempt-bots: true
|
||||
|
|
8
.github/workflows/reuse.yml
vendored
8
.github/workflows/reuse.yml
vendored
|
@ -15,8 +15,8 @@ jobs:
|
|||
reuse-compliance-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
- name: REUSE Compliance Check
|
||||
uses: fsfe/reuse-action@3ae3c6bdf1257ab19397fab11fd3312144692083 # v4.0.0
|
||||
- name: REUSE Compliance Check
|
||||
uses: fsfe/reuse-action@3ae3c6bdf1257ab19397fab11fd3312144692083 # v4.0.0
|
||||
|
|
|
@ -1206,4 +1206,4 @@
|
|||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '082a63031678a67879428f688f02d3b5')"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1245
app/schemas/com.nextcloud.client.database.NextcloudDatabase/83.json
Normal file
1245
app/schemas/com.nextcloud.client.database.NextcloudDatabase/83.json
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 35 KiB |
Binary file not shown.
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 35 KiB |
|
@ -106,7 +106,6 @@ public class FileIT extends AbstractOnServerIT {
|
|||
assertTrue(new SynchronizeFolderOperation(targetContext,
|
||||
folderPath,
|
||||
user,
|
||||
System.currentTimeMillis(),
|
||||
fileDataStorageManager)
|
||||
.execute(targetContext)
|
||||
.isSuccess());
|
||||
|
|
|
@ -255,6 +255,9 @@
|
|||
<activity
|
||||
android:name=".ui.activity.SyncedFoldersActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".ui.activity.InternalTwoWaySyncActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name="com.nextcloud.client.widget.DashboardWidgetConfigurationActivity"
|
||||
android:exported="false">
|
||||
|
@ -627,4 +630,4 @@
|
|||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
|
|
@ -60,7 +60,8 @@ import com.owncloud.android.db.ProviderMeta
|
|||
AutoMigration(from = 78, to = 79, spec = DatabaseMigrationUtil.ResetCapabilitiesPostMigration::class),
|
||||
AutoMigration(from = 79, to = 80),
|
||||
AutoMigration(from = 80, to = 81),
|
||||
AutoMigration(from = 81, to = 82)
|
||||
AutoMigration(from = 81, to = 82),
|
||||
AutoMigration(from = 82, to = 83)
|
||||
],
|
||||
exportSchema = true
|
||||
)
|
||||
|
|
|
@ -49,4 +49,10 @@ interface FileDao {
|
|||
|
||||
@Query("SELECT * FROM filelist where file_owner = :fileOwner AND etag_in_conflict IS NOT NULL")
|
||||
fun getFilesWithSyncConflict(fileOwner: String): List<FileEntity>
|
||||
|
||||
@Query(
|
||||
"SELECT * FROM filelist where file_owner = :fileOwner AND internal_two_way_sync_timestamp >= 0 " +
|
||||
"ORDER BY internal_two_way_sync_timestamp DESC"
|
||||
)
|
||||
fun getInternalTwoWaySyncFolders(fileOwner: String): List<FileEntity>
|
||||
}
|
||||
|
|
|
@ -115,5 +115,9 @@ data class FileEntity(
|
|||
@ColumnInfo(name = ProviderTableMeta.FILE_METADATA_GPS)
|
||||
val metadataGPS: String?,
|
||||
@ColumnInfo(name = ProviderTableMeta.FILE_E2E_COUNTER)
|
||||
val e2eCounter: Long?
|
||||
val e2eCounter: Long?,
|
||||
@ColumnInfo(name = ProviderTableMeta.FILE_INTERNAL_TWO_WAY_SYNC_TIMESTAMP)
|
||||
val internalTwoWaySync: Long?,
|
||||
@ColumnInfo(name = ProviderTableMeta.FILE_INTERNAL_TWO_WAY_SYNC_RESULT)
|
||||
val internalTwoWaySyncResult: String?
|
||||
)
|
||||
|
|
|
@ -54,6 +54,7 @@ import com.owncloud.android.ui.activity.FileActivity;
|
|||
import com.owncloud.android.ui.activity.FileDisplayActivity;
|
||||
import com.owncloud.android.ui.activity.FilePickerActivity;
|
||||
import com.owncloud.android.ui.activity.FolderPickerActivity;
|
||||
import com.owncloud.android.ui.activity.InternalTwoWaySyncActivity;
|
||||
import com.owncloud.android.ui.activity.ManageAccountsActivity;
|
||||
import com.owncloud.android.ui.activity.ManageSpaceActivity;
|
||||
import com.owncloud.android.ui.activity.NotificationsActivity;
|
||||
|
@ -476,4 +477,7 @@ abstract class ComponentsModule {
|
|||
|
||||
@ContributesAndroidInjector
|
||||
abstract TestJob testJob();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract InternalTwoWaySyncActivity internalTwoWaySyncActivity();
|
||||
}
|
||||
|
|
|
@ -95,6 +95,7 @@ class BackgroundJobFactory @Inject constructor(
|
|||
GeneratePdfFromImagesWork::class -> createPDFGenerateWork(context, workerParameters)
|
||||
HealthStatusWork::class -> createHealthStatusWork(context, workerParameters)
|
||||
TestJob::class -> createTestJob(context, workerParameters)
|
||||
InternalTwoWaySyncWork::class -> createInternalTwoWaySyncWork(context, workerParameters)
|
||||
else -> null // caller falls back to default factory
|
||||
}
|
||||
}
|
||||
|
@ -277,4 +278,14 @@ class BackgroundJobFactory @Inject constructor(
|
|||
backgroundJobManager.get()
|
||||
)
|
||||
}
|
||||
|
||||
private fun createInternalTwoWaySyncWork(context: Context, params: WorkerParameters): InternalTwoWaySyncWork {
|
||||
return InternalTwoWaySyncWork(
|
||||
context,
|
||||
params,
|
||||
accountManager,
|
||||
powerManagementService,
|
||||
connectivityService
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -168,4 +168,5 @@ interface BackgroundJobManager {
|
|||
fun schedulePeriodicHealthStatus()
|
||||
fun startHealthStatus()
|
||||
fun bothFilesSyncJobsRunning(syncedFolderID: Long): Boolean
|
||||
fun scheduleInternal2WaySync()
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ internal class BackgroundJobManagerImpl(
|
|||
const val JOB_PERIODIC_HEALTH_STATUS = "periodic_health_status"
|
||||
const val JOB_IMMEDIATE_HEALTH_STATUS = "immediate_health_status"
|
||||
|
||||
const val JOB_INTERNAL_TWO_WAY_SYNC = "internal_two_way_sync"
|
||||
|
||||
const val JOB_TEST = "test_job"
|
||||
|
||||
const val MAX_CONTENT_TRIGGER_DELAY_MS = 10000L
|
||||
|
@ -647,4 +649,13 @@ internal class BackgroundJobManagerImpl(
|
|||
request
|
||||
)
|
||||
}
|
||||
|
||||
override fun scheduleInternal2WaySync() {
|
||||
val request = periodicRequestBuilder(
|
||||
jobClass = InternalTwoWaySyncWork::class,
|
||||
jobName = JOB_INTERNAL_TWO_WAY_SYNC
|
||||
).build()
|
||||
|
||||
workManager.enqueueUniquePeriodicWork(JOB_INTERNAL_TWO_WAY_SYNC, ExistingPeriodicWorkPolicy.KEEP, request)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Tobias Kaminsky <tobias.kaminsky@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.client.jobs
|
||||
|
||||
import android.content.Context
|
||||
import androidx.work.Worker
|
||||
import androidx.work.WorkerParameters
|
||||
import com.nextcloud.client.account.UserAccountManager
|
||||
import com.nextcloud.client.device.PowerManagementService
|
||||
import com.nextcloud.client.network.ConnectivityService
|
||||
import com.owncloud.android.MainApp
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager
|
||||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
import com.owncloud.android.operations.SynchronizeFolderOperation
|
||||
import com.owncloud.android.utils.FileStorageUtils
|
||||
import java.io.File
|
||||
|
||||
@Suppress("Detekt.NestedBlockDepth")
|
||||
class InternalTwoWaySyncWork(
|
||||
private val context: Context,
|
||||
params: WorkerParameters,
|
||||
private val userAccountManager: UserAccountManager,
|
||||
private val powerManagementService: PowerManagementService,
|
||||
private val connectivityService: ConnectivityService
|
||||
) : Worker(context, params) {
|
||||
override fun doWork(): Result {
|
||||
Log_OC.d(TAG, "Worker started!")
|
||||
|
||||
var result = true
|
||||
|
||||
if (powerManagementService.isPowerSavingEnabled ||
|
||||
!connectivityService.isConnected || connectivityService.isInternetWalled
|
||||
) {
|
||||
Log_OC.d(TAG, "Not starting due to constraints!")
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
val users = userAccountManager.allUsers
|
||||
|
||||
for (user in users) {
|
||||
val fileDataStorageManager = FileDataStorageManager(user, context.contentResolver)
|
||||
val folders = fileDataStorageManager.getInternalTwoWaySyncFolders(user)
|
||||
|
||||
for (folder in folders) {
|
||||
val freeSpaceLeft = File(folder.storagePath).getFreeSpace()
|
||||
val localFolderSize = FileStorageUtils.getFolderSize(File(folder.storagePath, MainApp.getDataFolder()))
|
||||
val remoteFolderSize = folder.fileLength
|
||||
|
||||
if (freeSpaceLeft < (remoteFolderSize - localFolderSize)) {
|
||||
Log_OC.d(TAG, "Not enough space left!")
|
||||
result = false
|
||||
}
|
||||
|
||||
Log_OC.d(TAG, "Folder ${folder.remotePath}: started!")
|
||||
val operation = SynchronizeFolderOperation(context, folder.remotePath, user, fileDataStorageManager)
|
||||
.execute(context)
|
||||
|
||||
if (operation.isSuccess) {
|
||||
Log_OC.d(TAG, "Folder ${folder.remotePath}: finished!")
|
||||
} else {
|
||||
Log_OC.d(TAG, "Folder ${folder.remotePath} failed!")
|
||||
result = false
|
||||
}
|
||||
|
||||
folder.apply {
|
||||
internalFolderSyncResult = operation.code.toString()
|
||||
internalFolderSyncTimestamp = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
fileDataStorageManager.saveFile(folder)
|
||||
}
|
||||
}
|
||||
|
||||
return if (result) {
|
||||
Log_OC.d(TAG, "Worker finished with success!")
|
||||
Result.success()
|
||||
} else {
|
||||
Log_OC.d(TAG, "Worker finished with failure!")
|
||||
Result.failure()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TAG = "InternalTwoWaySyncWork"
|
||||
}
|
||||
}
|
|
@ -371,6 +371,7 @@ public class MainApp extends Application implements HasAndroidInjector {
|
|||
backgroundJobManager.scheduleMediaFoldersDetectionJob();
|
||||
backgroundJobManager.startMediaFoldersDetectionJob();
|
||||
backgroundJobManager.schedulePeriodicHealthStatus();
|
||||
backgroundJobManager.scheduleInternal2WaySync();
|
||||
}
|
||||
|
||||
registerGlobalPassCodeProtection();
|
||||
|
|
|
@ -77,6 +77,7 @@ import androidx.annotation.VisibleForTesting;
|
|||
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
||||
import kotlin.Pair;
|
||||
|
||||
@SuppressFBWarnings("CE")
|
||||
public class FileDataStorageManager {
|
||||
private static final String TAG = FileDataStorageManager.class.getSimpleName();
|
||||
|
||||
|
@ -558,6 +559,8 @@ public class FileDataStorageManager {
|
|||
cv.put(ProviderTableMeta.FILE_SHAREES, gson.toJson(fileOrFolder.getSharees()));
|
||||
cv.put(ProviderTableMeta.FILE_TAGS, gson.toJson(fileOrFolder.getTags()));
|
||||
cv.put(ProviderTableMeta.FILE_RICH_WORKSPACE, fileOrFolder.getRichWorkspace());
|
||||
cv.put(ProviderTableMeta.FILE_INTERNAL_TWO_WAY_SYNC_TIMESTAMP, fileOrFolder.getInternalFolderSyncTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_INTERNAL_TWO_WAY_SYNC_RESULT, fileOrFolder.getInternalFolderSyncResult());
|
||||
return cv;
|
||||
}
|
||||
|
||||
|
@ -602,6 +605,8 @@ public class FileDataStorageManager {
|
|||
cv.put(ProviderTableMeta.FILE_METADATA_GPS, gson.toJson(file.getGeoLocation()));
|
||||
cv.put(ProviderTableMeta.FILE_METADATA_LIVE_PHOTO, file.getLinkedFileIdForLivePhoto());
|
||||
cv.put(ProviderTableMeta.FILE_E2E_COUNTER, file.getE2eCounter());
|
||||
cv.put(ProviderTableMeta.FILE_INTERNAL_TWO_WAY_SYNC_TIMESTAMP, file.getInternalFolderSyncTimestamp());
|
||||
cv.put(ProviderTableMeta.FILE_INTERNAL_TWO_WAY_SYNC_RESULT, file.getInternalFolderSyncResult());
|
||||
|
||||
return cv;
|
||||
}
|
||||
|
@ -1035,6 +1040,7 @@ public class FileDataStorageManager {
|
|||
ocFile.setLivePhoto(fileEntity.getMetadataLivePhoto());
|
||||
ocFile.setHidden(nullToZero(fileEntity.getHidden()) == 1);
|
||||
ocFile.setE2eCounter(fileEntity.getE2eCounter());
|
||||
ocFile.setInternalFolderSyncTimestamp(fileEntity.getInternalTwoWaySync());
|
||||
|
||||
String sharees = fileEntity.getSharees();
|
||||
// Surprisingly JSON deserialization causes significant overhead.
|
||||
|
@ -2477,4 +2483,29 @@ public class FileDataStorageManager {
|
|||
|
||||
return files;
|
||||
}
|
||||
|
||||
public List<OCFile> getInternalTwoWaySyncFolders(User user) {
|
||||
List<FileEntity> fileEntities = fileDao.getInternalTwoWaySyncFolders(user.getAccountName());
|
||||
List<OCFile> files = new ArrayList<>(fileEntities.size());
|
||||
|
||||
for (FileEntity fileEntity : fileEntities) {
|
||||
files.add(createFileInstance(fileEntity));
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
public boolean isPartOfInternalTwoWaySync(OCFile file) {
|
||||
if (file.isInternalFolderSync()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while (file != null && !OCFile.ROOT_PATH.equals(file.getDecryptedRemotePath())) {
|
||||
if (file.isInternalFolderSync()) {
|
||||
return true;
|
||||
}
|
||||
file = getFileById(file.getParentId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,8 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
@Nullable
|
||||
private GeoLocation geolocation;
|
||||
private List<String> tags = new ArrayList<>();
|
||||
private Long internalFolderSyncTimestamp = -1L;
|
||||
private String internalFolderSyncResult = "";
|
||||
|
||||
/**
|
||||
* URI to the local path of the file contents, if stored in the device; cached after first call to
|
||||
|
@ -1051,6 +1053,26 @@ public class OCFile implements Parcelable, Comparable<OCFile>, ServerFileInterfa
|
|||
this.e2eCounter = e2eCounter;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isInternalFolderSync() {
|
||||
return internalFolderSyncTimestamp >= 0;
|
||||
}
|
||||
|
||||
public Long getInternalFolderSyncTimestamp() {
|
||||
return internalFolderSyncTimestamp;
|
||||
}
|
||||
|
||||
public void setInternalFolderSyncTimestamp(Long internalFolderSyncTimestamp) {
|
||||
this.internalFolderSyncTimestamp = internalFolderSyncTimestamp;
|
||||
}
|
||||
|
||||
public String getInternalFolderSyncResult() {
|
||||
return internalFolderSyncResult;
|
||||
}
|
||||
|
||||
public void setInternalFolderSyncResult(String internalFolderSyncResult) {
|
||||
this.internalFolderSyncResult = internalFolderSyncResult;
|
||||
}
|
||||
|
||||
public boolean isAPKorAAB() {
|
||||
if ("gplay".equals(BuildConfig.FLAVOR)) {
|
||||
|
|
|
@ -25,7 +25,7 @@ import java.util.List;
|
|||
*/
|
||||
public class ProviderMeta {
|
||||
public static final String DB_NAME = "filelist";
|
||||
public static final int DB_VERSION = 82;
|
||||
public static final int DB_VERSION = 83;
|
||||
|
||||
private ProviderMeta() {
|
||||
// No instance
|
||||
|
@ -120,6 +120,8 @@ public class ProviderMeta {
|
|||
public static final String FILE_LOCK_TOKEN = "lock_token";
|
||||
public static final String FILE_TAGS = "tags";
|
||||
public static final String FILE_E2E_COUNTER = "e2e_counter";
|
||||
public static final String FILE_INTERNAL_TWO_WAY_SYNC_TIMESTAMP = "internal_two_way_sync_timestamp";
|
||||
public static final String FILE_INTERNAL_TWO_WAY_SYNC_RESULT = "internal_two_way_sync_result";
|
||||
|
||||
public static final List<String> FILE_ALL_COLUMNS = Collections.unmodifiableList(Arrays.asList(
|
||||
_ID,
|
||||
|
@ -171,7 +173,9 @@ public class ProviderMeta {
|
|||
FILE_METADATA_LIVE_PHOTO,
|
||||
FILE_E2E_COUNTER,
|
||||
FILE_TAGS,
|
||||
FILE_METADATA_GPS));
|
||||
FILE_METADATA_GPS,
|
||||
FILE_INTERNAL_TWO_WAY_SYNC_TIMESTAMP,
|
||||
FILE_INTERNAL_TWO_WAY_SYNC_RESULT));
|
||||
public static final String FILE_DEFAULT_SORT_ORDER = FILE_NAME + " collate nocase asc";
|
||||
|
||||
// Columns of ocshares table
|
||||
|
|
|
@ -697,6 +697,7 @@ public class RefreshFolderOperation extends RemoteOperation {
|
|||
if (localFile != null) {
|
||||
updatedFile.setFileId(localFile.getFileId());
|
||||
updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
|
||||
updatedFile.setInternalFolderSyncTimestamp(localFile.getInternalFolderSyncTimestamp());
|
||||
updatedFile.setModificationTimestampAtLastSyncForData(
|
||||
localFile.getModificationTimestampAtLastSyncForData()
|
||||
);
|
||||
|
|
|
@ -295,6 +295,8 @@ public class SynchronizeFileOperation extends SyncOperation {
|
|||
}
|
||||
|
||||
private void requestForDownload(OCFile file) {
|
||||
Log_OC.d("InternalTwoWaySyncWork", "download file: " + file.getFileName());
|
||||
|
||||
FileDownloadHelper.Companion.instance().downloadFile(
|
||||
mUser,
|
||||
file);
|
||||
|
|
|
@ -55,9 +55,6 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
|
||||
private static final String TAG = SynchronizeFolderOperation.class.getSimpleName();
|
||||
|
||||
/** Time stamp for the synchronization process in progress */
|
||||
private long mCurrentSyncTime;
|
||||
|
||||
/** Remote path of the folder to synchronize */
|
||||
private String mRemotePath;
|
||||
|
||||
|
@ -95,17 +92,14 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
* @param context Application context.
|
||||
* @param remotePath Path to synchronize.
|
||||
* @param user Nextcloud account where the folder is located.
|
||||
* @param currentSyncTime Time stamp for the synchronization process in progress.
|
||||
*/
|
||||
public SynchronizeFolderOperation(Context context,
|
||||
String remotePath,
|
||||
User user,
|
||||
long currentSyncTime,
|
||||
FileDataStorageManager storageManager) {
|
||||
super(storageManager);
|
||||
|
||||
mRemotePath = remotePath;
|
||||
mCurrentSyncTime = currentSyncTime;
|
||||
this.user = user;
|
||||
mContext = context;
|
||||
mRemoteFolderChanged = false;
|
||||
|
@ -365,7 +359,7 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
}
|
||||
|
||||
private void updateLocalStateData(OCFile remoteFile, OCFile localFile, OCFile updatedFile) {
|
||||
updatedFile.setLastSyncDateForProperties(mCurrentSyncTime);
|
||||
updatedFile.setLastSyncDateForProperties(System.currentTimeMillis());
|
||||
if (localFile != null) {
|
||||
updatedFile.setFileId(localFile.getFileId());
|
||||
updatedFile.setLastSyncDateForData(localFile.getLastSyncDateForData());
|
||||
|
@ -393,8 +387,19 @@ public class SynchronizeFolderOperation extends SyncOperation {
|
|||
}
|
||||
}
|
||||
|
||||
private void classifyFileForLaterSyncOrDownload(OCFile remoteFile, OCFile localFile) {
|
||||
if (!remoteFile.isFolder()) {
|
||||
@SuppressFBWarnings("JLM")
|
||||
private void classifyFileForLaterSyncOrDownload(OCFile remoteFile, OCFile localFile) throws OperationCancelledException {
|
||||
if (remoteFile.isFolder()) {
|
||||
/// to download children files recursively
|
||||
synchronized (mCancellationRequested) {
|
||||
if (mCancellationRequested.get()) {
|
||||
throw new OperationCancelledException();
|
||||
}
|
||||
startSyncFolderOperation(remoteFile.getRemotePath());
|
||||
}
|
||||
|
||||
} else {
|
||||
/// prepare content synchronization for files (any file, not just favorites)
|
||||
SynchronizeFileOperation operation = new SynchronizeFileOperation(
|
||||
localFile,
|
||||
remoteFile,
|
||||
|
|
|
@ -707,7 +707,6 @@ public class OperationsService extends Service {
|
|||
this, // TODO remove this dependency from construction time
|
||||
remotePath,
|
||||
user,
|
||||
System.currentTimeMillis(), // TODO remove this dependency from construction time
|
||||
fileDataStorageManager
|
||||
);
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Tobias Kaminsky <tobias.kaminsky@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.owncloud.android.ui.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.nextcloud.client.di.Injectable
|
||||
import com.owncloud.android.databinding.InternalTwoWaySyncLayoutBinding
|
||||
import com.owncloud.android.ui.adapter.InternalTwoWaySyncAdapter
|
||||
|
||||
class InternalTwoWaySyncActivity : BaseActivity(), Injectable {
|
||||
lateinit var binding: InternalTwoWaySyncLayoutBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
binding = InternalTwoWaySyncLayoutBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
binding.list.apply {
|
||||
adapter = InternalTwoWaySyncAdapter(fileDataStorageManager, user.get(), context)
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -171,6 +171,9 @@ public class SettingsActivity extends PreferenceActivity
|
|||
// Details
|
||||
setupDetailsCategory(preferenceScreen);
|
||||
|
||||
// Sync
|
||||
setupSyncCategory();
|
||||
|
||||
// More
|
||||
setupMoreCategory();
|
||||
|
||||
|
@ -310,13 +313,19 @@ public class SettingsActivity extends PreferenceActivity
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupSyncCategory() {
|
||||
final PreferenceCategory preferenceCategorySync = (PreferenceCategory) findPreference("sync");
|
||||
viewThemeUtils.files.themePreferenceCategory(preferenceCategorySync);
|
||||
|
||||
setupAutoUploadPreference(preferenceCategorySync);
|
||||
setupInternalTwoWaySyncPreference(preferenceCategorySync);
|
||||
}
|
||||
|
||||
private void setupMoreCategory() {
|
||||
final PreferenceCategory preferenceCategoryMore = (PreferenceCategory) findPreference("more");
|
||||
viewThemeUtils.files.themePreferenceCategory(preferenceCategoryMore);
|
||||
|
||||
setupAutoUploadPreference(preferenceCategoryMore);
|
||||
|
||||
setupCalendarPreference(preferenceCategoryMore);
|
||||
|
||||
setupBackupPreference();
|
||||
|
@ -548,6 +557,16 @@ public class SettingsActivity extends PreferenceActivity
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setupInternalTwoWaySyncPreference(PreferenceCategory preferenceCategorySync) {
|
||||
Preference twoWaySync = findPreference("internal_two_way_sync");
|
||||
|
||||
twoWaySync.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(this, InternalTwoWaySyncActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void setupBackupPreference() {
|
||||
Preference pContactsBackup = findPreference("backup");
|
||||
|
|
|
@ -424,8 +424,12 @@ public class StorageMigration {
|
|||
throw new MigrationException(R.string.file_migration_failed_dir_already_exists);
|
||||
}
|
||||
|
||||
if (dstFile.getFreeSpace() < FileStorageUtils.getFolderSize(new File(srcFile, MainApp.getDataFolder()))) {
|
||||
throw new MigrationException(R.string.file_migration_failed_not_enough_space);
|
||||
try {
|
||||
if (dstFile.getFreeSpace() < FileStorageUtils.getFolderSize(new File(srcFile, MainApp.getDataFolder()))) {
|
||||
throw new MigrationException(R.string.file_migration_failed_not_enough_space);
|
||||
}
|
||||
} catch (MigrationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Tobias Kaminsky <tobias.kaminsky@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.owncloud.android.ui.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.nextcloud.client.account.User
|
||||
import com.owncloud.android.databinding.InternalTwoWaySyncViewHolderBinding
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
|
||||
class InternalTwoWaySyncAdapter(
|
||||
dataStorageManager: FileDataStorageManager,
|
||||
user: User,
|
||||
val context: Context
|
||||
) : RecyclerView.Adapter<InternalTwoWaySyncViewHolder>() {
|
||||
var folders: List<OCFile> = dataStorageManager.getInternalTwoWaySyncFolders(user)
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): InternalTwoWaySyncViewHolder {
|
||||
return InternalTwoWaySyncViewHolder(
|
||||
InternalTwoWaySyncViewHolderBinding.inflate(
|
||||
LayoutInflater.from(parent.context),
|
||||
parent,
|
||||
false
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return folders.size
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: InternalTwoWaySyncViewHolder, position: Int) {
|
||||
holder.bind(folders[position], context)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Tobias Kaminsky <tobias.kaminsky@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.owncloud.android.ui.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.databinding.InternalTwoWaySyncViewHolderBinding
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
import com.owncloud.android.utils.DisplayUtils
|
||||
|
||||
class InternalTwoWaySyncViewHolder(val binding: InternalTwoWaySyncViewHolderBinding) :
|
||||
RecyclerView.ViewHolder(binding.root) {
|
||||
fun bind(folder: OCFile, context: Context) {
|
||||
binding.run {
|
||||
size.text = DisplayUtils.bytesToHumanReadable(folder.fileLength)
|
||||
name.text = folder.decryptedFileName
|
||||
|
||||
if (folder.internalFolderSyncResult.isEmpty()) {
|
||||
syncResult.visibility = View.GONE
|
||||
syncResultDivider.visibility = View.GONE
|
||||
} else {
|
||||
syncResult.visibility = View.VISIBLE
|
||||
syncResultDivider.visibility = View.VISIBLE
|
||||
syncResult.text = folder.internalFolderSyncResult
|
||||
}
|
||||
|
||||
if (folder.internalFolderSyncTimestamp == 0L) {
|
||||
syncTimestamp.text = context.getString(R.string.internal_two_way_sync_not_yet)
|
||||
} else {
|
||||
syncTimestamp.text = DisplayUtils.getRelativeTimestamp(
|
||||
context,
|
||||
folder.internalFolderSyncTimestamp
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -261,6 +261,7 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
|
|||
binding.favorite.setOnClickListener(this);
|
||||
binding.overflowMenu.setOnClickListener(this);
|
||||
binding.lastModificationTimestamp.setOnClickListener(this);
|
||||
binding.folderSyncButton.setOnClickListener(this);
|
||||
|
||||
updateFileDetails(false, false);
|
||||
}
|
||||
|
@ -471,8 +472,14 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
|
|||
boolean showDetailedTimestamp = !preferences.isShowDetailedTimestampEnabled();
|
||||
preferences.setShowDetailedTimestampEnabled(showDetailedTimestamp);
|
||||
setFileModificationTimestamp(getFile(), showDetailedTimestamp);
|
||||
|
||||
Log_OC.e(TAG, "Incorrect view clicked!");
|
||||
} else if (id == R.id.folder_sync_button) {
|
||||
if (binding.folderSyncButton.isChecked()) {
|
||||
getFile().setInternalFolderSyncTimestamp(0L);
|
||||
} else {
|
||||
getFile().setInternalFolderSyncTimestamp(-1L);
|
||||
}
|
||||
|
||||
storageManager.saveFile(getFile());
|
||||
} else {
|
||||
Log_OC.e(TAG, "Incorrect view clicked!");
|
||||
}
|
||||
|
@ -556,6 +563,17 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
|
|||
if (fabMain != null) {
|
||||
fabMain.hide();
|
||||
}
|
||||
|
||||
binding.syncBlock.setVisibility(file.isFolder() ? View.VISIBLE : View.GONE);
|
||||
|
||||
if (file.isInternalFolderSync()) {
|
||||
binding.folderSyncButton.setChecked(file.isInternalFolderSync());
|
||||
} else {
|
||||
if (storageManager.isPartOfInternalTwoWaySync(file)) {
|
||||
binding.folderSyncButton.setChecked(true);
|
||||
binding.folderSyncButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupViewPager();
|
||||
|
|
|
@ -170,6 +170,39 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/syncBlock"
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="@color/list_divider_background" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_padding"
|
||||
android:paddingTop="@dimen/standard_half_padding"
|
||||
android:paddingEnd="@dimen/zero"
|
||||
android:paddingBottom="@dimen/standard_half_padding">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/folder_sync_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/sync" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
|
|
18
app/src/main/res/layout/internal_two_way_sync_layout.xml
Normal file
18
app/src/main/res/layout/internal_two_way_sync_layout.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Nextcloud - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Tobias Kaminsky <tobias@kaminsky.me>
|
||||
~ SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Nextcloud - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Andy Scherzinger <info@andy-scherzinger.de>
|
||||
~ SPDX-FileCopyrightText: 2024 Tobias Kaminsky <tobias@kaminsky.me>
|
||||
~ SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/min_list_item_size"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/standard_half_padding"
|
||||
android:paddingEnd="@dimen/standard_half_padding">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/file_icon_size"
|
||||
android:layout_height="@dimen/file_icon_size"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@null"
|
||||
android:src="@drawable/folder" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/min_list_item_size"
|
||||
android:layout_marginStart="@dimen/standard_half_margin"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="middle"
|
||||
android:gravity="center_vertical"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/text_color"
|
||||
android:textSize="@dimen/two_line_primary_text_size"
|
||||
tools:text="Folder abc" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/size"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size"
|
||||
tools:text="241 Mb" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:paddingStart="@dimen/zero"
|
||||
android:paddingEnd="@dimen/standard_quarter_padding"
|
||||
android:text="@string/info_separator"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sync_timestamp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size"
|
||||
tools:text="5 min ago" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sync_result_divider"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="end"
|
||||
android:paddingStart="@dimen/zero"
|
||||
android:paddingEnd="@dimen/standard_quarter_padding"
|
||||
android:text="@string/info_separator"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sync_result"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="@color/list_item_lastmod_and_filesize_text"
|
||||
android:textSize="@dimen/two_line_secondary_text_size"
|
||||
tools:text="Success" />
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">تم استخدام %1$s من %2$s</string>
|
||||
<string name="drawer_quota_unlimited">%1$s مُسّتخدم</string>
|
||||
<string name="drawer_synced_folders">تحميل تلقائي</string>
|
||||
<string name="e2e_counter_too_old">العدَّاد قديم جداً</string>
|
||||
<string name="e2e_hash_not_found">تعذّر العثور على التجزئة hash</string>
|
||||
<string name="e2e_not_yet_setup">التشفير من الحدّ للحدّ E2E غير مُجهّز</string>
|
||||
<string name="e2e_offline">غير ممكن بدون اتصال انترنت</string>
|
||||
<string name="e2e_signature_does_not_match">التوقيع غير مُطابق</string>
|
||||
<string name="ecosystem_apps_display_assistant">المُساعِد</string>
|
||||
<string name="ecosystem_apps_display_more">المزيد</string>
|
||||
<string name="ecosystem_apps_display_notes">الملاحظات Notes</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">تحديث الفهرس…</string>
|
||||
<string name="file_migration_use_data_folder">استعمل</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">بإنتظار مزامنة كاملة…</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">اسم المجلد الحالي غير صحيح. قُم رجاءً بتغيير اسم المجلد. إعادة التوجيه إلى المجلد الجذر</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">مسار المجلد يحتوي على أسماء محجوزة أو حروف غير صالحة</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">اسم ينتهي بفراغ أو نقطة</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s امتداد ملف غير مسموحٍ به</string>
|
||||
<string name="file_name_validator_error_invalid_character">اسم يحتوي على حروف غير صالحة: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s اسم ممنوع</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. قُم رجاءً بتغيير اسم الملف قبل نقله أو نسخه</string>
|
||||
<string name="file_name_validator_upload_content_error">بعض المحتويات لا يمكن تحميلها بسبب احتوائها على أسماء محجوزة أو حروف غير صالحة</string>
|
||||
<string name="file_not_found">تعذر العثور على الملف</string>
|
||||
<string name="file_not_synced">الملف لا يمكن مزامنته. عرض آخر إصدار متوفر.</string>
|
||||
<string name="file_rename">إعادة التسمية</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">المجلد موجود مسبقاً</string>
|
||||
<string name="folder_confirm_create">إنشاء</string>
|
||||
<string name="folder_list_empty_headline">لا توجد مجلدات</string>
|
||||
<string name="folder_name_empty">اسم المجلد لا يمكن أن يكون فارغاً</string>
|
||||
<string name="folder_picker_choose_button_text">إختَر</string>
|
||||
<string name="folder_picker_choose_caption_text">اختر مكان المجلد</string>
|
||||
<string name="folder_picker_copy_button_text">إنسَخ</string>
|
||||
|
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">%1$s of %2$s used</string>
|
||||
<string name="drawer_quota_unlimited">%1$s used</string>
|
||||
<string name="drawer_synced_folders">Auto upload</string>
|
||||
<string name="e2e_counter_too_old">Counter is too old</string>
|
||||
<string name="e2e_hash_not_found">Hash not found</string>
|
||||
<string name="e2e_not_yet_setup">E2E not yet setup</string>
|
||||
<string name="e2e_offline">Not possible without internet connection</string>
|
||||
<string name="e2e_signature_does_not_match">Signature does not match</string>
|
||||
<string name="ecosystem_apps_display_assistant">Assistant</string>
|
||||
<string name="ecosystem_apps_display_more">More</string>
|
||||
<string name="ecosystem_apps_display_notes">Notes</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">Updating index…</string>
|
||||
<string name="file_migration_use_data_folder">Use</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">Awaiting full sync…</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">Current folder name is invalid, please rename the folder. Redirecting to root</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">Folder path contains reserved names or invalid character</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">Name ends with a space or a period</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s is a forbidden file extension</string>
|
||||
<string name="file_name_validator_error_invalid_character">Name contains an invalid character: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s is a forbidden name</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Please rename the file before moving or copying</string>
|
||||
<string name="file_name_validator_upload_content_error">Some contents cannot able to uploaded due to contains reserved names or invalid character</string>
|
||||
<string name="file_not_found">File not found</string>
|
||||
<string name="file_not_synced">File could not be synced. Showing latest available version.</string>
|
||||
<string name="file_rename">Rename</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">Folder already exists</string>
|
||||
<string name="folder_confirm_create">Create</string>
|
||||
<string name="folder_list_empty_headline">No folders here</string>
|
||||
<string name="folder_name_empty">Folder name cannot be empty</string>
|
||||
<string name="folder_picker_choose_button_text">Choose</string>
|
||||
<string name="folder_picker_choose_caption_text">Choose target folder</string>
|
||||
<string name="folder_picker_copy_button_text">Copy</string>
|
||||
|
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">%1$s von %2$s verwendet</string>
|
||||
<string name="drawer_quota_unlimited">%1$s verwendet</string>
|
||||
<string name="drawer_synced_folders">Automatisches Hochladen</string>
|
||||
<string name="e2e_counter_too_old">Zähler ist zu alt</string>
|
||||
<string name="e2e_hash_not_found">Hash nicht gefunden</string>
|
||||
<string name="e2e_not_yet_setup">E2E bislang nicht eingerichtet</string>
|
||||
<string name="e2e_offline">Ohne Internetverbindung nicht möglich</string>
|
||||
<string name="e2e_signature_does_not_match">Signatur stimmt nicht überein</string>
|
||||
<string name="ecosystem_apps_display_assistant">Assistent</string>
|
||||
<string name="ecosystem_apps_display_more">Mehr</string>
|
||||
<string name="ecosystem_apps_display_notes">Notizen</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">Aktualisiere Index…</string>
|
||||
<string name="file_migration_use_data_folder">Verwende bestehenden</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">Warte auf die Fertigstellung aller Synchronisierungen …</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">Der aktuelle Ordnername ist ungültig. Bitte benennen Sie den Ordner um. Weiterleitung zum Stammverzeichnis</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">Der Ordnerpfad enthält reservierte Namen oder ungültige Zeichen</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">Der Name endet mit einem Leerzeichen oder einem Punkt</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s ist eine verbotene Dateierweiterung</string>
|
||||
<string name="file_name_validator_error_invalid_character">Der Name enthält ein ungültiges Zeichen: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s ist ein verbotener Name</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Bitte Datei umbenennen, bevor diese verschoben oder kopiert wird</string>
|
||||
<string name="file_name_validator_upload_content_error">Einige Inhalte können nicht hochgeladen werden, da sie reservierte Namen oder ungültige Zeichen enthalten</string>
|
||||
<string name="file_not_found">Datei nicht gefunden</string>
|
||||
<string name="file_not_synced">Die gewünschte Datei konnte nicht synchronisiert werden. Die letzte verfügbare Version wird angezeigt. </string>
|
||||
<string name="file_rename">Umbenennen</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">Ordner existiert bereits</string>
|
||||
<string name="folder_confirm_create">Erstellen</string>
|
||||
<string name="folder_list_empty_headline">Keine Ordner vorhanden</string>
|
||||
<string name="folder_name_empty">Der Ordnername darf nicht leer sein</string>
|
||||
<string name="folder_picker_choose_button_text">Auswählen</string>
|
||||
<string name="folder_picker_choose_caption_text">Zielordner auswählen</string>
|
||||
<string name="folder_picker_copy_button_text">Kopieren</string>
|
||||
|
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">Usado %1$s de %2$s</string>
|
||||
<string name="drawer_quota_unlimited">Usado %1$s</string>
|
||||
<string name="drawer_synced_folders">Envío automático</string>
|
||||
<string name="e2e_counter_too_old">O contador é demasiado antigo</string>
|
||||
<string name="e2e_hash_not_found">Non se atopou o resumo criptográfico</string>
|
||||
<string name="e2e_not_yet_setup">E2E aínda non está configurado</string>
|
||||
<string name="e2e_offline">Non é posíbel sen conexión a internet</string>
|
||||
<string name="e2e_signature_does_not_match">A sinatura non coincide</string>
|
||||
<string name="ecosystem_apps_display_assistant">Asistente</string>
|
||||
<string name="ecosystem_apps_display_more">Máis</string>
|
||||
<string name="ecosystem_apps_display_notes">Notas</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">Actualizando o índice…</string>
|
||||
<string name="file_migration_use_data_folder">Usar</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">Agardando que rematen as sincronizacións…</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">O nome actual do cartafol non é válido, cambie o nome do cartafol. Redireccionando á raíz</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">A ruta do cartafol contén nomes reservados ou caracteres non válidos</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">O nome remata cun espazo ou un punto</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s é unha extensión de ficheiro prohibida.</string>
|
||||
<string name="file_name_validator_error_invalid_character">O nome contén un carácter non válido: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s é un nome prohibido.</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Cambie o nome do ficheiro antes de mover ou copiar</string>
|
||||
<string name="file_name_validator_upload_content_error">Non é posíbel enviar algúns contidos porque conteñen nomes reservados ou caracteres non válidos</string>
|
||||
<string name="file_not_found">Non se atopou o ficheiro</string>
|
||||
<string name="file_not_synced">Non foi posíbel sincronizar o ficheiro. Amosase a última versión dispoñíbel.</string>
|
||||
<string name="file_rename">Cambiar o nome</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">Xa existe o cartafol</string>
|
||||
<string name="folder_confirm_create">Crear</string>
|
||||
<string name="folder_list_empty_headline">Aquí non hai cartafoles</string>
|
||||
<string name="folder_name_empty">O nome do cartafol non pode estar baleiro</string>
|
||||
<string name="folder_picker_choose_button_text">Escoller</string>
|
||||
<string name="folder_picker_choose_caption_text">Escoller o cartafol de destino</string>
|
||||
<string name="folder_picker_copy_button_text">Copiar</string>
|
||||
|
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">%1$s av %2$s brukt</string>
|
||||
<string name="drawer_quota_unlimited">%1$s brukt</string>
|
||||
<string name="drawer_synced_folders">Auto-opplasting</string>
|
||||
<string name="e2e_counter_too_old">Telleren er for gammel</string>
|
||||
<string name="e2e_hash_not_found">Hash ikke funnet</string>
|
||||
<string name="e2e_not_yet_setup">E2E er ikke satt opp enda</string>
|
||||
<string name="e2e_offline">Ikke mulig uten internettilkobling</string>
|
||||
<string name="e2e_signature_does_not_match">Signatur samsvarer ikke</string>
|
||||
<string name="ecosystem_apps_display_assistant">Assistent</string>
|
||||
<string name="ecosystem_apps_display_more">Mer</string>
|
||||
<string name="ecosystem_apps_display_notes">Notater</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">Oppdaterer indeks…</string>
|
||||
<string name="file_migration_use_data_folder">Bruk</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">Venter på full synkronisering…</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">Gjeldende mappenavn er ugyldig, vennligst gi nytt navn til mappen. Omdirigerer til rot</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">Mappebanen inneholder reserverte navn eller ugyldige tegn</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">Navn slutter med et mellomrom eller et punktum</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s er en forbudt filtype</string>
|
||||
<string name="file_name_validator_error_invalid_character">Navnet inneholder et ugyldig tegn: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s er et forbudt navn</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Gi nytt navn til filen før du flytter eller kopierer</string>
|
||||
<string name="file_name_validator_upload_content_error">Noe innhold kan ikke lastes opp på grunn av inneholder reserverte navn eller ugyldige tegn</string>
|
||||
<string name="file_not_found">Finner ikke filen</string>
|
||||
<string name="file_not_synced">Kunne ikke synkronisere fil. Viser sist tilgjengelige versjon.</string>
|
||||
<string name="file_rename">Gi nytt navn</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">Mappe finnes allerede</string>
|
||||
<string name="folder_confirm_create">Opprett</string>
|
||||
<string name="folder_list_empty_headline">Ingen mapper her</string>
|
||||
<string name="folder_name_empty">Mappenavnet kan ikke være tomt</string>
|
||||
<string name="folder_picker_choose_button_text">Velg</string>
|
||||
<string name="folder_picker_choose_caption_text">Velg målmappe</string>
|
||||
<string name="folder_picker_copy_button_text">Kopi</string>
|
||||
|
|
|
@ -279,8 +279,10 @@
|
|||
<string name="drawer_quota">%1$s av %2$s använt</string>
|
||||
<string name="drawer_quota_unlimited">%1$s använt</string>
|
||||
<string name="drawer_synced_folders">Automatisk uppladdning</string>
|
||||
<string name="e2e_hash_not_found">Hash kunde inte hittas</string>
|
||||
<string name="e2e_not_yet_setup">E2E ej inställt än</string>
|
||||
<string name="e2e_offline">Inte möjligt utan internetuppkoppling</string>
|
||||
<string name="e2e_signature_does_not_match">Signaturen matchar inte</string>
|
||||
<string name="ecosystem_apps_display_assistant">Assistent</string>
|
||||
<string name="ecosystem_apps_display_more">Mer</string>
|
||||
<string name="ecosystem_apps_display_notes">Anteckning</string>
|
||||
|
@ -406,6 +408,14 @@
|
|||
<string name="file_migration_updating_index">Uppdaterar index…</string>
|
||||
<string name="file_migration_use_data_folder">Använd</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">Väntar på fullständig synkronisering…</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">Aktuellt mappnamn är ogiltigt. Byt namn på mappen. Omdirigerar till root</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">Mappsökvägen innehåller reserverade namn eller ogiltiga tecken</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">Namnet slutar med ett mellanslag eller en punkt</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s är ett förbjudet filtillägg</string>
|
||||
<string name="file_name_validator_error_invalid_character">Namnet innehåller ett ogiltigt tecken: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s är ett förbjudet namn</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Byt namn på filen innan du flyttar eller kopierar</string>
|
||||
<string name="file_name_validator_upload_content_error">En del innehåll kan inte laddas upp på grund av att det innehåller reserverade namn eller ogiltiga tecken</string>
|
||||
<string name="file_not_found">Filen hittades inte</string>
|
||||
<string name="file_not_synced">Filen kunde inte synkroniseras. Visar senaste tillgängliga versionen.</string>
|
||||
<string name="file_rename">Byt namn</string>
|
||||
|
@ -429,6 +439,7 @@
|
|||
<string name="folder_already_exists">Mapp finns redan</string>
|
||||
<string name="folder_confirm_create">Skapa</string>
|
||||
<string name="folder_list_empty_headline">Inga mappar här</string>
|
||||
<string name="folder_name_empty">Mappnamnet får inte vara tomt</string>
|
||||
<string name="folder_picker_choose_button_text">Välj</string>
|
||||
<string name="folder_picker_choose_caption_text">Välj målmapp</string>
|
||||
<string name="folder_picker_copy_button_text">Kopiera</string>
|
||||
|
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">%1$s / %2$s kullanıldı</string>
|
||||
<string name="drawer_quota_unlimited">%1$s kullanılıyor</string>
|
||||
<string name="drawer_synced_folders">Otomatik yükleme</string>
|
||||
<string name="e2e_counter_too_old">Sayaç çok eski</string>
|
||||
<string name="e2e_hash_not_found">Karma bulunamadı</string>
|
||||
<string name="e2e_not_yet_setup">Uçtan uca şifreleme henüz kurulmamış</string>
|
||||
<string name="e2e_offline">İnternet bağlantısı olmadan yapılamaz</string>
|
||||
<string name="e2e_signature_does_not_match">İmza eşleşmiyor</string>
|
||||
<string name="ecosystem_apps_display_assistant">Yardımcı</string>
|
||||
<string name="ecosystem_apps_display_more">Diğer</string>
|
||||
<string name="ecosystem_apps_display_notes">Notlar</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">Dizin güncelleniyor …</string>
|
||||
<string name="file_migration_use_data_folder">Kullanılsın</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">Eşitleme işleminin tamamlanması bekleniyor …</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">Geçerli klasör adı geçersiz. Lütfen klasörü yeniden adlandırın. Kök klasöre yönlendiriliyorsunuz.</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">Klasör yolunda ayrılmış adlar veya geçersiz karakterler var</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">Ad bir boşluk ya da nokta ile bitiyor</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s dosya uzantısına izin verilmiyor.</string>
|
||||
<string name="file_name_validator_error_invalid_character">Ad içinde geçersiz bir karakter var: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s adına izin verilmiyor</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Kopyalamadan ya da taşımadan önce lütfen dosyayı yeniden adlandırın</string>
|
||||
<string name="file_name_validator_upload_content_error">Bazı içerikler, içinde ayrılmış adlar veya geçersiz karakterler bulunduğundan yüklenemedi</string>
|
||||
<string name="file_not_found">Dosya bulunamadı</string>
|
||||
<string name="file_not_synced">Dosya eşitlenemedi. Kullanılabilen son sürüm görüntüleniyor.</string>
|
||||
<string name="file_rename">Yeniden adlandır</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">Klasör zaten var</string>
|
||||
<string name="folder_confirm_create">Ekle</string>
|
||||
<string name="folder_list_empty_headline">Burada herhangi bir klasör yok</string>
|
||||
<string name="folder_name_empty">Klasör adı boş olamaz</string>
|
||||
<string name="folder_picker_choose_button_text">Seçin</string>
|
||||
<string name="folder_picker_choose_caption_text">Hedef klasörü seçin</string>
|
||||
<string name="folder_picker_copy_button_text">Kopyala</string>
|
||||
|
|
|
@ -278,8 +278,11 @@
|
|||
<string name="drawer_quota">Використано %1$s із %2$s</string>
|
||||
<string name="drawer_quota_unlimited">%1$sвикористано</string>
|
||||
<string name="drawer_synced_folders">Автоматичне завантаження</string>
|
||||
<string name="e2e_counter_too_old">Лічильний застарілий</string>
|
||||
<string name="e2e_hash_not_found">Не знайдено</string>
|
||||
<string name="e2e_not_yet_setup">Наскрізне шифруванння ще не налаштовано</string>
|
||||
<string name="e2e_offline">Дія не можлива без доступу до з\'єднання з мережею</string>
|
||||
<string name="e2e_signature_does_not_match">Підпис не збігається</string>
|
||||
<string name="ecosystem_apps_display_assistant">Помічник</string>
|
||||
<string name="ecosystem_apps_display_more">Більше</string>
|
||||
<string name="ecosystem_apps_display_notes">Нотатки</string>
|
||||
|
@ -365,6 +368,7 @@
|
|||
<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_local_search">Не знайдено файли або каталоги згідно із запитом</string>
|
||||
<string name="file_list_empty_moving">Тут нічого немає. Ви можете створити каталог.</string>
|
||||
<string name="file_list_empty_on_device">Тут ти можете знайти каталоги та файли, які було звантажено.</string>
|
||||
<string name="file_list_empty_recently_modified">Відсутні зміни серед файлів за останні 7 днів</string>
|
||||
|
@ -402,6 +406,14 @@
|
|||
<string name="file_migration_updating_index">Оновлення індексу...</string>
|
||||
<string name="file_migration_use_data_folder">Використовувати</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">Очікування повної синхронізації…</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">Перейменуйте назву поточого каталогу, оскільки його назва не є дійсною. Переспрямування до кореневого каталогу.</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">Шлях до каталогу містить зарезервовані імена або недійсні символи</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">Ім\'я закінчується на символ пробілу або крапку</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s не є дозволеним розширенням файлу</string>
|
||||
<string name="file_name_validator_error_invalid_character">Ім\'я містить недійсний символ: %s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s не є дозволеним ім\'ям</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Перейменуйте файл перед переміщенням або копіюванням</string>
|
||||
<string name="file_name_validator_upload_content_error">Окремі дані неможливо завантажити, оскільки він містить зарезервовані імена або недійсні символи</string>
|
||||
<string name="file_not_found">Файл не знайдено</string>
|
||||
<string name="file_not_synced">Неможливо синхронізувати файл. Буде показано останню доступну версію.</string>
|
||||
<string name="file_rename">Перейменувати</string>
|
||||
|
@ -425,6 +437,7 @@
|
|||
<string name="folder_already_exists">Каталог вже існує</string>
|
||||
<string name="folder_confirm_create">Створити</string>
|
||||
<string name="folder_list_empty_headline">Тут відсутні каталоги</string>
|
||||
<string name="folder_name_empty">Ім\'я каталогу не може бути порожнім</string>
|
||||
<string name="folder_picker_choose_button_text">Вибрати</string>
|
||||
<string name="folder_picker_choose_caption_text">Виберіть каталог призначення</string>
|
||||
<string name="folder_picker_copy_button_text">Копія</string>
|
||||
|
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">已用 %2$s 中的 %1$s</string>
|
||||
<string name="drawer_quota_unlimited">使用了 %1$s 的存儲空間</string>
|
||||
<string name="drawer_synced_folders">自動上傳</string>
|
||||
<string name="e2e_counter_too_old">計數器太舊</string>
|
||||
<string name="e2e_hash_not_found">未找到哈希值</string>
|
||||
<string name="e2e_not_yet_setup">尚未設定端到端加密</string>
|
||||
<string name="e2e_offline">沒有互聯網連接無法使用</string>
|
||||
<string name="e2e_signature_does_not_match">簽名不相符</string>
|
||||
<string name="ecosystem_apps_display_assistant">助手</string>
|
||||
<string name="ecosystem_apps_display_more">更多</string>
|
||||
<string name="ecosystem_apps_display_notes">備註</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">更新索引中…</string>
|
||||
<string name="file_migration_use_data_folder">使用</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">等待完整同步…</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">目前資料夾名稱無效,請重新命名該資料夾。重定向到根目錄</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">資料夾途徑包含保留名稱或無效字符</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">名稱以空格或句點結尾。</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">「.%s」是禁止使用的副檔名。</string>
|
||||
<string name="file_name_validator_error_invalid_character">名字含有無效的字元:「%s」。</string>
|
||||
<string name="file_name_validator_error_reserved_names">「%s」是禁止使用的名字。</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s。請在移動或複製之前重新命名檔案</string>
|
||||
<string name="file_name_validator_upload_content_error">部分內容因包含保留名稱或無效字元而無法上傳</string>
|
||||
<string name="file_not_found">找不到檔案</string>
|
||||
<string name="file_not_synced">檔案不能同步,將顯示最新可用版本。</string>
|
||||
<string name="file_rename">更名</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">文件夾已存在</string>
|
||||
<string name="folder_confirm_create">建立</string>
|
||||
<string name="folder_list_empty_headline">這裡沒有資料夾</string>
|
||||
<string name="folder_name_empty">資料夾名稱不能為空</string>
|
||||
<string name="folder_picker_choose_button_text">選擇</string>
|
||||
<string name="folder_picker_choose_caption_text">選擇目標資料夾</string>
|
||||
<string name="folder_picker_copy_button_text">複製</string>
|
||||
|
|
|
@ -279,8 +279,11 @@
|
|||
<string name="drawer_quota">在 %2$s中使用了%1$s </string>
|
||||
<string name="drawer_quota_unlimited">%1$s已使用</string>
|
||||
<string name="drawer_synced_folders">自動上傳</string>
|
||||
<string name="e2e_counter_too_old">計數器太舊</string>
|
||||
<string name="e2e_hash_not_found">找不到雜湊值</string>
|
||||
<string name="e2e_not_yet_setup">尚未設定端到端加密</string>
|
||||
<string name="e2e_offline">沒有網際網路連線就無法使用</string>
|
||||
<string name="e2e_signature_does_not_match">簽章不相符</string>
|
||||
<string name="ecosystem_apps_display_assistant">助理</string>
|
||||
<string name="ecosystem_apps_display_more">更多</string>
|
||||
<string name="ecosystem_apps_display_notes">筆記</string>
|
||||
|
@ -406,6 +409,14 @@
|
|||
<string name="file_migration_updating_index">正在更新索引……</string>
|
||||
<string name="file_migration_use_data_folder">使用</string>
|
||||
<string name="file_migration_waiting_for_unfinished_sync">正在等待完全同步……</string>
|
||||
<string name="file_name_validator_current_path_is_invalid">目前資料夾名稱無效,請重新命名資料夾。重新導向至根目錄</string>
|
||||
<string name="file_name_validator_error_contains_reserved_names_or_invalid_characters">資料夾路徑包含保留名稱或無效字元</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">名稱以空格或句點結尾</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s 是禁止使用的副檔名</string>
|
||||
<string name="file_name_validator_error_invalid_character">名稱包含無效的字元:%s</string>
|
||||
<string name="file_name_validator_error_reserved_names">%s 是禁止的名稱</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s。請在移動或複製前重新命名檔案</string>
|
||||
<string name="file_name_validator_upload_content_error">部份內容包含保留名稱或無效字元而無法上傳</string>
|
||||
<string name="file_not_found">找不到檔案</string>
|
||||
<string name="file_not_synced">檔案無法同步,將顯示最新可用版本。</string>
|
||||
<string name="file_rename">重新命名</string>
|
||||
|
@ -429,6 +440,7 @@
|
|||
<string name="folder_already_exists">資料夾已存在</string>
|
||||
<string name="folder_confirm_create">建立</string>
|
||||
<string name="folder_list_empty_headline">這裡沒有資料夾</string>
|
||||
<string name="folder_name_empty">資料夾名稱不能為空</string>
|
||||
<string name="folder_picker_choose_button_text">選擇</string>
|
||||
<string name="folder_picker_choose_caption_text">選擇目標資料夾</string>
|
||||
<string name="folder_picker_copy_button_text">複製</string>
|
||||
|
|
|
@ -1218,13 +1218,15 @@
|
|||
<string name="sub_folder_rule_day">Year/Month/Day</string>
|
||||
<string name="secure_share_not_set_up">Secure sharing is not set up for this user</string>
|
||||
<string name="share_not_allowed_when_file_drop">Resharing is not allowed during secure file drop</string>
|
||||
<string name="prefs_category_sync">Sync</string>
|
||||
<string name="internal_two_way_sync">Internal two way sync</string>
|
||||
<string name="prefs_two_way_sync_summary">Manage internal folders for two way sync</string>
|
||||
<string name="internal_two_way_sync_not_yet">Not yet, soon to be synced</string>
|
||||
<string name="gplay_restriction">Google restricted downloading APK/AAB files!</string>
|
||||
<string name="file_list_empty_local_search">No file or folder matching your search</string>
|
||||
|
||||
<string name="unified_search_fragment_calendar_event_not_found">Event not found, you can always sync to update. Redirecting to web…</string>
|
||||
<string name="unified_search_fragment_contact_not_found">Contact not found, you can always sync to update. Redirecting to web…</string>
|
||||
<string name="unified_search_fragment_permission_needed">Permissions are required to open search result otherwise it will redirected to web…</string>
|
||||
|
||||
<string name="file_name_validator_current_path_is_invalid">Current folder name is invalid, please rename the folder. Redirecting to root</string>
|
||||
<string name="file_name_validator_rename_before_move_or_copy">%s. Please rename the file before moving or copying</string>
|
||||
<string name="file_name_validator_upload_content_error">Some contents cannot able to uploaded due to contains reserved names or invalid character</string>
|
||||
|
@ -1233,4 +1235,5 @@
|
|||
<string name="file_name_validator_error_reserved_names">%s is a forbidden name</string>
|
||||
<string name="file_name_validator_error_forbidden_file_extensions">.%s is a forbidden file extension</string>
|
||||
<string name="file_name_validator_error_ends_with_space_period">Name ends with a space or a period</string>
|
||||
<string name="sync">Sync</string>
|
||||
</resources>
|
||||
|
|
|
@ -53,13 +53,23 @@
|
|||
android:key="show_media_scan_notifications"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/prefs_category_sync"
|
||||
android:key="sync">
|
||||
<Preference
|
||||
android:title="@string/drawer_synced_folders"
|
||||
android:key="syncedFolders"
|
||||
android:summary="@string/prefs_sycned_folders_summary" />
|
||||
|
||||
<Preference
|
||||
android:title="@string/internal_two_way_sync"
|
||||
android:key="internal_two_way_sync"
|
||||
android:summary="@string/prefs_two_way_sync_summary" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/prefs_category_more"
|
||||
android:key="more">
|
||||
<Preference
|
||||
android:title="@string/drawer_synced_folders"
|
||||
android:key="syncedFolders"
|
||||
android:summary="@string/prefs_sycned_folders_summary" />
|
||||
<Preference
|
||||
android:title="@string/prefs_calendar_contacts"
|
||||
android:key="calendar_contacts"
|
||||
|
|
Loading…
Reference in a new issue