mirror of
https://github.com/nextcloud/android.git
synced 2024-12-19 23:42:03 +03:00
Merge remote-tracking branch 'origin/master' into dev
This commit is contained in:
commit
e0af72d32a
109 changed files with 1015 additions and 476 deletions
|
@ -1,4 +1,4 @@
|
|||
FROM ubuntu:noble@sha256:99c35190e22d294cdace2783ac55effc69d32896daaa265f0bbedbcde4fbe3e5
|
||||
FROM ubuntu:noble@sha256:278628f08d4979fb9af9ead44277dbc9c92c2465922310916ad0c46ec9999295
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ENV ANDROID_HOME=/usr/lib/android-sdk
|
||||
|
|
|
@ -9,7 +9,7 @@ name: tests-stable
|
|||
|
||||
steps:
|
||||
- name: gplay
|
||||
image: ghcr.io/nextcloud/continuous-integration-android8:3
|
||||
image: ghcr.io/nextcloud/continuous-integration-android8:4
|
||||
privileged: true
|
||||
environment:
|
||||
LOG_USERNAME:
|
||||
|
@ -132,7 +132,7 @@ name: allScreenshots
|
|||
|
||||
steps:
|
||||
- name: runAllScreenshots
|
||||
image: ghcr.io/nextcloud/continuous-integration-android8:3
|
||||
image: ghcr.io/nextcloud/continuous-integration-android8:4
|
||||
privileged: true
|
||||
environment:
|
||||
GIT_USERNAME:
|
||||
|
@ -183,6 +183,6 @@ name: GIT_TOKEN
|
|||
data: XIoa9IYq+xQ+N5iln8dlpWv0jV6ROr7HuE24ioUr4uQ8m8SjyH0yognWYLYLqnbTKrFWlFZiEMQTH/sZiWjRFvV1iL0=
|
||||
---
|
||||
kind: signature
|
||||
hmac: 8aeb253a66781661eee55fd4111a40a2fe222f5bfec35f2f3a7775e3d6db6b09
|
||||
hmac: f0d3fa25f7f901e8b3deacec52db0d5a81f05f7d4f13af27c633ad712ecdbc4d
|
||||
|
||||
...
|
||||
|
|
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
|
@ -39,7 +39,7 @@ jobs:
|
|||
with:
|
||||
swap-size-gb: 10
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4
|
||||
uses: github/codeql-action/init@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
- name: Set up JDK 17
|
||||
|
@ -53,4 +53,4 @@ jobs:
|
|||
echo "org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties"
|
||||
./gradlew assembleDebug
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4
|
||||
uses: github/codeql-action/analyze@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
||||
|
|
2
.github/workflows/scorecard.yml
vendored
2
.github/workflows/scorecard.yml
vendored
|
@ -42,6 +42,6 @@ jobs:
|
|||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@ea9e4e37992a54ee68a9622e985e60c8e8f12d9f # v3.27.4
|
||||
uses: github/codeql-action/upload-sarif@f09c1c0a94de965c15400f5634aa42fac8fb8f88 # v3.27.5
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
2
.github/workflows/unit-tests.yml
vendored
2
.github/workflows/unit-tests.yml
vendored
|
@ -42,7 +42,7 @@ jobs:
|
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: scripts/uploadReport.sh "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" ${{github.event.number}} "test" "Unit" ${{github.event.number}}
|
||||
- name: Upload coverage to codecov
|
||||
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
|
||||
uses: codecov/codecov-action@985343d70564a82044c1b7fcb84c2fa05405c1a2 # v5.0.4
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
flags: unit
|
||||
|
|
|
@ -412,7 +412,7 @@ dependencies {
|
|||
implementation "com.github.stateless4j:stateless4j:2.6.0"
|
||||
|
||||
// upon each update first test: new registration, receive push
|
||||
gplayImplementation "com.google.firebase:firebase-messaging:24.0.2"
|
||||
gplayImplementation "com.google.firebase:firebase-messaging:24.1.0"
|
||||
gplayImplementation 'com.google.android.gms:play-services-base:18.5.0'
|
||||
gplayImplementation 'com.google.android.play:review-ktx:2.0.2'
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 34 KiB |
Binary file not shown.
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 34 KiB |
|
@ -155,43 +155,43 @@ class FileDisplayActivityIT : AbstractOnServerIT() {
|
|||
Assert.assertEquals(storageManager.getFileByPath("/"), sut.currentDir)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun checkToolbarTitleOnNavigation() {
|
||||
// Create folder structure
|
||||
val topFolder = "folder1"
|
||||
val childFolder = "folder2"
|
||||
|
||||
CreateFolderOperation("/$topFolder/", user, targetContext, storageManager)
|
||||
.execute(client)
|
||||
|
||||
CreateFolderOperation("/$topFolder/$childFolder/", user, targetContext, storageManager)
|
||||
.execute(client)
|
||||
|
||||
activityRule.launchActivity(null)
|
||||
|
||||
shortSleep()
|
||||
|
||||
// go into "foo"
|
||||
onView(withText(topFolder)).perform(click())
|
||||
shortSleep()
|
||||
|
||||
// check title is right
|
||||
checkToolbarTitle(topFolder)
|
||||
|
||||
// go into "bar"
|
||||
onView(withText(childFolder)).perform(click())
|
||||
shortSleep()
|
||||
|
||||
// check title is right
|
||||
checkToolbarTitle(childFolder)
|
||||
|
||||
// browse back up, we should be back in "foo"
|
||||
Espresso.pressBack()
|
||||
shortSleep()
|
||||
|
||||
// check title is right
|
||||
checkToolbarTitle(topFolder)
|
||||
}
|
||||
// @Test
|
||||
// fun checkToolbarTitleOnNavigation() {
|
||||
// // Create folder structure
|
||||
// val topFolder = "folder1"
|
||||
// val childFolder = "folder2"
|
||||
//
|
||||
// CreateFolderOperation("/$topFolder/", user, targetContext, storageManager)
|
||||
// .execute(client)
|
||||
//
|
||||
// CreateFolderOperation("/$topFolder/$childFolder/", user, targetContext, storageManager)
|
||||
// .execute(client)
|
||||
//
|
||||
// activityRule.launchActivity(null)
|
||||
//
|
||||
// shortSleep()
|
||||
//
|
||||
// // go into "foo"
|
||||
// onView(withText(topFolder)).perform(click())
|
||||
// shortSleep()
|
||||
//
|
||||
// // check title is right
|
||||
// checkToolbarTitle(topFolder)
|
||||
//
|
||||
// // go into "bar"
|
||||
// onView(withText(childFolder)).perform(click())
|
||||
// shortSleep()
|
||||
//
|
||||
// // check title is right
|
||||
// checkToolbarTitle(childFolder)
|
||||
//
|
||||
// // browse back up, we should be back in "foo"
|
||||
// Espresso.pressBack()
|
||||
// shortSleep()
|
||||
//
|
||||
// // check title is right
|
||||
// checkToolbarTitle(topFolder)
|
||||
// }
|
||||
|
||||
private fun checkToolbarTitle(childFolder: String) {
|
||||
onView(withId(R.id.appbar)).check(
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.utils
|
||||
|
||||
import android.os.Bundle
|
||||
import com.owncloud.android.AbstractIT
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
|
||||
import com.owncloud.android.utils.appConfig.AppConfigKeys
|
||||
import com.owncloud.android.utils.appConfig.AppConfigManager
|
||||
import org.junit.AfterClass
|
||||
import org.junit.Test
|
||||
|
||||
class AppConfigManagerTests : AbstractIT() {
|
||||
|
||||
private val testBaseUrl = "nextcloud.cloud.cloud"
|
||||
private val testProxyHost = "nextcloud.cloud.cloud.com"
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private val testProxyPort = 8800
|
||||
|
||||
@Test
|
||||
fun testSetProxyConfigWhenGivenClientBrandedPlusAndCorrectBundleDataProxyConfigurationShouldSet() {
|
||||
val proxySetting = Bundle().apply {
|
||||
putString(AppConfigKeys.ProxyHost.key, testProxyHost)
|
||||
putInt(AppConfigKeys.ProxyPort.key, testProxyPort)
|
||||
}
|
||||
|
||||
AppConfigManager(targetContext, proxySetting).run {
|
||||
setProxyConfig(true)
|
||||
}
|
||||
|
||||
val proxyHost = OwnCloudClientManagerFactory.getProxyHost()
|
||||
val proxyPort = OwnCloudClientManagerFactory.getProxyPort()
|
||||
|
||||
assert(proxyHost.equals(testProxyHost))
|
||||
assert(proxyPort == testProxyPort)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetProxyConfigWhenGivenClientNotBrandedPlusAndCorrectBundleDataProxyConfigurationShouldNotSet() {
|
||||
val proxySetting = Bundle().apply {
|
||||
putString(AppConfigKeys.ProxyHost.key, testProxyHost)
|
||||
putInt(AppConfigKeys.ProxyPort.key, testProxyPort)
|
||||
}
|
||||
|
||||
AppConfigManager(targetContext, proxySetting).run {
|
||||
setProxyConfig(false)
|
||||
}
|
||||
|
||||
val proxyHost = OwnCloudClientManagerFactory.getProxyHost()
|
||||
val proxyPort = OwnCloudClientManagerFactory.getProxyPort()
|
||||
|
||||
assert(proxyHost.equals(""))
|
||||
assert(proxyPort == -1)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetBaseUrlConfigWhenGivenClientBrandedPlusAndCorrectBundleDataBaseUrlConfigurationShouldSet() {
|
||||
val baseUrlConfig = Bundle().apply {
|
||||
putString(AppConfigKeys.BaseUrl.key, testBaseUrl)
|
||||
}
|
||||
val sut = AppConfigManager(targetContext, baseUrlConfig)
|
||||
assert(!sut.getBaseUrl(true).isNullOrEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetBaseUrlConfigWhenGivenClientBrandedPlusAndBrokenBundleDataBaseUrlConfigurationShouldNotSet() {
|
||||
val baseUrlConfig = Bundle()
|
||||
val sut = AppConfigManager(targetContext, baseUrlConfig)
|
||||
assert(sut.getBaseUrl(true).isNullOrEmpty())
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
@AfterClass
|
||||
fun tearDown() {
|
||||
OwnCloudClientManagerFactory.setProxyHost("")
|
||||
OwnCloudClientManagerFactory.setProxyPort(-1)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -167,4 +167,12 @@ class AutoRenameTests : AbstractOnServerIT() {
|
|||
val expectedFolderName = "/COm02/2569.webp"
|
||||
assert(result == expectedFolderName) { "Expected $expectedFolderName but got $result" }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testValidFilename() {
|
||||
val filename = ".file.TXT"
|
||||
val result = AutoRename.rename(filename, capability)
|
||||
val expectedFilename = "_file.txt"
|
||||
assert(result == expectedFilename) { "Expected $expectedFilename but got $result" }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,6 +313,11 @@
|
|||
android:name=".ui.activity.ContactsPreferenceActivity"
|
||||
android:exported="false"
|
||||
android:launchMode="singleInstance" />
|
||||
<activity
|
||||
android:name=".ui.activity.ChooseStorageLocationActivity"
|
||||
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
|
||||
android:exported="false"
|
||||
android:theme="@style/Theme.NoBackground" />
|
||||
<activity
|
||||
android:name=".ui.activity.ReceiveExternalFilesActivity"
|
||||
android:excludeFromRecents="true"
|
||||
|
|
|
@ -46,6 +46,11 @@ class OfflineOperationTypeAdapter : JsonSerializer<OfflineOperationType>, JsonDe
|
|||
jsonObject.addProperty("newName", src.newName)
|
||||
}
|
||||
|
||||
is OfflineOperationType.RemoveFile -> {
|
||||
jsonObject.addProperty("type", src.type)
|
||||
jsonObject.addProperty("path", src.path)
|
||||
}
|
||||
|
||||
null -> Unit
|
||||
}
|
||||
|
||||
|
@ -78,6 +83,11 @@ class OfflineOperationTypeAdapter : JsonSerializer<OfflineOperationType>, JsonDe
|
|||
jsonObject.get("newName").asString
|
||||
)
|
||||
|
||||
OfflineOperationRawType.RemoveFile.name -> OfflineOperationType.RemoveFile(
|
||||
jsonObject.get("type").asString,
|
||||
jsonObject.get("path").asString
|
||||
)
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.nextcloud.client.widget.DashboardWidgetProvider;
|
|||
import com.nextcloud.client.widget.DashboardWidgetService;
|
||||
import com.nextcloud.receiver.NetworkChangeReceiver;
|
||||
import com.nextcloud.ui.ChooseAccountDialogFragment;
|
||||
import com.nextcloud.ui.ChooseStorageLocationDialogFragment;
|
||||
import com.nextcloud.ui.ImageDetailFragment;
|
||||
import com.nextcloud.ui.SetStatusDialogFragment;
|
||||
import com.nextcloud.ui.composeActivity.ComposeActivity;
|
||||
|
@ -89,13 +90,13 @@ import com.owncloud.android.ui.dialog.RenameFileDialogFragment;
|
|||
import com.owncloud.android.ui.dialog.RenamePublicShareDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.SendFilesDialog;
|
||||
import com.owncloud.android.ui.dialog.SendShareDialog;
|
||||
import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.SharePasswordDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.SortingOrderDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.SslUntrustedCertDialog;
|
||||
import com.owncloud.android.ui.dialog.StoragePermissionDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.SyncFileNotEnoughSpaceDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.SyncedFolderPreferencesDialogFragment;
|
||||
import com.owncloud.android.ui.dialog.setupEncryption.SetupEncryptionDialogFragment;
|
||||
import com.owncloud.android.ui.fragment.ExtendedListFragment;
|
||||
import com.owncloud.android.ui.fragment.FeatureFragment;
|
||||
import com.owncloud.android.ui.fragment.FileDetailActivitiesFragment;
|
||||
|
@ -416,6 +417,9 @@ abstract class ComponentsModule {
|
|||
@ContributesAndroidInjector
|
||||
abstract SetupEncryptionDialogFragment setupEncryptionDialogFragment();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract ChooseStorageLocationDialogFragment chooseStorageLocationDialogFragment();
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract SharePasswordDialogFragment sharePasswordDialogFragment();
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.owncloud.android.lib.common.operations.RemoteOperationResult
|
|||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
import com.owncloud.android.lib.resources.files.UploadFileRemoteOperation
|
||||
import com.owncloud.android.operations.CreateFolderOperation
|
||||
import com.owncloud.android.operations.RemoveFileOperation
|
||||
import com.owncloud.android.operations.RenameFileOperation
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -163,6 +164,16 @@ class OfflineOperationsWorker(
|
|||
renameFileOperation?.execute(client) to renameFileOperation
|
||||
}
|
||||
|
||||
is OfflineOperationType.RemoveFile -> {
|
||||
val removeFileOperation = withContext(NonCancellable) {
|
||||
val operationType = (operation.type as OfflineOperationType.RemoveFile)
|
||||
val ocFile = fileDataStorageManager.getFileByDecryptedRemotePath(operationType.path)
|
||||
RemoveFileOperation(ocFile, false, user, true, context, fileDataStorageManager)
|
||||
}
|
||||
|
||||
removeFileOperation.execute(client) to removeFileOperation
|
||||
}
|
||||
|
||||
else -> {
|
||||
Log_OC.d(TAG, "Unsupported operation type: ${operation.type}")
|
||||
null
|
||||
|
@ -186,7 +197,15 @@ class OfflineOperationsWorker(
|
|||
Log_OC.d(TAG, "$logMessage filename: ${operation.filename}, type: ${operation.type}")
|
||||
|
||||
if (result.isSuccess) {
|
||||
repository.updateNextOperations(operation)
|
||||
if (operation.type is OfflineOperationType.RemoveFile) {
|
||||
val operationType = operation.type as OfflineOperationType.RemoveFile
|
||||
fileDataStorageManager.getFileByDecryptedRemotePath(operationType.path)?.let { ocFile ->
|
||||
repository.deleteOperation(ocFile)
|
||||
}
|
||||
} else {
|
||||
repository.updateNextOperations(operation)
|
||||
}
|
||||
|
||||
fileDataStorageManager.offlineOperationDao.delete(operation)
|
||||
notificationManager.update(totalOperations, currentSuccessfulOperationIndex, operation.filename ?: "")
|
||||
} else {
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.nextcloud.client.account.UserAccountManager
|
|||
import com.nextcloud.client.appinfo.AppInfo
|
||||
import com.nextcloud.client.di.Injectable
|
||||
import com.nextcloud.client.preferences.AppPreferences
|
||||
import com.nextcloud.utils.mdm.MDMConfig
|
||||
import com.owncloud.android.BuildConfig
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity
|
||||
|
@ -76,13 +77,12 @@ class FirstRunActivity : BaseActivity(), Injectable {
|
|||
binding = FirstRunActivityBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
|
||||
val isProviderOrOwnInstallationVisible = resources.getBoolean(R.bool.show_provider_or_own_installation)
|
||||
setSlideshowSize(resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE)
|
||||
|
||||
registerActivityResult()
|
||||
setupLoginButton()
|
||||
setupSignupButton(isProviderOrOwnInstallationVisible)
|
||||
setupHostOwnServerTextView(isProviderOrOwnInstallationVisible)
|
||||
setupSignupButton(MDMConfig.showIntro(this))
|
||||
setupHostOwnServerTextView(MDMConfig.showIntro(this))
|
||||
deleteAccountAtFirstLaunch()
|
||||
setupFeaturesViewAdapter()
|
||||
handleOnBackPressed()
|
||||
|
@ -207,10 +207,9 @@ class FirstRunActivity : BaseActivity(), Injectable {
|
|||
}
|
||||
|
||||
private fun setSlideshowSize(isLandscape: Boolean) {
|
||||
val isProviderOrOwnInstallationVisible = resources.getBoolean(R.bool.show_provider_or_own_installation)
|
||||
binding.buttonLayout.orientation = if (isLandscape) LinearLayout.HORIZONTAL else LinearLayout.VERTICAL
|
||||
|
||||
val layoutParams: LinearLayout.LayoutParams = if (isProviderOrOwnInstallationVisible) {
|
||||
val layoutParams: LinearLayout.LayoutParams = if (MDMConfig.showIntro(this)) {
|
||||
LinearLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
|
|
|
@ -13,13 +13,14 @@ import android.content.Intent
|
|||
import android.content.res.Resources
|
||||
import com.nextcloud.client.account.CurrentAccountProvider
|
||||
import com.nextcloud.client.preferences.AppPreferences
|
||||
import com.nextcloud.utils.mdm.MDMConfig
|
||||
import com.owncloud.android.BuildConfig
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity
|
||||
import com.owncloud.android.features.FeatureItem
|
||||
import com.owncloud.android.ui.activity.PassCodeActivity
|
||||
|
||||
internal class OnboardingServiceImpl constructor(
|
||||
internal class OnboardingServiceImpl(
|
||||
private val resources: Resources,
|
||||
private val preferences: AppPreferences,
|
||||
private val accountProvider: CurrentAccountProvider
|
||||
|
@ -61,8 +62,7 @@ internal class OnboardingServiceImpl constructor(
|
|||
}
|
||||
|
||||
override fun launchFirstRunIfNeeded(activity: Activity): Boolean {
|
||||
val isProviderOrOwnInstallationVisible = resources.getBoolean(R.bool.show_provider_or_own_installation)
|
||||
val canLaunch = isProviderOrOwnInstallationVisible && isFirstRun && activity is AuthenticatorActivity
|
||||
val canLaunch = MDMConfig.showIntro(activity) && isFirstRun && activity is AuthenticatorActivity
|
||||
if (canLaunch) {
|
||||
val intent = Intent(activity, FirstRunActivity::class.java)
|
||||
activity.startActivityForResult(intent, AuthenticatorActivity.REQUEST_CODE_FIRST_RUN)
|
||||
|
|
|
@ -55,6 +55,7 @@ public final class AppPreferencesImpl implements AppPreferences {
|
|||
*/
|
||||
public static final String AUTO_PREF__LAST_SEEN_VERSION_CODE = "lastSeenVersionCode";
|
||||
public static final String STORAGE_PATH = "storage_path";
|
||||
public static final String DATA_STORAGE_LOCATION = "data_storage_location";
|
||||
public static final String STORAGE_PATH_VALID = "storage_path_valid";
|
||||
public static final String PREF__DARK_THEME = "dark_theme_mode";
|
||||
public static final float DEFAULT_GRID_COLUMN = 3f;
|
||||
|
|
|
@ -24,10 +24,13 @@ sealed class OfflineOperationType {
|
|||
var ocFileId: Long,
|
||||
val newName: String
|
||||
) : OfflineOperationType()
|
||||
|
||||
data class RemoveFile(override val type: String, var path: String) : OfflineOperationType()
|
||||
}
|
||||
|
||||
enum class OfflineOperationRawType {
|
||||
CreateFolder,
|
||||
CreateFile,
|
||||
RenameFile
|
||||
RenameFile,
|
||||
RemoveFile
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.nextcloud.client.account.UserAccountManager
|
|||
import com.nextcloud.client.di.Injectable
|
||||
import com.nextcloud.client.network.ClientFactory
|
||||
import com.nextcloud.utils.extensions.getParcelableArgument
|
||||
import com.nextcloud.utils.mdm.MDMConfig
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.databinding.DialogChooseAccountBinding
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager
|
||||
|
@ -120,8 +121,7 @@ class ChooseAccountDialogFragment :
|
|||
viewThemeUtils
|
||||
)
|
||||
|
||||
// hide "add account" when no multi account
|
||||
if (!resources.getBoolean(R.bool.multiaccount_support)) {
|
||||
if (!MDMConfig.multiAccountSupport(requireContext())) {
|
||||
binding.addAccount.visibility = View.GONE
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 ZetaTom <70907959+ZetaTom@users.noreply.github.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.ui
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.nextcloud.client.di.Injectable
|
||||
import com.nextcloud.client.preferences.AppPreferencesImpl
|
||||
import com.owncloud.android.MainApp
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.databinding.DialogDataStorageLocationBinding
|
||||
import com.owncloud.android.datastorage.DataStorageProvider
|
||||
import com.owncloud.android.datastorage.StoragePoint
|
||||
import com.owncloud.android.datastorage.StoragePoint.PrivacyType
|
||||
import com.owncloud.android.datastorage.StoragePoint.StorageType
|
||||
import com.owncloud.android.utils.DisplayUtils
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils
|
||||
import java.io.File
|
||||
import javax.inject.Inject
|
||||
|
||||
class ChooseStorageLocationDialogFragment : DialogFragment(), Injectable {
|
||||
|
||||
private lateinit var binding: DialogDataStorageLocationBinding
|
||||
|
||||
@Inject
|
||||
lateinit var viewThemeUtils: ViewThemeUtils
|
||||
|
||||
private val storagePoints = DataStorageProvider.getInstance().availableStoragePoints
|
||||
|
||||
private val selectedStorageType
|
||||
get() = if (!binding.storageExternalRadio.isChecked) StorageType.INTERNAL else StorageType.EXTERNAL
|
||||
private val selectedPrivacyType
|
||||
get() = if (binding.allowMediaIndexSwitch.isChecked) PrivacyType.PUBLIC else PrivacyType.PRIVATE
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
binding = DialogDataStorageLocationBinding.inflate(layoutInflater)
|
||||
|
||||
viewThemeUtils.material.colorMaterialSwitch(binding.allowMediaIndexSwitch)
|
||||
viewThemeUtils.platform.themeRadioButton(binding.storageInternalRadio)
|
||||
viewThemeUtils.platform.themeRadioButton(binding.storageExternalRadio)
|
||||
|
||||
val builder = MaterialAlertDialogBuilder(requireContext()).setTitle(R.string.storage_choose_location)
|
||||
.setPositiveButton(R.string.common_ok) { dialog: DialogInterface, _ ->
|
||||
notifyResult()
|
||||
dialog.dismiss()
|
||||
}.setView(binding.root)
|
||||
|
||||
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(requireContext(), builder)
|
||||
|
||||
binding.storageRadioGroup.setOnCheckedChangeListener { _, _ ->
|
||||
updateMediaIndexSwitch()
|
||||
}
|
||||
|
||||
binding.allowMediaIndexSwitch.setOnCheckedChangeListener { _, _ ->
|
||||
updateStorageTypeSelection()
|
||||
}
|
||||
|
||||
return builder.create()
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
setupLocationSelection()
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface) {
|
||||
super.onDismiss(dialog)
|
||||
activity?.finish()
|
||||
}
|
||||
|
||||
private fun setupLocationSelection() {
|
||||
updateStorageTypeSelection()
|
||||
|
||||
val radioButton = when (getCurrentStorageLocation().storageType) {
|
||||
StorageType.EXTERNAL -> binding.storageExternalRadio
|
||||
else -> binding.storageInternalRadio
|
||||
}
|
||||
|
||||
radioButton.isChecked = true
|
||||
updateMediaIndexSwitch()
|
||||
}
|
||||
|
||||
private fun getStoragePointLabel(storageType: StorageType, privacyType: PrivacyType): String {
|
||||
val typeString = when (storageType) {
|
||||
StorageType.INTERNAL -> getString(R.string.storage_internal_storage)
|
||||
StorageType.EXTERNAL -> getString(R.string.storage_external_storage)
|
||||
}
|
||||
|
||||
val storagePath =
|
||||
storagePoints.firstOrNull { it.storageType == storageType && it.privacyType == privacyType }?.path
|
||||
|
||||
return storagePath?.let {
|
||||
val file = File(it)
|
||||
val totalSpace = file.totalSpace
|
||||
val usedSpace = totalSpace - file.freeSpace
|
||||
return String.format(
|
||||
getString(R.string.file_migration_free_space),
|
||||
typeString,
|
||||
DisplayUtils.bytesToHumanReadable(usedSpace),
|
||||
DisplayUtils.bytesToHumanReadable(totalSpace)
|
||||
)
|
||||
} ?: typeString
|
||||
}
|
||||
|
||||
private fun updateMediaIndexSwitch() {
|
||||
val privacyTypes =
|
||||
storagePoints.filter { it.storageType == selectedStorageType }.map { it.privacyType }.distinct()
|
||||
binding.allowMediaIndexSwitch.isEnabled = privacyTypes.size > 1
|
||||
binding.allowMediaIndexSwitch.isChecked = privacyTypes.contains(PrivacyType.PUBLIC)
|
||||
}
|
||||
|
||||
private fun updateStorageTypeSelection() {
|
||||
val hasInternalStorage = storagePoints.any { it.storageType == StorageType.INTERNAL }
|
||||
val hasExternalStorage = storagePoints.any { it.storageType == StorageType.EXTERNAL }
|
||||
|
||||
binding.storageInternalRadio.isEnabled = hasInternalStorage
|
||||
binding.storageInternalRadio.text = getStoragePointLabel(StorageType.INTERNAL, selectedPrivacyType)
|
||||
|
||||
binding.storageExternalRadio.isEnabled = hasExternalStorage
|
||||
binding.storageExternalRadio.text = getStoragePointLabel(StorageType.EXTERNAL, selectedPrivacyType)
|
||||
}
|
||||
|
||||
private fun getCurrentStorageLocation(): StoragePoint {
|
||||
val appContext = MainApp.getAppContext()
|
||||
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext)
|
||||
val storagePath = sharedPreferences.getString(AppPreferencesImpl.STORAGE_PATH, appContext.filesDir.absolutePath)
|
||||
return storagePoints.first { it.path == storagePath }
|
||||
}
|
||||
|
||||
private fun notifyResult() {
|
||||
val newPath =
|
||||
storagePoints.first { it.storageType == selectedStorageType && it.privacyType == selectedPrivacyType }
|
||||
|
||||
val resultBundle = Bundle().apply {
|
||||
putString(KEY_RESULT_STORAGE_LOCATION, newPath.path)
|
||||
}
|
||||
|
||||
parentFragmentManager.setFragmentResult(KEY_RESULT_STORAGE_LOCATION, resultBundle)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY_RESULT_STORAGE_LOCATION = "KEY_RESULT_STORAGE_LOCATION"
|
||||
const val STORAGE_LOCATION_RESULT_CODE = 100
|
||||
|
||||
@JvmStatic
|
||||
fun newInstance() = ChooseStorageLocationDialogFragment()
|
||||
|
||||
@JvmStatic
|
||||
val TAG: String = Companion::class.java.simpleName
|
||||
}
|
||||
}
|
|
@ -59,7 +59,7 @@ object AutoRename {
|
|||
|
||||
forbiddenFilenameExtensions.find { it == StringConstants.DOT }?.let { forbiddenExtension ->
|
||||
pathSegments.replaceAll { segment ->
|
||||
replacePathSegment(forbiddenExtension, segment)
|
||||
replaceDots(forbiddenExtension, segment)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,9 +67,13 @@ object AutoRename {
|
|||
.filter { it != StringConstants.SPACE && it != StringConstants.DOT }
|
||||
.forEach { forbiddenExtension ->
|
||||
pathSegments.replaceAll { segment ->
|
||||
replacePathSegment(forbiddenExtension, segment)
|
||||
replaceFileExtensions(forbiddenExtension, segment)
|
||||
}
|
||||
}
|
||||
|
||||
pathSegments.replaceAll { segment ->
|
||||
lowercaseFileExtension(segment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -82,16 +86,41 @@ object AutoRename {
|
|||
}
|
||||
}
|
||||
|
||||
private fun replacePathSegment(forbiddenExtension: String, segment: String): String {
|
||||
return if (segment.endsWith(forbiddenExtension, ignoreCase = true) ||
|
||||
segment.startsWith(forbiddenExtension, ignoreCase = true)
|
||||
) {
|
||||
segment.replace(forbiddenExtension, REPLACEMENT)
|
||||
private fun lowercaseFileExtension(input: String): String {
|
||||
val lastDotIndex = input.lastIndexOf('.')
|
||||
|
||||
return if (lastDotIndex > 0) {
|
||||
val base = input.substring(0, lastDotIndex)
|
||||
val extension = input.substring(lastDotIndex + 1).lowercase() // Convert extension to lowercase
|
||||
|
||||
"$base.$extension"
|
||||
} else {
|
||||
input
|
||||
}
|
||||
}
|
||||
|
||||
private fun replaceDots(forbiddenExtension: String, segment: String): String {
|
||||
return if (isSegmentContainsForbiddenExtension(forbiddenExtension, segment)) {
|
||||
segment.replaceFirst(forbiddenExtension, REPLACEMENT)
|
||||
} else {
|
||||
segment
|
||||
}
|
||||
}
|
||||
|
||||
private fun replaceFileExtensions(forbiddenExtension: String, segment: String): String {
|
||||
return if (isSegmentContainsForbiddenExtension(forbiddenExtension, segment)) {
|
||||
val newExtension = forbiddenExtension.replace(StringConstants.DOT, REPLACEMENT, ignoreCase = true)
|
||||
segment.replace(forbiddenExtension, newExtension.lowercase(), ignoreCase = true)
|
||||
} else {
|
||||
segment
|
||||
}
|
||||
}
|
||||
|
||||
private fun isSegmentContainsForbiddenExtension(forbiddenExtension: String, segment: String): Boolean {
|
||||
return segment.endsWith(forbiddenExtension, ignoreCase = true) ||
|
||||
segment.startsWith(forbiddenExtension, ignoreCase = true)
|
||||
}
|
||||
|
||||
private fun convertToUTF8(filename: String): String {
|
||||
return String(filename.toByteArray(), Charsets.UTF_8)
|
||||
}
|
||||
|
|
134
app/src/main/java/com/nextcloud/utils/mdm/MDMConfig.kt
Normal file
134
app/src/main/java/com/nextcloud/utils/mdm/MDMConfig.kt
Normal file
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.nextcloud.utils.mdm
|
||||
|
||||
import android.content.Context
|
||||
import android.content.RestrictionsManager
|
||||
import com.owncloud.android.BuildConfig
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.utils.appConfig.AppConfigKeys
|
||||
|
||||
object MDMConfig {
|
||||
fun multiAccountSupport(context: Context): Boolean {
|
||||
val multiAccountSupport = context.resources.getBoolean(R.bool.multiaccount_support)
|
||||
|
||||
val disableMultiAccountViaMDM = context.getRestriction(
|
||||
AppConfigKeys.DisableMultiAccount,
|
||||
context.resources.getBoolean(R.bool.disable_multiaccount)
|
||||
)
|
||||
|
||||
return multiAccountSupport && !disableMultiAccountViaMDM
|
||||
}
|
||||
|
||||
fun shareViaLink(context: Context): Boolean {
|
||||
val disableShareViaMDM = context.getRestriction(
|
||||
AppConfigKeys.DisableSharing,
|
||||
context.resources.getBoolean(R.bool.disable_sharing)
|
||||
)
|
||||
|
||||
val shareViaLink = context.resources.getBoolean(R.bool.share_via_link_feature)
|
||||
|
||||
return shareViaLink && !disableShareViaMDM
|
||||
}
|
||||
|
||||
fun shareViaUser(context: Context): Boolean {
|
||||
val disableShareViaMDM = context.getRestriction(
|
||||
AppConfigKeys.DisableSharing,
|
||||
context.resources.getBoolean(R.bool.disable_sharing)
|
||||
)
|
||||
|
||||
val shareViaUsers = context.resources.getBoolean(R.bool.share_with_users_feature)
|
||||
|
||||
return shareViaUsers && !disableShareViaMDM
|
||||
}
|
||||
|
||||
fun sendFilesSupport(context: Context): Boolean {
|
||||
val disableShareViaMDM = context.getRestriction(
|
||||
AppConfigKeys.DisableSharing,
|
||||
context.resources.getBoolean(R.bool.disable_sharing)
|
||||
)
|
||||
|
||||
val sendFilesToOtherApp = "on".equals(context.getString(R.string.send_files_to_other_apps), ignoreCase = true)
|
||||
|
||||
return sendFilesToOtherApp && !disableShareViaMDM
|
||||
}
|
||||
|
||||
fun sharingSupport(context: Context): Boolean {
|
||||
val disableShareViaMDM = context.getRestriction(
|
||||
AppConfigKeys.DisableSharing,
|
||||
context.resources.getBoolean(R.bool.disable_sharing)
|
||||
)
|
||||
|
||||
val sendFilesToOtherApp = "on".equals(context.getString(R.string.send_files_to_other_apps), ignoreCase = true)
|
||||
|
||||
val shareViaUsers = context.resources.getBoolean(R.bool.share_with_users_feature)
|
||||
|
||||
val shareViaLink = context.resources.getBoolean(R.bool.share_via_link_feature)
|
||||
|
||||
return sendFilesToOtherApp && shareViaLink && shareViaUsers && !disableShareViaMDM
|
||||
}
|
||||
|
||||
fun clipBoardSupport(context: Context): Boolean {
|
||||
val disableClipboardSupport = context.getRestriction(
|
||||
AppConfigKeys.DisableClipboard,
|
||||
context.resources.getBoolean(R.bool.disable_clipboard)
|
||||
)
|
||||
|
||||
return !disableClipboardSupport
|
||||
}
|
||||
|
||||
fun externalSiteSupport(context: Context): Boolean {
|
||||
val disableMoreExternalSiteViaMDM = context.getRestriction(
|
||||
AppConfigKeys.DisableMoreExternalSite,
|
||||
context.resources.getBoolean(R.bool.disable_more_external_site)
|
||||
)
|
||||
|
||||
val showExternalLinks = context.resources.getBoolean(R.bool.show_external_links)
|
||||
|
||||
return showExternalLinks && !disableMoreExternalSiteViaMDM
|
||||
}
|
||||
|
||||
fun showIntro(context: Context): Boolean {
|
||||
val disableIntroViaMDM =
|
||||
context.getRestriction(AppConfigKeys.DisableIntro, context.resources.getBoolean(R.bool.disable_intro))
|
||||
|
||||
val isProviderOrOwnInstallationVisible = context.resources.getBoolean(R.bool.show_provider_or_own_installation)
|
||||
|
||||
return isProviderOrOwnInstallationVisible && !disableIntroViaMDM
|
||||
}
|
||||
|
||||
fun isLogEnabled(context: Context): Boolean {
|
||||
val disableLogViaMDM =
|
||||
context.getRestriction(AppConfigKeys.DisableLog, context.resources.getBoolean(R.bool.disable_log))
|
||||
|
||||
val loggerEnabled = context.resources.getBoolean(R.bool.logger_enabled)
|
||||
|
||||
return loggerEnabled && !disableLogViaMDM && BuildConfig.DEBUG
|
||||
}
|
||||
|
||||
fun getBaseUrl(context: Context): String = context.getRestriction(AppConfigKeys.BaseUrl, "")
|
||||
|
||||
fun getHost(context: Context): String =
|
||||
context.getRestriction(AppConfigKeys.ProxyHost, context.getString(R.string.proxy_host))
|
||||
|
||||
fun getPort(context: Context): Int =
|
||||
context.getRestriction(AppConfigKeys.ProxyPort, context.resources.getInteger(R.integer.proxy_port))
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun <T : Any> Context.getRestriction(appConfigKey: AppConfigKeys, defaultValue: T): T {
|
||||
val restrictionsManager = getSystemService(Context.RESTRICTIONS_SERVICE) as? RestrictionsManager
|
||||
val appRestrictions = restrictionsManager?.getApplicationRestrictions() ?: return defaultValue
|
||||
|
||||
return when (defaultValue) {
|
||||
is String -> appRestrictions.getString(appConfigKey.key, defaultValue) as T? ?: defaultValue
|
||||
is Int -> appRestrictions.getInt(appConfigKey.key, defaultValue) as T? ?: defaultValue
|
||||
is Boolean -> appRestrictions.getBoolean(appConfigKey.key, defaultValue) as T? ?: defaultValue
|
||||
else -> defaultValue
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,11 +22,11 @@ import android.app.Application;
|
|||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
|
@ -62,6 +62,7 @@ import com.nextcloud.client.preferences.DarkMode;
|
|||
import com.nextcloud.receiver.NetworkChangeListener;
|
||||
import com.nextcloud.receiver.NetworkChangeReceiver;
|
||||
import com.nextcloud.utils.extensions.ContextExtensionsKt;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.nmc.android.ui.LauncherActivity;
|
||||
import com.owncloud.android.authentication.PassCodeManager;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
|
@ -87,7 +88,6 @@ import com.owncloud.android.utils.FilesSyncHelper;
|
|||
import com.owncloud.android.utils.PermissionUtil;
|
||||
import com.owncloud.android.utils.ReceiversHelper;
|
||||
import com.owncloud.android.utils.SecurityUtils;
|
||||
import com.owncloud.android.utils.appConfig.AppConfigManager;
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils;
|
||||
|
||||
import org.conscrypt.Conscrypt;
|
||||
|
@ -199,8 +199,6 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
|
|||
@SuppressWarnings("unused")
|
||||
private boolean mBound;
|
||||
|
||||
private AppConfigManager appConfigManager;
|
||||
|
||||
private static AppComponent appComponent;
|
||||
|
||||
private NetworkChangeReceiver networkChangeReceiver;
|
||||
|
@ -333,11 +331,7 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
|
|||
OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
|
||||
|
||||
if (isClientBrandedPlus()) {
|
||||
RestrictionsManager restrictionsManager = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
appConfigManager = new AppConfigManager(this, restrictionsManager.getApplicationRestrictions());
|
||||
appConfigManager.setProxyConfig(isClientBrandedPlus());
|
||||
|
||||
// Listen app config changes
|
||||
setProxyConfig();
|
||||
ContextExtensionsKt.registerBroadcastReceiver(this, restrictionsReceiver, restrictionsFilter, ReceiverFlag.NotExported);
|
||||
} else {
|
||||
setProxyForNonBrandedPlusClients();
|
||||
|
@ -346,8 +340,7 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
|
|||
// initialise thumbnails cache on background thread
|
||||
new ThumbnailsCacheManager.InitDiskCacheTask().execute();
|
||||
|
||||
|
||||
if (BuildConfig.DEBUG || getApplicationContext().getResources().getBoolean(R.bool.logger_enabled)) {
|
||||
if (MDMConfig.INSTANCE.isLogEnabled(this)) {
|
||||
// use app writable dir, no permissions needed
|
||||
Log_OC.setLoggerImplementation(new LegacyLoggerAdapter(logger));
|
||||
Log_OC.d("Debug", "start logging");
|
||||
|
@ -388,6 +381,18 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
|
|||
registerGlobalPassCodeProtection();
|
||||
networkChangeReceiver = new NetworkChangeReceiver(this, connectivityService);
|
||||
registerNetworkChangeReceiver();
|
||||
|
||||
if (!MDMConfig.INSTANCE.sendFilesSupport(this)) {
|
||||
disableDocumentsStorageProvider();
|
||||
}
|
||||
}
|
||||
|
||||
public void disableDocumentsStorageProvider() {
|
||||
String packageName = getPackageName();
|
||||
String providerClassName = "com.owncloud.android.providers.DocumentsStorageProvider";
|
||||
ComponentName componentName = new ComponentName(packageName, providerClassName);
|
||||
PackageManager packageManager = getPackageManager();
|
||||
packageManager.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
|
||||
}
|
||||
|
||||
private final LifecycleEventObserver lifecycleEventObserver = ((lifecycleOwner, event) -> {
|
||||
|
@ -397,8 +402,7 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
|
|||
passCodeManager.setCanAskPin(true);
|
||||
Log_OC.d(TAG, "APP IN BACKGROUND");
|
||||
} else if (event == Lifecycle.Event.ON_RESUME) {
|
||||
if (appConfigManager == null) return;
|
||||
appConfigManager.setProxyConfig(isClientBrandedPlus());
|
||||
setProxyConfig();
|
||||
Log_OC.d(TAG, "APP ON RESUME");
|
||||
}
|
||||
});
|
||||
|
@ -420,11 +424,34 @@ public class MainApp extends Application implements HasAndroidInjector, NetworkC
|
|||
|
||||
private final BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
|
||||
@Override public void onReceive(Context context, Intent intent) {
|
||||
if (appConfigManager == null) return;
|
||||
appConfigManager.setProxyConfig(isClientBrandedPlus());
|
||||
setProxyConfig();
|
||||
}
|
||||
};
|
||||
|
||||
private void setProxyConfig() {
|
||||
if (!isClientBrandedPlus()) {
|
||||
Log_OC.d(TAG, "Proxy configuration cannot be set. Client is not branded plus.");
|
||||
return;
|
||||
}
|
||||
|
||||
String host = MDMConfig.INSTANCE.getHost(this);
|
||||
int port = MDMConfig.INSTANCE.getPort(this);
|
||||
|
||||
if (TextUtils.isEmpty(host) || port == -1) {
|
||||
Log_OC.d(TAG, "Proxy configuration cannot be found");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
OwnCloudClientManagerFactory.setProxyHost(host);
|
||||
OwnCloudClientManagerFactory.setProxyPort(port);
|
||||
|
||||
Log_OC.d(TAG, "Proxy configuration successfully set");
|
||||
} catch (Resources.NotFoundException e) {
|
||||
Log_OC.e(TAG, "Proxy config cannot able to set due to: $e");
|
||||
}
|
||||
}
|
||||
|
||||
private void registerGlobalPassCodeProtection() {
|
||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.os.Bundle;
|
|||
import android.os.Handler;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.lib.common.accounts.AccountTypeUtils;
|
||||
|
@ -70,7 +71,7 @@ public class AccountAuthenticator extends AbstractAccountAuthenticator {
|
|||
|
||||
final Bundle bundle = new Bundle();
|
||||
|
||||
if (mContext.getResources().getBoolean(R.bool.multiaccount_support) || accounts.length < 1) {
|
||||
if (accounts.length < 1 || MDMConfig.INSTANCE.multiAccountSupport(mContext)) {
|
||||
try {
|
||||
validateAccountType(accountType);
|
||||
} catch (AuthenticatorException e) {
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.app.Activity;
|
|||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
|
@ -71,6 +70,7 @@ import com.nextcloud.client.preferences.AppPreferences;
|
|||
import com.nextcloud.common.PlainClient;
|
||||
import com.nextcloud.operations.PostMethod;
|
||||
import com.nextcloud.utils.extensions.BundleExtensionsKt;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.AccountSetupBinding;
|
||||
|
@ -112,7 +112,6 @@ import com.owncloud.android.utils.DisplayUtils;
|
|||
import com.owncloud.android.utils.ErrorMessageAdapter;
|
||||
import com.owncloud.android.utils.PermissionUtil;
|
||||
import com.owncloud.android.utils.WebViewUtil;
|
||||
import com.owncloud.android.utils.appConfig.AppConfigManager;
|
||||
import com.owncloud.android.utils.theme.CapabilityUtils;
|
||||
import com.owncloud.android.utils.theme.ViewThemeUtils;
|
||||
|
||||
|
@ -320,11 +319,9 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
String webloginUrl = null;
|
||||
|
||||
if (MainApp.isClientBrandedPlus()) {
|
||||
RestrictionsManager restrictionsManager = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
AppConfigManager appConfigManager = new AppConfigManager(this, restrictionsManager.getApplicationRestrictions());
|
||||
|
||||
if (!TextUtils.isEmpty(appConfigManager.getBaseUrl(MainApp.isClientBrandedPlus()))) {
|
||||
webloginUrl = appConfigManager.getBaseUrl(MainApp.isClientBrandedPlus()) + WEB_LOGIN;
|
||||
String baseUrl = MDMConfig.INSTANCE.getBaseUrl(this);
|
||||
if (!TextUtils.isEmpty(baseUrl)) {
|
||||
webloginUrl = baseUrl + WEB_LOGIN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -812,9 +809,8 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
passCodeManager.onActivityResumed(this);
|
||||
|
||||
Uri data = intent.getData();
|
||||
|
||||
if (data != null && data.toString().startsWith(getString(R.string.login_data_own_scheme))) {
|
||||
if (!getResources().getBoolean(R.bool.multiaccount_support) &&
|
||||
if (!MDMConfig.INSTANCE.multiAccountSupport(this) &&
|
||||
accountManager.getAccounts().length == 1) {
|
||||
Toast.makeText(this, R.string.no_mutliple_accounts_allowed, Toast.LENGTH_LONG).show();
|
||||
finish();
|
||||
|
@ -1535,7 +1531,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
return;
|
||||
}
|
||||
|
||||
if (!getResources().getBoolean(R.bool.multiaccount_support) &&
|
||||
if (!MDMConfig.INSTANCE.multiAccountSupport(this) &&
|
||||
accountManager.getAccounts().length == 1) {
|
||||
Toast.makeText(this, R.string.no_mutliple_accounts_allowed, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
|
|
|
@ -11,16 +11,14 @@ import android.os.Bundle
|
|||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import com.nextcloud.client.di.Injectable
|
||||
import com.nextcloud.utils.mdm.MDMConfig
|
||||
import com.owncloud.android.R
|
||||
|
||||
class DeepLinkLoginActivity : AuthenticatorActivity(), Injectable {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (!resources.getBoolean(R.bool.multiaccount_support) &&
|
||||
accountManager.accounts.size == 1
|
||||
) {
|
||||
if (!MDMConfig.multiAccountSupport(this) && accountManager.accounts.size == 1) {
|
||||
Toast.makeText(this, R.string.no_mutliple_accounts_allowed, Toast.LENGTH_LONG).show()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -175,6 +175,10 @@ public class FileDataStorageManager {
|
|||
}
|
||||
}
|
||||
|
||||
public OfflineOperationEntity getOfflineEntityFromOCFile(OCFile file) {
|
||||
return offlineOperationDao.getByPath(file.getDecryptedRemotePath());
|
||||
}
|
||||
|
||||
public OfflineOperationEntity addCreateFolderOfflineOperation(String path, String filename, Long parentOCFileId) {
|
||||
OfflineOperationEntity entity = new OfflineOperationEntity();
|
||||
|
||||
|
@ -246,6 +250,25 @@ public class FileDataStorageManager {
|
|||
return filename;
|
||||
}
|
||||
|
||||
public void addRemoveFileOfflineOperation(String path, String filename, Long parentOCFileId) {
|
||||
OfflineOperationEntity entity = new OfflineOperationEntity();
|
||||
|
||||
entity.setFilename(filename);
|
||||
entity.setParentOCFileId(parentOCFileId);
|
||||
|
||||
OfflineOperationType.RemoveFile operationType = new OfflineOperationType.RemoveFile(OfflineOperationRawType.RemoveFile.name(), path);
|
||||
entity.setType(operationType);
|
||||
entity.setPath(path);
|
||||
|
||||
long createdAt = System.currentTimeMillis();
|
||||
long modificationTimestamp = System.currentTimeMillis();
|
||||
|
||||
entity.setCreatedAt(createdAt);
|
||||
entity.setModifiedAt(modificationTimestamp / 1000);
|
||||
|
||||
offlineOperationDao.insert(entity);
|
||||
}
|
||||
|
||||
public void renameOfflineOperation(OCFile file, String newFolderName) {
|
||||
var entity = offlineOperationDao.getByPath(file.getDecryptedRemotePath());
|
||||
if (entity == null) {
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.nextcloud.client.editimage.EditImageActivity;
|
|||
import com.nextcloud.client.jobs.download.FileDownloadHelper;
|
||||
import com.nextcloud.client.jobs.upload.FileUploadHelper;
|
||||
import com.nextcloud.utils.EditorUtils;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
|
@ -184,9 +185,24 @@ public class FileMenuFilter {
|
|||
}
|
||||
|
||||
private void filterSendFiles(List<Integer> toHide, boolean inSingleFileFragment) {
|
||||
if ((overflowMenu || SEND_OFF.equalsIgnoreCase(context.getString(R.string.send_files_to_other_apps)) || containsEncryptedFile()) ||
|
||||
(!inSingleFileFragment && (isSingleSelection() || !allFileDown())) ||
|
||||
!toHide.contains(R.id.action_send_share_file)) {
|
||||
boolean sendFilesNotSupported = context != null && !MDMConfig.INSTANCE.sendFilesSupport(context);
|
||||
boolean hasEncryptedFile = containsEncryptedFile();
|
||||
boolean isSingleSelection = isSingleSelection();
|
||||
boolean allFilesNotDown = !allFileDown();
|
||||
|
||||
if (sendFilesNotSupported) {
|
||||
toHide.add(R.id.action_send_file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (overflowMenu || hasEncryptedFile) {
|
||||
toHide.add(R.id.action_send_file);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!inSingleFileFragment && (isSingleSelection || allFilesNotDown)) {
|
||||
toHide.add(R.id.action_send_file);
|
||||
} else if (!toHide.contains(R.id.action_send_share_file)) {
|
||||
toHide.add(R.id.action_send_file);
|
||||
}
|
||||
}
|
||||
|
@ -425,13 +441,11 @@ public class FileMenuFilter {
|
|||
}
|
||||
|
||||
private boolean isShareWithUsersAllowed() {
|
||||
return context != null &&
|
||||
context.getResources().getBoolean(R.bool.share_with_users_feature);
|
||||
return context != null && MDMConfig.INSTANCE.shareViaUser(context);
|
||||
}
|
||||
|
||||
private boolean isShareViaLinkAllowed() {
|
||||
return context != null &&
|
||||
context.getResources().getBoolean(R.bool.share_via_link_feature);
|
||||
return context != null && MDMConfig.INSTANCE.shareViaLink(context);
|
||||
}
|
||||
|
||||
private boolean isSingleSelection() {
|
||||
|
|
|
@ -64,6 +64,19 @@ public class CopyFileOperation extends SyncOperation {
|
|||
if (file.isFolder()) {
|
||||
targetPath += OCFile.PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
// auto rename, to allow copy
|
||||
if (targetPath.equals(srcPath)) {
|
||||
if (file.isFolder()) {
|
||||
targetPath = targetParentPath + file.getFileName();
|
||||
}
|
||||
targetPath = UploadFileOperation.getNewAvailableRemotePath(client, targetPath, null, false);
|
||||
|
||||
if (file.isFolder()) {
|
||||
targetPath += OCFile.PATH_SEPARATOR;
|
||||
}
|
||||
}
|
||||
|
||||
RemoteOperationResult result = new CopyFileRemoteOperation(srcPath, targetPath, false).execute(client);
|
||||
|
||||
/// 3. local copy
|
||||
|
|
|
@ -1342,7 +1342,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
* @param fileNames list of decrypted file names
|
||||
* @return new remote path
|
||||
*/
|
||||
private String getNewAvailableRemotePath(OwnCloudClient client,
|
||||
public static String getNewAvailableRemotePath(OwnCloudClient client,
|
||||
String remotePath,
|
||||
List<String> fileNames,
|
||||
boolean encrypted) {
|
||||
|
@ -1368,7 +1368,7 @@ public class UploadFileOperation extends SyncOperation {
|
|||
return newPath;
|
||||
}
|
||||
|
||||
private boolean existsFile(OwnCloudClient client,
|
||||
private static boolean existsFile(OwnCloudClient client,
|
||||
String remotePath,
|
||||
List<String> fileNames,
|
||||
boolean encrypted) {
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 ZetaTom <70907959+ZetaTom@users.noreply.github.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.owncloud.android.ui.activity
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.nextcloud.ui.ChooseStorageLocationDialogFragment
|
||||
|
||||
class ChooseStorageLocationActivity : AppCompatActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
val chooseStorageLocationDialogFragment = ChooseStorageLocationDialogFragment.newInstance()
|
||||
supportFragmentManager.setFragmentResultListener(
|
||||
KEY_RESULT_STORAGE_LOCATION,
|
||||
this
|
||||
) { _, result ->
|
||||
setResult(
|
||||
ChooseStorageLocationDialogFragment.STORAGE_LOCATION_RESULT_CODE,
|
||||
Intent().putExtra(
|
||||
KEY_RESULT_STORAGE_LOCATION,
|
||||
result.getString(KEY_RESULT_STORAGE_LOCATION)
|
||||
)
|
||||
)
|
||||
}
|
||||
chooseStorageLocationDialogFragment.show(supportFragmentManager, "choose_storage_location")
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY_RESULT_STORAGE_LOCATION = ChooseStorageLocationDialogFragment.KEY_RESULT_STORAGE_LOCATION
|
||||
}
|
||||
}
|
|
@ -59,6 +59,7 @@ import com.nextcloud.common.NextcloudClient;
|
|||
import com.nextcloud.ui.ChooseAccountDialogFragment;
|
||||
import com.nextcloud.ui.composeActivity.ComposeActivity;
|
||||
import com.nextcloud.ui.composeActivity.ComposeDestination;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.PassCodeManager;
|
||||
|
@ -602,10 +603,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
}
|
||||
|
||||
public void openAddAccount() {
|
||||
boolean isProviderOrOwnInstallationVisible = getResources()
|
||||
.getBoolean(R.bool.show_provider_or_own_installation);
|
||||
|
||||
if (isProviderOrOwnInstallationVisible) {
|
||||
if (MDMConfig.INSTANCE.showIntro(this)) {
|
||||
Intent firstRunIntent = new Intent(getApplicationContext(), FirstRunActivity.class);
|
||||
firstRunIntent.putExtra(FirstRunActivity.EXTRA_ALLOW_CLOSE, true);
|
||||
startActivity(firstRunIntent);
|
||||
|
@ -824,7 +822,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
|
||||
private void updateQuotaLink() {
|
||||
if (mQuotaTextLink != null) {
|
||||
if (getBaseContext().getResources().getBoolean(R.bool.show_external_links)) {
|
||||
if (MDMConfig.INSTANCE.externalSiteSupport(this)) {
|
||||
List<ExternalLink> quotas = externalLinksProvider.getExternalLink(ExternalLinkType.QUOTA);
|
||||
|
||||
float density = getResources().getDisplayMetrics().density;
|
||||
|
@ -973,7 +971,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
}
|
||||
|
||||
private void updateExternalLinksInDrawer() {
|
||||
if (mNavigationView != null && getBaseContext().getResources().getBoolean(R.bool.show_external_links)) {
|
||||
if (mNavigationView != null && MDMConfig.INSTANCE.externalSiteSupport(this)) {
|
||||
mNavigationView.getMenu().removeGroup(R.id.drawer_menu_external_links);
|
||||
|
||||
int greyColor = ContextCompat.getColor(this, R.color.drawer_menu_icon);
|
||||
|
@ -1222,7 +1220,7 @@ public abstract class DrawerActivity extends ToolbarActivity
|
|||
* Retrieves external links via api from 'external' app
|
||||
*/
|
||||
public void fetchExternalLinks(final boolean force) {
|
||||
if (!getBaseContext().getResources().getBoolean(R.bool.show_external_links)) {
|
||||
if (!MDMConfig.INSTANCE.externalSiteSupport(this)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ import com.nextcloud.utils.extensions.ActivityExtensionsKt;
|
|||
import com.nextcloud.utils.extensions.BundleExtensionsKt;
|
||||
import com.nextcloud.utils.extensions.FileExtensionsKt;
|
||||
import com.nextcloud.utils.extensions.IntentExtensionsKt;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
|
@ -718,12 +719,14 @@ public abstract class FileActivity extends DrawerActivity
|
|||
OCFile file,
|
||||
String link,
|
||||
final ViewThemeUtils viewThemeUtils) {
|
||||
ClipboardUtil.copyToClipboard(activity, link, false);
|
||||
Snackbar snackbar = Snackbar.make(activity.findViewById(android.R.id.content), R.string.clipboard_text_copied,
|
||||
Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.share, v -> showShareLinkDialog(activity, file, link));
|
||||
viewThemeUtils.material.themeSnackbar(snackbar);
|
||||
snackbar.show();
|
||||
if (MDMConfig.INSTANCE.shareViaLink(activity) && MDMConfig.INSTANCE.clipBoardSupport(activity)) {
|
||||
ClipboardUtil.copyToClipboard(activity, link, false);
|
||||
Snackbar snackbar = Snackbar.make(activity.findViewById(android.R.id.content), R.string.clipboard_text_copied,
|
||||
Snackbar.LENGTH_LONG)
|
||||
.setAction(R.string.share, v -> showShareLinkDialog(activity, file, link));
|
||||
viewThemeUtils.material.themeSnackbar(snackbar);
|
||||
snackbar.show();
|
||||
}
|
||||
}
|
||||
|
||||
public static void showShareLinkDialog(FileActivity activity, ServerFileInterface file, String link) {
|
||||
|
|
|
@ -403,15 +403,16 @@ open class FolderPickerActivity :
|
|||
private fun checkButtonStates(isConditionMet: Boolean) {
|
||||
folderPickerBinding.run {
|
||||
folderPickerBtnChoose.isEnabled = isConditionMet
|
||||
folderPickerBtnCopy.isEnabled = isFolderSelectable() && isConditionMet
|
||||
folderPickerBtnMove.isEnabled = isFolderSelectable() && isConditionMet
|
||||
folderPickerBtnCopy.isEnabled = isFolderSelectable(COPY) && isConditionMet
|
||||
folderPickerBtnMove.isEnabled = isFolderSelectable(MOVE) && isConditionMet
|
||||
}
|
||||
}
|
||||
|
||||
// for copy and move, disable selecting parent folder of target files
|
||||
private fun isFolderSelectable(): Boolean {
|
||||
private fun isFolderSelectable(type: String): Boolean {
|
||||
return when {
|
||||
action != MOVE_OR_COPY -> true
|
||||
action == MOVE_OR_COPY && type == COPY -> true
|
||||
targetFilePaths.isNullOrEmpty() -> true
|
||||
file?.isFolder != true -> true
|
||||
|
||||
|
@ -688,6 +689,8 @@ open class FolderPickerActivity :
|
|||
const val MOVE_OR_COPY = "MOVE_OR_COPY"
|
||||
const val CHOOSE_LOCATION = "CHOOSE_LOCATION"
|
||||
private val TAG = FolderPickerActivity::class.java.simpleName
|
||||
private const val MOVE = "MOVE"
|
||||
private const val COPY = "COPY"
|
||||
|
||||
const val TAG_LIST_OF_FOLDERS = "LIST_OF_FOLDERS"
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import com.nextcloud.client.onboarding.FirstRunActivity;
|
|||
import com.nextcloud.model.WorkerState;
|
||||
import com.nextcloud.model.WorkerStateLiveData;
|
||||
import com.nextcloud.utils.extensions.BundleExtensionsKt;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
|
@ -131,8 +132,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
|
|||
}
|
||||
|
||||
arbitraryDataProvider = new ArbitraryDataProviderImpl(this);
|
||||
|
||||
multipleAccountsSupported = getResources().getBoolean(R.bool.multiaccount_support);
|
||||
multipleAccountsSupported = MDMConfig.INSTANCE.multiAccountSupport(this);
|
||||
|
||||
userListAdapter = new UserListAdapter(this,
|
||||
accountManager,
|
||||
|
@ -230,7 +230,7 @@ public class ManageAccountsActivity extends FileActivity implements UserListAdap
|
|||
userListItems.add(new UserListItem(user, !pendingForRemoval));
|
||||
}
|
||||
|
||||
if (getResources().getBoolean(R.bool.multiaccount_support)) {
|
||||
if (MDMConfig.INSTANCE.multiAccountSupport(this)) {
|
||||
userListItems.add(new UserListItem());
|
||||
}
|
||||
|
||||
|
|
|
@ -50,15 +50,13 @@ import com.nextcloud.client.network.ConnectivityService;
|
|||
import com.nextcloud.client.preferences.AppPreferences;
|
||||
import com.nextcloud.client.preferences.AppPreferencesImpl;
|
||||
import com.nextcloud.client.preferences.DarkMode;
|
||||
import com.owncloud.android.BuildConfig;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProvider;
|
||||
import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
|
||||
import com.owncloud.android.datamodel.ExternalLinksProvider;
|
||||
import com.owncloud.android.datastorage.DataStorageProvider;
|
||||
import com.owncloud.android.datastorage.StoragePoint;
|
||||
import com.owncloud.android.lib.common.ExternalLink;
|
||||
import com.owncloud.android.lib.common.ExternalLinkType;
|
||||
import com.owncloud.android.lib.common.utils.Log_OC;
|
||||
|
@ -115,6 +113,7 @@ public class SettingsActivity extends PreferenceActivity
|
|||
private static final int ACTION_REQUEST_CODE_DAVDROID_SETUP = 10;
|
||||
private static final int ACTION_SHOW_MNEMONIC = 11;
|
||||
private static final int ACTION_E2E = 12;
|
||||
private static final int ACTION_SET_STORAGE_LOCATION = 13;
|
||||
private static final int TRUE_VALUE = 1;
|
||||
|
||||
private static final String DAV_PATH = "/remote.php/dav";
|
||||
|
@ -128,7 +127,7 @@ public class SettingsActivity extends PreferenceActivity
|
|||
private ThemeableSwitchPreference showEcosystemApps;
|
||||
private AppCompatDelegate delegate;
|
||||
|
||||
private ListPreference prefStoragePath;
|
||||
private Preference prefDataLoc;
|
||||
private String storagePath;
|
||||
private String pendingLock;
|
||||
|
||||
|
@ -379,11 +378,9 @@ public class SettingsActivity extends PreferenceActivity
|
|||
}
|
||||
|
||||
private void setupLoggingPreference(PreferenceCategory preferenceCategoryMore) {
|
||||
|
||||
boolean loggerEnabled = getResources().getBoolean(R.bool.logger_enabled) || BuildConfig.DEBUG;
|
||||
Preference pLogger = findPreference("logger");
|
||||
if (pLogger != null) {
|
||||
if (loggerEnabled) {
|
||||
if (MDMConfig.INSTANCE.isLogEnabled(this)) {
|
||||
pLogger.setOnPreferenceClickListener(preference -> {
|
||||
Intent loggerIntent = new Intent(getApplicationContext(), LogsActivity.class);
|
||||
startActivity(loggerIntent);
|
||||
|
@ -802,34 +799,16 @@ public class SettingsActivity extends PreferenceActivity
|
|||
final PreferenceCategory preferenceCategoryGeneral = (PreferenceCategory) findPreference("general");
|
||||
viewThemeUtils.files.themePreferenceCategory(preferenceCategoryGeneral);
|
||||
|
||||
prefStoragePath = (ListPreference) findPreference(AppPreferencesImpl.STORAGE_PATH);
|
||||
if (prefStoragePath != null) {
|
||||
StoragePoint[] storageOptions = DataStorageProvider.getInstance().getAvailableStoragePoints();
|
||||
String[] entries = new String[storageOptions.length];
|
||||
String[] values = new String[storageOptions.length];
|
||||
for (int i = 0; i < storageOptions.length; ++i) {
|
||||
entries[i] = storageOptions[i].getDescription();
|
||||
values[i] = storageOptions[i].getPath();
|
||||
}
|
||||
prefStoragePath.setEntries(entries);
|
||||
prefStoragePath.setEntryValues(values);
|
||||
|
||||
prefStoragePath.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
String newPath = (String) newValue;
|
||||
|
||||
if (storagePath.equals(newPath)) {
|
||||
return true;
|
||||
}
|
||||
StorageMigration storageMigration = new StorageMigration(this, user, storagePath, newPath, viewThemeUtils);
|
||||
storageMigration.setStorageMigrationProgressListener(this);
|
||||
storageMigration.migrate();
|
||||
|
||||
return false;
|
||||
prefDataLoc = findPreference(AppPreferencesImpl.DATA_STORAGE_LOCATION);
|
||||
if (prefDataLoc != null) {
|
||||
prefDataLoc.setOnPreferenceClickListener(p -> {
|
||||
Intent intent = new Intent(MainApp.getAppContext(), ChooseStorageLocationActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
startActivityForResult(intent, ACTION_SET_STORAGE_LOCATION);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
loadStoragePath();
|
||||
|
||||
ListPreference themePref = (ListPreference) findPreference("darkMode");
|
||||
|
||||
List<String> themeEntries = new ArrayList<>(3);
|
||||
|
@ -996,6 +975,14 @@ public class SettingsActivity extends PreferenceActivity
|
|||
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
|
||||
startActivity(i);
|
||||
} else if (requestCode == ACTION_SET_STORAGE_LOCATION && data != null) {
|
||||
String newPath = data.getStringExtra(ChooseStorageLocationActivity.KEY_RESULT_STORAGE_LOCATION);
|
||||
|
||||
if (!storagePath.equals(newPath)) {
|
||||
StorageMigration storageMigration = new StorageMigration(this, user, storagePath, newPath, viewThemeUtils);
|
||||
storageMigration.setStorageMigrationProgressListener(this);
|
||||
storageMigration.migrate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1101,7 +1088,7 @@ public class SettingsActivity extends PreferenceActivity
|
|||
}
|
||||
|
||||
private void loadExternalSettingLinks(PreferenceCategory preferenceCategory) {
|
||||
if (getBaseContext().getResources().getBoolean(R.bool.show_external_links)) {
|
||||
if (MDMConfig.INSTANCE.externalSiteSupport(this)) {
|
||||
ExternalLinksProvider externalLinksProvider = new ExternalLinksProvider(getContentResolver());
|
||||
|
||||
for (final ExternalLink link : externalLinksProvider.getExternalLink(ExternalLinkType.SETTINGS)) {
|
||||
|
@ -1139,21 +1126,6 @@ public class SettingsActivity extends PreferenceActivity
|
|||
SharedPreferences.Editor editor = appPrefs.edit();
|
||||
editor.putString(AppPreferencesImpl.STORAGE_PATH, storagePath);
|
||||
editor.apply();
|
||||
String storageDescription = DataStorageProvider.getInstance().getStorageDescriptionByPath(storagePath);
|
||||
prefStoragePath.setSummary(storageDescription);
|
||||
prefStoragePath.setValue(newStoragePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load storage path set on preferences
|
||||
*/
|
||||
private void loadStoragePath() {
|
||||
SharedPreferences appPrefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
|
||||
// Load storage path from shared preferences. Use private internal storage by default.
|
||||
storagePath = appPrefs.getString(AppPreferencesImpl.STORAGE_PATH,
|
||||
getApplicationContext().getFilesDir().getAbsolutePath());
|
||||
String storageDescription = DataStorageProvider.getInstance().getStorageDescriptionByPath(storagePath);
|
||||
prefStoragePath.setSummary(storageDescription);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,6 +19,7 @@ import android.graphics.PorterDuff;
|
|||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.FileDetailsShareLinkShareItemBinding;
|
||||
import com.owncloud.android.lib.resources.shares.OCShare;
|
||||
|
@ -78,11 +79,16 @@ class LinkShareViewHolder extends RecyclerView.ViewHolder {
|
|||
String permissionName = SharingMenuHelper.getPermissionName(context, publicShare);
|
||||
setPermissionName(publicShare, permissionName);
|
||||
|
||||
binding.copyLink.setOnClickListener(v -> listener.copyLink(publicShare));
|
||||
binding.overflowMenu.setOnClickListener(v -> listener.showSharingMenuActionSheet(publicShare));
|
||||
if (!SharingMenuHelper.isSecureFileDrop(publicShare)) {
|
||||
binding.shareByLinkContainer.setOnClickListener(v -> listener.showPermissionsDialog(publicShare));
|
||||
}
|
||||
|
||||
if (MDMConfig.INSTANCE.clipBoardSupport(context)) {
|
||||
binding.copyLink.setOnClickListener(v -> listener.copyLink(publicShare));
|
||||
} else {
|
||||
binding.copyLink.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void setPermissionName(OCShare publicShare, String permissionName) {
|
||||
|
|
|
@ -36,9 +36,10 @@ import com.nextcloud.client.account.User;
|
|||
import com.nextcloud.client.database.entity.OfflineOperationEntity;
|
||||
import com.nextcloud.client.jobs.upload.FileUploadHelper;
|
||||
import com.nextcloud.client.preferences.AppPreferences;
|
||||
import com.nextcloud.model.OfflineOperationType;
|
||||
import com.nextcloud.model.OCFileFilterType;
|
||||
import com.nextcloud.model.OfflineOperationType;
|
||||
import com.nextcloud.utils.extensions.ViewExtensionsKt;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.GridImageBinding;
|
||||
|
@ -458,6 +459,10 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
}
|
||||
|
||||
updateLivePhotoIndicators(gridViewHolder, file);
|
||||
|
||||
if (!MDMConfig.INSTANCE.sharingSupport(activity)) {
|
||||
gridViewHolder.getShared().setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,28 +612,11 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
localSize = localFile.length();
|
||||
}
|
||||
|
||||
holder.getFileSize().setVisibility(View.VISIBLE);
|
||||
|
||||
|
||||
if (file.isOfflineOperation()) {
|
||||
holder.getFileSize().setText(MainApp.string(R.string.oc_file_list_adapter_offline_operation_description_text));
|
||||
} else {
|
||||
holder.getFileSize().setText(DisplayUtils.bytesToHumanReadable(localSize));
|
||||
}
|
||||
|
||||
holder.getFileSizeSeparator().setVisibility(View.VISIBLE);
|
||||
prepareFileSize(holder, file, localSize);
|
||||
} else {
|
||||
final long fileLength = file.getFileLength();
|
||||
if (fileLength >= 0) {
|
||||
holder.getFileSize().setVisibility(View.VISIBLE);
|
||||
|
||||
if (file.isOfflineOperation()) {
|
||||
holder.getFileSize().setText(MainApp.string(R.string.oc_file_list_adapter_offline_operation_description_text));
|
||||
} else {
|
||||
holder.getFileSize().setText(DisplayUtils.bytesToHumanReadable(fileLength));
|
||||
}
|
||||
|
||||
holder.getFileSizeSeparator().setVisibility(View.VISIBLE);
|
||||
prepareFileSize(holder, file, fileLength);
|
||||
} else {
|
||||
holder.getFileSize().setVisibility(View.GONE);
|
||||
holder.getFileSizeSeparator().setVisibility(View.GONE);
|
||||
|
@ -666,6 +654,28 @@ public class OCFileListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
applyVisualsForOfflineOperations(holder, file);
|
||||
}
|
||||
|
||||
private void prepareFileSize(ListItemViewHolder holder, OCFile file, long size) {
|
||||
holder.getFileSize().setVisibility(View.VISIBLE);
|
||||
ViewExtensionsKt.setVisibleIf(holder.getFileSizeSeparator(), !file.isOfflineOperation());
|
||||
String fileSizeText = getFileSizeText(file, size);
|
||||
holder.getFileSize().setText(fileSizeText);
|
||||
}
|
||||
|
||||
private String getFileSizeText(OCFile file, long size) {
|
||||
OfflineOperationEntity entity = mStorageManager.getOfflineEntityFromOCFile(file);
|
||||
boolean isRemoveOperation = entity != null && entity.getType() instanceof OfflineOperationType.RemoveFile;
|
||||
|
||||
if (isRemoveOperation) {
|
||||
return activity.getString(R.string.oc_file_list_adapter_offline_operation_remove_description_text);
|
||||
}
|
||||
|
||||
if (file.isOfflineOperation()) {
|
||||
return activity.getString(R.string.oc_file_list_adapter_offline_operation_description_text);
|
||||
}
|
||||
|
||||
return DisplayUtils.bytesToHumanReadable(size);
|
||||
}
|
||||
|
||||
private void applyVisualsForOfflineOperations(ListItemViewHolder holder, OCFile file) {
|
||||
ViewExtensionsKt.setVisibleIf(holder.getShared(), !file.isOfflineOperation());
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.nextcloud.client.jobs.download.FileDownloadHelper
|
|||
import com.nextcloud.client.jobs.upload.FileUploadHelper
|
||||
import com.nextcloud.client.preferences.AppPreferences
|
||||
import com.nextcloud.utils.extensions.createRoundedOutline
|
||||
import com.nextcloud.utils.mdm.MDMConfig
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager
|
||||
import com.owncloud.android.datamodel.OCFile
|
||||
|
@ -368,6 +369,12 @@ class OCFileListDelegate(
|
|||
|
||||
private fun showShareIcon(gridViewHolder: ListViewHolder, file: OCFile) {
|
||||
val sharedIconView = gridViewHolder.shared
|
||||
|
||||
if (!MDMConfig.sharingSupport(context)) {
|
||||
sharedIconView.visibility = View.GONE
|
||||
return
|
||||
}
|
||||
|
||||
if (gridViewHolder is OCFileListItemViewHolder || file.unreadCommentsCount == 0) {
|
||||
sharedIconView.visibility = View.VISIBLE
|
||||
if (file.isSharedWithSharee || file.isSharedWithMe) {
|
||||
|
|
|
@ -14,10 +14,12 @@ package com.owncloud.android.ui.adapter;
|
|||
import android.annotation.SuppressLint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.FileDetailsShareInternalShareLinkBinding;
|
||||
import com.owncloud.android.databinding.FileDetailsShareLinkShareItemBinding;
|
||||
|
@ -79,43 +81,51 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
@NonNull
|
||||
@Override
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
switch (ShareType.fromValue(viewType)) {
|
||||
case PUBLIC_LINK, EMAIL -> {
|
||||
return new LinkShareViewHolder(
|
||||
FileDetailsShareLinkShareItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
parent,
|
||||
false),
|
||||
fileActivity,
|
||||
viewThemeUtils);
|
||||
}
|
||||
case NEW_PUBLIC_LINK -> {
|
||||
if (encrypted) {
|
||||
return new NewSecureFileDropViewHolder(
|
||||
FileDetailsShareSecureFileDropAddNewItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
boolean shareViaLink = MDMConfig.INSTANCE.shareViaLink(fileActivity);
|
||||
|
||||
if (shareViaLink) {
|
||||
switch (ShareType.fromValue(viewType)) {
|
||||
case PUBLIC_LINK, EMAIL -> {
|
||||
return new LinkShareViewHolder(
|
||||
FileDetailsShareLinkShareItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
parent,
|
||||
false),
|
||||
fileActivity,
|
||||
viewThemeUtils);
|
||||
}
|
||||
case NEW_PUBLIC_LINK -> {
|
||||
if (encrypted) {
|
||||
return new NewSecureFileDropViewHolder(
|
||||
FileDetailsShareSecureFileDropAddNewItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
parent,
|
||||
false)
|
||||
);
|
||||
} else {
|
||||
return new NewLinkShareViewHolder(
|
||||
FileDetailsSharePublicLinkAddNewItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
parent,
|
||||
false)
|
||||
);
|
||||
} else {
|
||||
return new NewLinkShareViewHolder(
|
||||
FileDetailsSharePublicLinkAddNewItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
parent,
|
||||
false)
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
case INTERNAL -> {
|
||||
return new InternalShareViewHolder(
|
||||
FileDetailsShareInternalShareLinkBinding.inflate(LayoutInflater.from(fileActivity), parent, false),
|
||||
fileActivity);
|
||||
}
|
||||
default -> {
|
||||
return new ShareViewHolder(FileDetailsShareShareItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
parent,
|
||||
false),
|
||||
user,
|
||||
fileActivity,
|
||||
viewThemeUtils);
|
||||
}
|
||||
}
|
||||
case INTERNAL -> {
|
||||
return new InternalShareViewHolder(
|
||||
FileDetailsShareInternalShareLinkBinding.inflate(LayoutInflater.from(fileActivity), parent, false),
|
||||
fileActivity);
|
||||
}
|
||||
default -> {
|
||||
return new ShareViewHolder(FileDetailsShareShareItemBinding.inflate(LayoutInflater.from(fileActivity),
|
||||
parent,
|
||||
false),
|
||||
user,
|
||||
fileActivity,
|
||||
viewThemeUtils);
|
||||
}
|
||||
} else {
|
||||
return new InternalShareViewHolder(
|
||||
FileDetailsShareInternalShareLinkBinding.inflate(LayoutInflater.from(fileActivity), parent, false),
|
||||
fileActivity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,6 +137,16 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
|
||||
final OCShare share = shares.get(position);
|
||||
|
||||
boolean shareViaLink = MDMConfig.INSTANCE.shareViaLink(fileActivity);
|
||||
|
||||
if (!shareViaLink) {
|
||||
if (holder instanceof InternalShareViewHolder internalShareViewHolder) {
|
||||
internalShareViewHolder.bind(share, listener);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (holder instanceof LinkShareViewHolder publicShareViewHolder) {
|
||||
publicShareViewHolder.bind(share, listener);
|
||||
} else if (holder instanceof InternalShareViewHolder internalShareViewHolder) {
|
||||
|
@ -148,7 +168,12 @@ public class ShareeListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol
|
|||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return shares.size();
|
||||
boolean shareViaLink = MDMConfig.INSTANCE.shareViaLink(fileActivity);
|
||||
if (shareViaLink) {
|
||||
return shares.size();
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.widget.ImageView;
|
|||
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.nextcloud.client.account.UserAccountManager;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.AccountActionBinding;
|
||||
import com.owncloud.android.databinding.AccountItemBinding;
|
||||
|
@ -94,7 +95,9 @@ public class UserListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||
viewThemeUtils);
|
||||
} else {
|
||||
return new AddAccountViewHolderItem(
|
||||
AccountActionBinding.inflate(LayoutInflater.from(context), parent, false));
|
||||
AccountActionBinding.inflate(LayoutInflater.from(context), parent, false),
|
||||
context
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -303,8 +306,11 @@ public class UserListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||
*/
|
||||
static class AddAccountViewHolderItem extends RecyclerView.ViewHolder {
|
||||
|
||||
AddAccountViewHolderItem(@NonNull AccountActionBinding binding) {
|
||||
private final Context context;
|
||||
|
||||
AddAccountViewHolderItem(@NonNull AccountActionBinding binding, Context context) {
|
||||
super(binding.getRoot());
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -313,11 +319,12 @@ public class UserListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
|
|||
* @param accountListAdapterListener {@link Listener}
|
||||
*/
|
||||
private void bind(Listener accountListAdapterListener) {
|
||||
// bind action listener
|
||||
boolean isProviderOrOwnInstallationVisible = itemView.getContext().getResources()
|
||||
.getBoolean(R.bool.show_provider_or_own_installation);
|
||||
if (context == null) {
|
||||
Log_OC.d(TAG,"Context cannot be null, AddAccountViewHolderItem onClick is disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isProviderOrOwnInstallationVisible) {
|
||||
if (MDMConfig.INSTANCE.showIntro(context)) {
|
||||
itemView.setOnClickListener(v -> accountListAdapterListener.showFirstRunActivity());
|
||||
} else {
|
||||
itemView.setOnClickListener(v -> accountListAdapterListener.startAccountCreation());
|
||||
|
|
|
@ -65,7 +65,7 @@ class MultipleAccountsDialog : DialogFragment(), Injectable, UserListAdapter.Cli
|
|||
private val accountListItems: List<UserListItem>
|
||||
/**
|
||||
* creates the account list items list including the add-account action in case
|
||||
* multiaccount_support is enabled.
|
||||
* multi account support is enabled.
|
||||
*
|
||||
* @return list of account list items
|
||||
*/
|
||||
|
|
|
@ -90,17 +90,33 @@ class RemoveFilesDialogFragment : ConfirmationDialogFragment(), ConfirmationDial
|
|||
fileDataStorageManager.deleteOfflineOperation(it)
|
||||
}
|
||||
|
||||
if (files.isNotEmpty()) {
|
||||
val cg = activity as ComponentsGetter?
|
||||
cg?.fileOperationsHelper?.removeFiles(files, onlyLocalCopy, false)
|
||||
}
|
||||
if (requireActivity() is FileDisplayActivity) {
|
||||
val activity = requireActivity() as FileDisplayActivity
|
||||
activity.connectivityService.isNetworkAndServerAvailable { result ->
|
||||
if (result) {
|
||||
if (files.isNotEmpty()) {
|
||||
val cg = activity as ComponentsGetter?
|
||||
cg?.fileOperationsHelper?.removeFiles(files, onlyLocalCopy, false)
|
||||
}
|
||||
|
||||
if (offlineFiles.isNotEmpty()) {
|
||||
val activity = requireActivity() as? FileDisplayActivity
|
||||
activity?.refreshCurrentDirectory()
|
||||
}
|
||||
if (offlineFiles.isNotEmpty()) {
|
||||
activity.refreshCurrentDirectory()
|
||||
}
|
||||
} else {
|
||||
files.forEach { file ->
|
||||
fileDataStorageManager.addRemoveFileOfflineOperation(
|
||||
file.decryptedRemotePath,
|
||||
file.fileName,
|
||||
file.parentId
|
||||
)
|
||||
}
|
||||
|
||||
finishActionMode()
|
||||
activity.refreshCurrentDirectory()
|
||||
}
|
||||
|
||||
finishActionMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onNeutral(callerTag: String?) {
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.nextcloud.android.common.ui.theme.utils.ColorRole
|
|||
import com.nextcloud.client.di.Injectable
|
||||
import com.nextcloud.client.utils.IntentUtil.createSendIntent
|
||||
import com.nextcloud.utils.extensions.getParcelableArgument
|
||||
import com.nextcloud.utils.mdm.MDMConfig
|
||||
import com.owncloud.android.BuildConfig
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.databinding.SendShareFragmentBinding
|
||||
|
@ -73,7 +74,12 @@ class SendShareDialog : BottomSheetDialogFragment(R.layout.send_share_fragment),
|
|||
binding = SendShareFragmentBinding.inflate(inflater, container, false)
|
||||
|
||||
binding.btnShare.setOnClickListener { shareFile(file) }
|
||||
binding.btnLink.setOnClickListener { shareByLink() }
|
||||
|
||||
if (MDMConfig.shareViaLink(requireContext()) && MDMConfig.clipBoardSupport(requireContext())) {
|
||||
binding.btnLink.setOnClickListener { shareByLink() }
|
||||
} else {
|
||||
binding.btnLink.visibility = View.GONE
|
||||
}
|
||||
|
||||
applyTintColor()
|
||||
setupBottomSheetBehaviour()
|
||||
|
@ -85,6 +91,10 @@ class SendShareDialog : BottomSheetDialogFragment(R.layout.send_share_fragment),
|
|||
|
||||
@Suppress("MagicNumber")
|
||||
private fun setupSendButtonRecyclerView() {
|
||||
if (!MDMConfig.sendFilesSupport(requireContext())) {
|
||||
return
|
||||
}
|
||||
|
||||
val sendIntent = createSendIntent(requireContext(), file!!)
|
||||
val sendButtonDataList = setupSendButtonData(sendIntent)
|
||||
val clickListener = setupSendButtonClickListener(sendIntent)
|
||||
|
|
|
@ -36,6 +36,7 @@ import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
|
|||
import com.nextcloud.utils.MenuUtils;
|
||||
import com.nextcloud.utils.extensions.BundleExtensionsKt;
|
||||
import com.nextcloud.utils.extensions.FileExtensionsKt;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.FileDetailsFragmentBinding;
|
||||
|
@ -841,6 +842,10 @@ public class FileDetailFragment extends FileFragment implements OnClickListener,
|
|||
}
|
||||
|
||||
private boolean showSharingTab() {
|
||||
if (!MDMConfig.INSTANCE.shareViaLink(requireContext()) && !MDMConfig.INSTANCE.shareViaUser(requireContext())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (getFile().isEncrypted()) {
|
||||
if (parentFolder == null) {
|
||||
parentFolder = storageManager.getFileById(getFile().getParentId());
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.nextcloud.client.di.Injectable;
|
|||
import com.nextcloud.client.network.ClientFactory;
|
||||
import com.nextcloud.utils.extensions.BundleExtensionsKt;
|
||||
import com.nextcloud.utils.extensions.FileExtensionsKt;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.FileDetailsSharingFragmentBinding;
|
||||
import com.owncloud.android.datamodel.FileDataStorageManager;
|
||||
|
@ -244,6 +245,14 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
|
|||
binding.pickContactEmailBtn.setVisibility(View.GONE);
|
||||
disableSearchView(binding.searchView);
|
||||
}
|
||||
|
||||
checkShareViaUser();
|
||||
}
|
||||
|
||||
private void checkShareViaUser() {
|
||||
if (!MDMConfig.INSTANCE.shareViaUser(requireContext())) {
|
||||
binding.searchContainer.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void disableSearchView(View view) {
|
||||
|
@ -494,9 +503,13 @@ public class FileDetailSharingFragment extends Fragment implements ShareeListAda
|
|||
}
|
||||
|
||||
private void pickContactEmail() {
|
||||
Intent intent = new Intent(Intent.ACTION_PICK);
|
||||
intent.setDataAndType(ContactsContract.Contacts.CONTENT_URI, ContactsContract.CommonDataKinds.Email.CONTENT_TYPE);
|
||||
onContactSelectionResultLauncher.launch(intent);
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Email.CONTENT_URI);
|
||||
|
||||
if (intent.resolveActivity(requireContext().getPackageManager()) != null) {
|
||||
onContactSelectionResultLauncher.launch(intent);
|
||||
} else {
|
||||
DisplayUtils.showSnackMessage(requireActivity(), getString(R.string.file_detail_sharing_fragment_no_contact_app_message));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleContactResult(@NonNull Uri contactUri) {
|
||||
|
|
|
@ -16,6 +16,7 @@ import android.view.ViewGroup;
|
|||
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialog;
|
||||
import com.nextcloud.utils.mdm.MDMConfig;
|
||||
import com.owncloud.android.databinding.FileDetailsSharingMenuBottomSheetFragmentBinding;
|
||||
import com.owncloud.android.lib.resources.shares.OCShare;
|
||||
import com.owncloud.android.lib.resources.shares.ShareType;
|
||||
|
@ -72,7 +73,10 @@ public class FileDetailSharingMenuBottomSheetDialog extends BottomSheetDialog {
|
|||
private void updateUI() {
|
||||
if (ocShare.getShareType() == ShareType.PUBLIC_LINK) {
|
||||
binding.menuShareAddAnotherLink.setVisibility(View.VISIBLE);
|
||||
binding.menuShareSendLink.setVisibility(View.VISIBLE);
|
||||
|
||||
if (MDMConfig.INSTANCE.sendFilesSupport(getContext())) {
|
||||
binding.menuShareSendLink.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else {
|
||||
binding.menuShareAddAnotherLink.setVisibility(View.GONE);
|
||||
binding.menuShareSendLink.setVisibility(View.GONE);
|
||||
|
|
|
@ -60,13 +60,9 @@ public final class BitmapUtils {
|
|||
}
|
||||
|
||||
public static Bitmap addColorFilter(Bitmap originalBitmap, int filterColor, int opacity) {
|
||||
int width = originalBitmap.getWidth();
|
||||
int height = originalBitmap.getHeight();
|
||||
|
||||
Bitmap resultBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Bitmap resultBitmap = originalBitmap.copy(Bitmap.Config.ARGB_8888, true);
|
||||
Canvas canvas = new Canvas(resultBitmap);
|
||||
|
||||
canvas.drawBitmap(originalBitmap, 0, 0, null);
|
||||
canvas.drawBitmap(resultBitmap, 0, 0, null);
|
||||
|
||||
Paint paint = new Paint();
|
||||
paint.setColor(filterColor);
|
||||
|
@ -74,7 +70,7 @@ public final class BitmapUtils {
|
|||
paint.setAlpha(opacity);
|
||||
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
|
||||
canvas.drawRect(0, 0, width, height, paint);
|
||||
canvas.drawRect(0, 0, resultBitmap.getWidth(), resultBitmap.getHeight(), paint);
|
||||
|
||||
return resultBitmap;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import android.content.ClipboardManager
|
|||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import android.widget.Toast
|
||||
import com.nextcloud.utils.mdm.MDMConfig
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
|
||||
|
@ -25,6 +26,10 @@ object ClipboardUtil {
|
|||
@JvmOverloads
|
||||
@Suppress("TooGenericExceptionCaught")
|
||||
fun copyToClipboard(activity: Activity, text: String?, showToast: Boolean = true) {
|
||||
if (!MDMConfig.clipBoardSupport(activity)) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(text)) {
|
||||
try {
|
||||
val clip = ClipData.newPlainText(
|
||||
|
|
|
@ -13,5 +13,11 @@ package com.owncloud.android.utils.appConfig
|
|||
enum class AppConfigKeys(val key: String) {
|
||||
BaseUrl("base_url"),
|
||||
ProxyHost("proxy_host"),
|
||||
ProxyPort("proxy_port")
|
||||
ProxyPort("proxy_port"),
|
||||
DisableMultiAccount("disable_multiaccount"),
|
||||
DisableSharing("disable_sharing"),
|
||||
DisableClipboard("disable_clipboard"),
|
||||
DisableMoreExternalSite("disable_more_external_site"),
|
||||
DisableIntro("disable_intro"),
|
||||
DisableLog("disable_log")
|
||||
}
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Alper Ozturk <alper.ozturk@nextcloud.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.appConfig
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.os.Bundle
|
||||
import android.text.TextUtils
|
||||
import com.owncloud.android.R
|
||||
import com.owncloud.android.lib.common.OwnCloudClientManagerFactory
|
||||
import com.owncloud.android.lib.common.utils.Log_OC
|
||||
|
||||
class AppConfigManager(private val context: Context, private val appRestrictions: Bundle) {
|
||||
|
||||
private val tag = "AppConfigManager"
|
||||
|
||||
fun setProxyConfig(isBrandedPlus: Boolean) {
|
||||
if (!isBrandedPlus) {
|
||||
Log_OC.d(tag, "Proxy configuration cannot be set. Client is not branded plus.")
|
||||
return
|
||||
}
|
||||
|
||||
val host = if (appRestrictions.containsKey(AppConfigKeys.ProxyHost.key)) {
|
||||
appRestrictions.getString(AppConfigKeys.ProxyHost.key)
|
||||
} else {
|
||||
context.getString(R.string.proxy_host)
|
||||
}
|
||||
|
||||
val port = if (appRestrictions.containsKey(AppConfigKeys.ProxyPort.key)) {
|
||||
appRestrictions.getInt(AppConfigKeys.ProxyPort.key)
|
||||
} else {
|
||||
context.resources.getInteger(R.integer.proxy_port)
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(host) || port == -1) {
|
||||
Log_OC.d(tag, "Proxy configuration cannot be found")
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
OwnCloudClientManagerFactory.setProxyHost(host)
|
||||
OwnCloudClientManagerFactory.setProxyPort(port)
|
||||
|
||||
Log_OC.d(tag, "Proxy configuration successfully set")
|
||||
} catch (e: Resources.NotFoundException) {
|
||||
Log_OC.e(tag, "Proxy config cannot able to set due to: $e")
|
||||
}
|
||||
}
|
||||
|
||||
fun getBaseUrl(isBrandedPlus: Boolean): String? {
|
||||
if (!isBrandedPlus) {
|
||||
Log_OC.d(tag, "Proxy configuration cannot be set. Client is not branded plus. Default url applied")
|
||||
return null
|
||||
}
|
||||
|
||||
return if (appRestrictions.containsKey(AppConfigKeys.BaseUrl.key)) {
|
||||
appRestrictions.getString(AppConfigKeys.BaseUrl.key)
|
||||
} else {
|
||||
Log_OC.d(tag, "BaseUrl configuration cannot be found, default url applied")
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
47
app/src/main/res/layout/dialog_data_storage_location.xml
Normal file
47
app/src/main/res/layout/dialog_data_storage_location.xml
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Nextcloud - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 ZetaTom <70907959+ZetaTom@users.noreply.github.com>
|
||||
~ SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingHorizontal="@dimen/dialog_padding">
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/storage_radioGroup"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/storage_internal_radio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:enabled="false"
|
||||
android:text="@string/storage_internal_storage" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/storage_external_radio"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:enabled="false"
|
||||
android:text="@string/storage_external_storage" />
|
||||
</RadioGroup>
|
||||
|
||||
<com.google.android.material.materialswitch.MaterialSwitch
|
||||
android:id="@+id/allow_media_index_switch"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:enabled="false"
|
||||
android:text="@string/file_migration_allow_media_indexing"
|
||||
app:layout_constraintTop_toBottomOf="@+id/storage_radioGroup"
|
||||
tools:layout_editor_absoluteX="24dp" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -693,7 +693,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">مقترحات بتطبيقات من نكست كلاود في شريط التصفح navigation heading</string>
|
||||
<string name="prefs_show_hidden_files">عرض الملفات المخفية</string>
|
||||
<string name="prefs_sourcecode">الحصول على الشفرة المصدرية</string>
|
||||
<string name="prefs_storage_path">مجلد تخزين البيانات</string>
|
||||
<string name="prefs_data_storage_location">مجلد تخزين البيانات</string>
|
||||
<string name="prefs_sycned_folders_summary">إدارة الملفات للتحميل التلقائي</string>
|
||||
<string name="prefs_synced_folders_local_path_title">مجلد محلي</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">مجلد عن بعد</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud app suggestions in navigation heading</string>
|
||||
<string name="prefs_show_hidden_files">Show hidden files</string>
|
||||
<string name="prefs_sourcecode">Get source code</string>
|
||||
<string name="prefs_storage_path">Data storage folder</string>
|
||||
<string name="prefs_data_storage_location">Data storage folder</string>
|
||||
<string name="prefs_sycned_folders_summary">Manage folders for auto upload</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Local folder</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Remote folder</string>
|
||||
|
|
|
@ -581,7 +581,7 @@
|
|||
<string name="prefs_setup_e2e">Настройка на цялостно криптиране</string>
|
||||
<string name="prefs_show_hidden_files">Показване и на скрити файлове</string>
|
||||
<string name="prefs_sourcecode">Получаване на изходния код</string>
|
||||
<string name="prefs_storage_path">Папка за съхранение на данни</string>
|
||||
<string name="prefs_data_storage_location">Папка за съхранение на данни</string>
|
||||
<string name="prefs_sycned_folders_summary">Управление на папки за автоматично качване</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Локална папка</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Отдалечена папка</string>
|
||||
|
|
|
@ -600,7 +600,7 @@
|
|||
<string name="prefs_setup_e2e">Configureu el xifratge d\'extrem a extrem</string>
|
||||
<string name="prefs_show_hidden_files">Mostra els fitxers ocults</string>
|
||||
<string name="prefs_sourcecode">Aconseguiu el codi font</string>
|
||||
<string name="prefs_storage_path">Carpeta de dades</string>
|
||||
<string name="prefs_data_storage_location">Carpeta de dades</string>
|
||||
<string name="prefs_sycned_folders_summary">Gestiona les carpetes per a la pujada automàtica</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Carpeta local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Carpeta remota</string>
|
||||
|
|
|
@ -689,7 +689,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Doporučování Nextcloud aplikací v záhlaví navigace</string>
|
||||
<string name="prefs_show_hidden_files">Zobrazit skryté soubory</string>
|
||||
<string name="prefs_sourcecode">Získat zdrojové kódy</string>
|
||||
<string name="prefs_storage_path">Složka pro ukládání dat</string>
|
||||
<string name="prefs_data_storage_location">Složka pro ukládání dat</string>
|
||||
<string name="prefs_sycned_folders_summary">Spravovat složky pro automatické nahrávání</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Místní složka</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Vzdálená složka</string>
|
||||
|
|
|
@ -632,7 +632,7 @@ Enheds legitimationsoplysninger er sat op
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud app anbefalinger i navigationspanelet</string>
|
||||
<string name="prefs_show_hidden_files">Vis skjulte filer</string>
|
||||
<string name="prefs_sourcecode">Hent kildetekst</string>
|
||||
<string name="prefs_storage_path">Lagringsmappe for data</string>
|
||||
<string name="prefs_data_storage_location">Lagringsmappe for data</string>
|
||||
<string name="prefs_sycned_folders_summary">Administrér mapper til auto upload</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Lokal mappe</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Ekstern mappe</string>
|
||||
|
|
|
@ -689,7 +689,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud-App-Vorschläge in der Navigationsüberschrift</string>
|
||||
<string name="prefs_show_hidden_files">Versteckte Dateien anzeigen</string>
|
||||
<string name="prefs_sourcecode">Zum Programmcode</string>
|
||||
<string name="prefs_storage_path">Speicherordner</string>
|
||||
<string name="prefs_data_storage_location">Speicherordner</string>
|
||||
<string name="prefs_sycned_folders_summary">Ordner für \"Automatisches Hochladen\" verwalten</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Lokaler Ordner</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Remote-Ordner</string>
|
||||
|
|
|
@ -587,7 +587,7 @@
|
|||
<string name="prefs_setup_e2e">Ρύθμιση κρυπτογράφησης από άκρο σε άκρο</string>
|
||||
<string name="prefs_show_hidden_files">Εμφάνιση κρυφών αρχείων</string>
|
||||
<string name="prefs_sourcecode">Λήψη πηγαίου κώδικα</string>
|
||||
<string name="prefs_storage_path">Φάκελος αποθήκευσης δεδομένων</string>
|
||||
<string name="prefs_data_storage_location">Φάκελος αποθήκευσης δεδομένων</string>
|
||||
<string name="prefs_sycned_folders_summary">Διαχείριση φακέλων για αυτόματη μεταφόρτωση</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Τοπικός φάκελος</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Απομακρυσμένος φάκελος</string>
|
||||
|
|
|
@ -655,7 +655,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Sugerencias de aplicaciones de Nextcloud en el encabezado de navegación</string>
|
||||
<string name="prefs_show_hidden_files">Mostrar archivos ocultos</string>
|
||||
<string name="prefs_sourcecode">Obtener el código fuente</string>
|
||||
<string name="prefs_storage_path">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_data_storage_location">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_sycned_folders_summary">Administrar carpetas para carga automática</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Carpeta local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Carpeta remota</string>
|
||||
|
|
|
@ -589,7 +589,7 @@
|
|||
<string name="prefs_setup_e2e">Configurar encriptación de extremo a extremo</string>
|
||||
<string name="prefs_show_hidden_files">Mostrar archivos ocultos</string>
|
||||
<string name="prefs_sourcecode">Obtener el código fuente</string>
|
||||
<string name="prefs_storage_path">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_data_storage_location">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_sycned_folders_summary">Administrar carpetas para carga automática</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Carpeta local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Carpeta remota</string>
|
||||
|
|
|
@ -655,7 +655,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Sugerencias de aplicaciones de Nextcloud en el encabezado de navegación</string>
|
||||
<string name="prefs_show_hidden_files">Mostrar archivos ocultos</string>
|
||||
<string name="prefs_sourcecode">Obtener el código fuente</string>
|
||||
<string name="prefs_storage_path">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_data_storage_location">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_sycned_folders_summary">Administrar carpetas para carga automática</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Carpeta local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Carpeta remota</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Sugerencias de Nextcloud app en encabezado de navegación</string>
|
||||
<string name="prefs_show_hidden_files">Mostrar archivos ocultos</string>
|
||||
<string name="prefs_sourcecode">Obtener el código fuente</string>
|
||||
<string name="prefs_storage_path">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_data_storage_location">Carpeta de almacenamiento de datos</string>
|
||||
<string name="prefs_sycned_folders_summary">Administrar carpetas para auto-subida</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Carpeta local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Carpeta remota</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud aplikazioaren iradokizunak nabigazio goiburuan</string>
|
||||
<string name="prefs_show_hidden_files">Erakutsi ezkutuko fitxategiak</string>
|
||||
<string name="prefs_sourcecode">Eskuratu iturburu-kodea</string>
|
||||
<string name="prefs_storage_path">Datu-biltegiratze karpeta</string>
|
||||
<string name="prefs_data_storage_location">Datu-biltegiratze karpeta</string>
|
||||
<string name="prefs_sycned_folders_summary">Kudeatu karpeten igotze automatikoa</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Karpeta lokala</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Urruneko karpeta</string>
|
||||
|
|
|
@ -628,7 +628,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud app suggestions in navigation heading</string>
|
||||
<string name="prefs_show_hidden_files">فایل های مخفی را نشان بده </string>
|
||||
<string name="prefs_sourcecode">دریافت کد منبع</string>
|
||||
<string name="prefs_storage_path">مسیر ذخیرهسازی</string>
|
||||
<string name="prefs_data_storage_location">مسیر ذخیرهسازی</string>
|
||||
<string name="prefs_sycned_folders_summary">مدیریت پوشهها جهت آپلود خودکار</string>
|
||||
<string name="prefs_synced_folders_local_path_title">پوشه محلی</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">پوشه از راه دور</string>
|
||||
|
|
|
@ -643,7 +643,7 @@ GNU yleinen lisenssi, versio 2</string>
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud-sovellusehdotukset navigointipalkissa</string>
|
||||
<string name="prefs_show_hidden_files">Näytä piilotetut tiedostot</string>
|
||||
<string name="prefs_sourcecode">Hanki lähdekoodi</string>
|
||||
<string name="prefs_storage_path">Tiedostojen tallennuskansio</string>
|
||||
<string name="prefs_data_storage_location">Tiedostojen tallennuskansio</string>
|
||||
<string name="prefs_sycned_folders_summary">Hallinnoi kansioita automaattista latausta varten</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Paikallinen kansio</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Etäkansio</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Suggestions d\'applications Nextcloud dans l\'en-tête de navigation</string>
|
||||
<string name="prefs_show_hidden_files">Afficher les fichiers masqués</string>
|
||||
<string name="prefs_sourcecode">Obtenir le code source</string>
|
||||
<string name="prefs_storage_path">Dossier de stockage des données</string>
|
||||
<string name="prefs_data_storage_location">Dossier de stockage des données</string>
|
||||
<string name="prefs_sycned_folders_summary">Gérer les dossiers pour le téléversement automatique</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Dossier local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Dossier distant</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Moltaí aip Nextcloud sa cheannteideal nascleanúna</string>
|
||||
<string name="prefs_show_hidden_files">Taispeáin comhaid i bhfolach</string>
|
||||
<string name="prefs_sourcecode">Faigh cód foinse</string>
|
||||
<string name="prefs_storage_path">Fillteán stórála sonraí</string>
|
||||
<string name="prefs_data_storage_location">Fillteán stórála sonraí</string>
|
||||
<string name="prefs_sycned_folders_summary">Bainistigh fillteáin le haghaidh uaslódáil uathoibríoch</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Fillteán áitiúil</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Fillteán cianda</string>
|
||||
|
|
|
@ -495,7 +495,7 @@
|
|||
<string name="prefs_manage_accounts">Stiùirich cunntasan</string>
|
||||
<string name="prefs_show_hidden_files">Seall faidhlichean falaichte</string>
|
||||
<string name="prefs_sourcecode">Faigh am bun-tùs</string>
|
||||
<string name="prefs_storage_path">Pasgan stòradh dàta</string>
|
||||
<string name="prefs_data_storage_location">Pasgan stòradh dàta</string>
|
||||
<string name="prefs_sycned_folders_summary">Stiùirich pasganan an luchdaidh suas fhèin-obrachail</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Pasgan ionadail</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Pasgan cèin</string>
|
||||
|
|
|
@ -689,7 +689,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Suxestións da aplicación Nextcloud no título de navegación</string>
|
||||
<string name="prefs_show_hidden_files">Amosar ficheiros agochados</string>
|
||||
<string name="prefs_sourcecode">Obter o código fonte</string>
|
||||
<string name="prefs_storage_path">Cartafol de almacenamento de datos</string>
|
||||
<string name="prefs_data_storage_location">Cartafol de almacenamento de datos</string>
|
||||
<string name="prefs_sycned_folders_summary">Xestionar os cartafoles para a envío automático</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Cartafol local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Cartafol remoto</string>
|
||||
|
|
|
@ -550,7 +550,7 @@
|
|||
<string name="prefs_recommend">Preporuči prijatelju</string>
|
||||
<string name="prefs_show_hidden_files">Prikaz skrivenih datoteka</string>
|
||||
<string name="prefs_sourcecode">Preuzmi izvorni kod</string>
|
||||
<string name="prefs_storage_path">Mapa za pohranu podataka</string>
|
||||
<string name="prefs_data_storage_location">Mapa za pohranu podataka</string>
|
||||
<string name="prefs_sycned_folders_summary">Upravljanje mapama za automatsko otpremanje</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Lokalna mapa</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Udaljena mapa</string>
|
||||
|
|
|
@ -612,7 +612,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud alkalmazásjavaslatok a navigációs fejlécben</string>
|
||||
<string name="prefs_show_hidden_files">Rejtett fájlok megjelenítése</string>
|
||||
<string name="prefs_sourcecode">Forráskód beszerzése</string>
|
||||
<string name="prefs_storage_path">Adattároló mappa</string>
|
||||
<string name="prefs_data_storage_location">Adattároló mappa</string>
|
||||
<string name="prefs_sycned_folders_summary">Mappák kezelése az automatikus feltöltéshez</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Helyi mappa</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Távoli mappa</string>
|
||||
|
|
|
@ -608,7 +608,7 @@ Otomatis unggah hanya bekerja dengan baik apabila Anda mengeluarkan aplikasi ini
|
|||
<string name="prefs_show_ecosystem_apps_summary">Saran aplikasi Nextcloud dalam judul navigasi</string>
|
||||
<string name="prefs_show_hidden_files">Lihat berkas tersembunyi</string>
|
||||
<string name="prefs_sourcecode">Dapatkan kode sumber</string>
|
||||
<string name="prefs_storage_path"> Folder penyimpanan data</string>
|
||||
<string name="prefs_data_storage_location"> Folder penyimpanan data</string>
|
||||
<string name="prefs_sycned_folders_summary">Kelola folder untuk pengunggahan otomatis</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Berkas lokal</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Folder remot</string>
|
||||
|
|
|
@ -591,7 +591,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Tillögur Nextcloud-forrita í flakkfyrirsögn</string>
|
||||
<string name="prefs_show_hidden_files">Sýna faldar skrár</string>
|
||||
<string name="prefs_sourcecode">Náðu í grunnkóðann</string>
|
||||
<string name="prefs_storage_path">Mappa fyrir geymslu gagna</string>
|
||||
<string name="prefs_data_storage_location">Mappa fyrir geymslu gagna</string>
|
||||
<string name="prefs_sycned_folders_summary">Sýsla með möppur vegna sjálfvirkra innsendinga</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Staðvær mappa</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Fjartengd mappa</string>
|
||||
|
|
|
@ -632,7 +632,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Consigli delle applicazioni di Nextcloud nell\'intestazione di navigazione</string>
|
||||
<string name="prefs_show_hidden_files">Mostra i file nascosti</string>
|
||||
<string name="prefs_sourcecode">Ottieni codice sorgente</string>
|
||||
<string name="prefs_storage_path">Cartella di archiviazione dei dati</string>
|
||||
<string name="prefs_data_storage_location">Cartella di archiviazione dei dati</string>
|
||||
<string name="prefs_sycned_folders_summary">Gestisci le cartelle per il caricamento automatico</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Cartella locale</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Cartella remota</string>
|
||||
|
|
|
@ -651,7 +651,7 @@
|
|||
<string name="prefs_show_ecosystem_apps">アップスイッチャーを表示</string>
|
||||
<string name="prefs_show_hidden_files">隠しファイルを表示</string>
|
||||
<string name="prefs_sourcecode">ソースコードを入手</string>
|
||||
<string name="prefs_storage_path">データ保存フォルダー</string>
|
||||
<string name="prefs_data_storage_location">データ保存フォルダー</string>
|
||||
<string name="prefs_sycned_folders_summary">自動アップロードするフォルダーを管理する</string>
|
||||
<string name="prefs_synced_folders_local_path_title">ローカルフォルダー</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">リモートフォルダー</string>
|
||||
|
|
|
@ -607,7 +607,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud app suggestions in navigation heading</string>
|
||||
<string name="prefs_show_hidden_files">Show hidden files</string>
|
||||
<string name="prefs_sourcecode">Get source code</string>
|
||||
<string name="prefs_storage_path">Data storage folder</string>
|
||||
<string name="prefs_data_storage_location">Data storage folder</string>
|
||||
<string name="prefs_sycned_folders_summary">Manage folders for auto upload</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Local folder</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Remote folder</string>
|
||||
|
|
|
@ -660,7 +660,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">탐색창 상단에 표시되는 Nextcloud 앱 제안</string>
|
||||
<string name="prefs_show_hidden_files">숨겨진 파일 보기</string>
|
||||
<string name="prefs_sourcecode">소스 코드 보기</string>
|
||||
<string name="prefs_storage_path">데이터 저장 폴더</string>
|
||||
<string name="prefs_data_storage_location">데이터 저장 폴더</string>
|
||||
<string name="prefs_sycned_folders_summary">자동 업로드를 위한 폴더 관리</string>
|
||||
<string name="prefs_synced_folders_local_path_title">로컬 폴더</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">원격 폴더</string>
|
||||
|
|
|
@ -495,7 +495,7 @@
|
|||
<string name="prefs_manage_accounts">ຈັດການບັນຊີ</string>
|
||||
<string name="prefs_show_hidden_files">ສະແດງຟາຍທີ່ເຊື່ອງໄວ້</string>
|
||||
<string name="prefs_sourcecode">ຮັບລະຫັດແຫຼ່ງຂໍ້ມູນ</string>
|
||||
<string name="prefs_storage_path">ໂຟນເດີການເກັບຂໍ້ມູນ</string>
|
||||
<string name="prefs_data_storage_location">ໂຟນເດີການເກັບຂໍ້ມູນ</string>
|
||||
<string name="prefs_sycned_folders_summary">ຈັດການໂຟນເດີສໍາລັບການອັບໂຫລດອັດຕະໂນມັດ</string>
|
||||
<string name="prefs_synced_folders_local_path_title">ໂຟນເດີ</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">ໂຟນໄລຍະໄກ</string>
|
||||
|
|
|
@ -588,7 +588,7 @@
|
|||
<string name="prefs_recommend">Rekomenduoti draugui</string>
|
||||
<string name="prefs_show_hidden_files">Rodyti paslėptus failus</string>
|
||||
<string name="prefs_sourcecode">Gauti pirminį kodą</string>
|
||||
<string name="prefs_storage_path">Duomenų aplankas</string>
|
||||
<string name="prefs_data_storage_location">Duomenų aplankas</string>
|
||||
<string name="prefs_sycned_folders_summary">Tvarkykite automatinio įkėlimo aplankus</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Aplankas vietinis</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Nuotolinis aplankas</string>
|
||||
|
|
|
@ -510,7 +510,7 @@
|
|||
<string name="prefs_manage_accounts">Управување со сметки</string>
|
||||
<string name="prefs_show_hidden_files">Прикажи сокриени датотеки</string>
|
||||
<string name="prefs_sourcecode">Превземи го изворниот код</string>
|
||||
<string name="prefs_storage_path">Папка за складиште на податоци</string>
|
||||
<string name="prefs_data_storage_location">Папка за складиште на податоци</string>
|
||||
<string name="prefs_sycned_folders_summary">Уреди папки за автоматско прикачување</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Папка на уредот</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Папка на серверот</string>
|
||||
|
|
|
@ -665,7 +665,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Vis Nextcloud app-forslag i navigasjonen</string>
|
||||
<string name="prefs_show_hidden_files">Vis skjulte filer</string>
|
||||
<string name="prefs_sourcecode">Hent kildekode</string>
|
||||
<string name="prefs_storage_path">Datalagringsmappe</string>
|
||||
<string name="prefs_data_storage_location">Datalagringsmappe</string>
|
||||
<string name="prefs_sycned_folders_summary">Styr mapper for automatisk opplastning</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Lokal mappe</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Mappe på server</string>
|
||||
|
|
|
@ -656,7 +656,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud app suggesties in navigatiekopregel</string>
|
||||
<string name="prefs_show_hidden_files">Verborgen bestanden weergeven</string>
|
||||
<string name="prefs_sourcecode">Krijg broncode</string>
|
||||
<string name="prefs_storage_path">Gegevensopslagmap</string>
|
||||
<string name="prefs_data_storage_location">Gegevensopslagmap</string>
|
||||
<string name="prefs_sycned_folders_summary">Mappen beheren voor automatisch uploaden</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Lokale map</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Externe map</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Sugestie aplikacji Nextcloud w nagłówku nawigacji</string>
|
||||
<string name="prefs_show_hidden_files">Pokaż ukryte pliki</string>
|
||||
<string name="prefs_sourcecode">Pobierz kod źródłowy</string>
|
||||
<string name="prefs_storage_path">Katalog przechowywania danych</string>
|
||||
<string name="prefs_data_storage_location">Katalog przechowywania danych</string>
|
||||
<string name="prefs_sycned_folders_summary">Zarządzaj katalogami do automatycznego wysyłania</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Katalog lokalny</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Katalog zdalny</string>
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<string name="advanced_settings">Configurações avançadas </string>
|
||||
<string name="allow_resharing">Permitir recompartilhamento</string>
|
||||
<string name="app_config_base_url_title">URL base</string>
|
||||
<string name="app_config_proxy_host_title">Nome do Host do Proxy</string>
|
||||
<string name="app_config_proxy_port_title">Porta do Proxy</string>
|
||||
<string name="app_widget_description">Mostra um widget do painel</string>
|
||||
<string name="appbar_search_in">Pesquisar em %s</string>
|
||||
|
@ -55,6 +56,7 @@
|
|||
<string name="assistant_screen_task_delete_success_message">Tarefa excluída com sucesso</string>
|
||||
<string name="assistant_screen_task_list_error_state_message">Não foi possível buscar a lista de tarefas. Verifique sua conexão com a Internet.</string>
|
||||
<string name="assistant_screen_task_more_actions_bottom_sheet_delete_action">Excluir tarefa</string>
|
||||
<string name="assistant_screen_task_output_empty_text">O resultado da tarefa ainda não está pronto.</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_unknown_task_status_text">Desconhecido</string>
|
||||
|
@ -687,7 +689,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Sugestões de aplicativos Nextcloud no título de navegação</string>
|
||||
<string name="prefs_show_hidden_files">Mostrar arquivos ocultos</string>
|
||||
<string name="prefs_sourcecode">Obter código-fonte</string>
|
||||
<string name="prefs_storage_path">Pasta de armazenamento de dados</string>
|
||||
<string name="prefs_data_storage_location">Pasta de armazenamento de dados</string>
|
||||
<string name="prefs_sycned_folders_summary">Gerenciar pastas para envio automático</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Pasta local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Pasta remota</string>
|
||||
|
@ -760,6 +762,7 @@
|
|||
<string name="screenshot_06_davdroid_subline">Sincronizar com DAVx5</string>
|
||||
<string name="search_error">Erro ao obter os resultados da pesquisa </string>
|
||||
<string name="secure_share_not_set_up">O compartilhamento seguro não está configurado para este usuário</string>
|
||||
<string name="secure_share_search">Compartilhamento seguro…</string>
|
||||
<string name="select_all">Selecionar tudo</string>
|
||||
<string name="select_media_folder">Definir pasta de mídia</string>
|
||||
<string name="select_one_template">Selecione um modelo</string>
|
||||
|
@ -803,6 +806,7 @@
|
|||
<string name="share_permissions">Permissões de compartilhamento </string>
|
||||
<string name="share_remote_clarification">%1$s (remoto)</string>
|
||||
<string name="share_room_clarification">%1$s (conversa)</string>
|
||||
<string name="share_search">Nome, Federated Cloud ID ou endereço de e-mail…</string>
|
||||
<string name="share_send_new_email">Enviar novo e-mail </string>
|
||||
<string name="share_send_note">Anotação ao destinatário</string>
|
||||
<string name="share_settings">Configurações</string>
|
||||
|
|
|
@ -588,7 +588,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Sugestões de aplicações Nextcloud no cabeçalho da navegação</string>
|
||||
<string name="prefs_show_hidden_files">Mostrar ficheiros ocultados</string>
|
||||
<string name="prefs_sourcecode">Obter código fonte</string>
|
||||
<string name="prefs_storage_path">Pasta de armazenamento de dados</string>
|
||||
<string name="prefs_data_storage_location">Pasta de armazenamento de dados</string>
|
||||
<string name="prefs_sycned_folders_summary">Gerir as pastas para o envio automático</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Pasta Local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Pasta Remota</string>
|
||||
|
|
|
@ -610,7 +610,7 @@
|
|||
<string name="prefs_setup_e2e">Configurează encripție end-to-end</string>
|
||||
<string name="prefs_show_hidden_files">Arată fișierele ascunse</string>
|
||||
<string name="prefs_sourcecode">Obține codul sursă</string>
|
||||
<string name="prefs_storage_path">Dosarul de stocare a datelor</string>
|
||||
<string name="prefs_data_storage_location">Dosarul de stocare a datelor</string>
|
||||
<string name="prefs_sycned_folders_summary">Administrează dosare pentru încărcare automată</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Dosar local</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Dosar la distanță</string>
|
||||
|
|
|
@ -688,7 +688,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Рекомендации по приложению Nextcloud в заголовке навигации</string>
|
||||
<string name="prefs_show_hidden_files">Показывать скрытые файлы</string>
|
||||
<string name="prefs_sourcecode">Исходный код</string>
|
||||
<string name="prefs_storage_path">Папка хранения данных</string>
|
||||
<string name="prefs_data_storage_location">Папка хранения данных</string>
|
||||
<string name="prefs_sycned_folders_summary">Управление папками для автозагрузки</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Папка на устройстве</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Папка на сервере</string>
|
||||
|
|
|
@ -522,7 +522,7 @@
|
|||
<string name="prefs_manage_accounts">Gesti is contos</string>
|
||||
<string name="prefs_show_hidden_files">Mustra documentos cuados</string>
|
||||
<string name="prefs_sourcecode">Otene su còdighe sorgente</string>
|
||||
<string name="prefs_storage_path">Cartella de archiviatzione de is datos</string>
|
||||
<string name="prefs_data_storage_location">Cartella de archiviatzione de is datos</string>
|
||||
<string name="prefs_sycned_folders_summary">Gesti cartellas pro carrigamentu automàticu</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Cartella locale</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Cartella remota</string>
|
||||
|
|
|
@ -651,7 +651,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Návrhy Nextcloud aplikácií v navigačnom záhlaví</string>
|
||||
<string name="prefs_show_hidden_files">Zobraziť skryté súbory</string>
|
||||
<string name="prefs_sourcecode">Získajte zdrojový kód</string>
|
||||
<string name="prefs_storage_path">Priečinok dátového úložiska</string>
|
||||
<string name="prefs_data_storage_location">Priečinok dátového úložiska</string>
|
||||
<string name="prefs_sycned_folders_summary">Spravovať priečinky pre automatické nahrávanie</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Lokálny priečinok</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Vzdialený priečinok</string>
|
||||
|
|
|
@ -610,7 +610,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Predlogi programov Nextcloud v naslovu</string>
|
||||
<string name="prefs_show_hidden_files">Pokaži skrite datoteke</string>
|
||||
<string name="prefs_sourcecode">Pridobi izvorno kodo</string>
|
||||
<string name="prefs_storage_path">Mapa podatkovne shrambe</string>
|
||||
<string name="prefs_data_storage_location">Mapa podatkovne shrambe</string>
|
||||
<string name="prefs_sycned_folders_summary">Upravljanje map za samodejno pošiljanje</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Krajevna mapa</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Mapa na strežniku</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Предлози Nextcloud апликација у заглављу навигације</string>
|
||||
<string name="prefs_show_hidden_files">Прикажи скривене фајлове</string>
|
||||
<string name="prefs_sourcecode">Узми изворни кôд</string>
|
||||
<string name="prefs_storage_path">Фасцикла за податке</string>
|
||||
<string name="prefs_data_storage_location">Фасцикла за податке</string>
|
||||
<string name="prefs_sycned_folders_summary">Управљање фолдерима за аутоматско отпремање</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Локална фасцикла</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Удаљена фасцикла</string>
|
||||
|
|
|
@ -689,7 +689,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Nextcloud-appförslag i navigeringsrubriken</string>
|
||||
<string name="prefs_show_hidden_files">Visa dolda filer</string>
|
||||
<string name="prefs_sourcecode">Hämta källkod</string>
|
||||
<string name="prefs_storage_path">Datalagringsmapp</string>
|
||||
<string name="prefs_data_storage_location">Datalagringsmapp</string>
|
||||
<string name="prefs_sycned_folders_summary">Hantera mappar för automatiskt uppladdning</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Lokal mapp</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Extern mapp</string>
|
||||
|
|
|
@ -485,7 +485,7 @@
|
|||
<string name="prefs_manage_accounts">Hasabyňyzy dolandyrmak</string>
|
||||
<string name="prefs_show_hidden_files">Gizlin faýllary görkez</string>
|
||||
<string name="prefs_sourcecode">Çeşme koduny alyň</string>
|
||||
<string name="prefs_storage_path">Maglumat saklaýyş bukjasy</string>
|
||||
<string name="prefs_data_storage_location">Maglumat saklaýyş bukjasy</string>
|
||||
<string name="prefs_sycned_folders_summary">Awtomatik ýüklemek üçin bukjalary dolandyrmak</string>
|
||||
<string name="prefs_synced_folders_local_path_title">ýerli bukjasy</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Uzakdaky bukja</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Gezinme başlığında Nextcloud uygulama önerileri</string>
|
||||
<string name="prefs_show_hidden_files">Gizli dosyaları görüntüle</string>
|
||||
<string name="prefs_sourcecode">Kaynak kodunu alın</string>
|
||||
<string name="prefs_storage_path">Veri depolama klasörü</string>
|
||||
<string name="prefs_data_storage_location">Veri depolama klasörü</string>
|
||||
<string name="prefs_sycned_folders_summary">Otomatik yükleme klasörleri yönetimi</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Yerel klasör</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Uzak klasör</string>
|
||||
|
|
|
@ -687,7 +687,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">يول باشلاش ماۋزۇسىدىكى Nextcloud ئەپ تەكلىپلىرى</string>
|
||||
<string name="prefs_show_hidden_files">يوشۇرۇن ھۆججەتلەرنى كۆرسەت</string>
|
||||
<string name="prefs_sourcecode">ئەسلى كودقا ئېرىشىش</string>
|
||||
<string name="prefs_storage_path">سانلىق مەلۇمات ساقلاش قىسقۇچى</string>
|
||||
<string name="prefs_data_storage_location">سانلىق مەلۇمات ساقلاش قىسقۇچى</string>
|
||||
<string name="prefs_sycned_folders_summary">ئاپتوماتىك يوللاش ئۈچۈن ھۆججەت قىسقۇچلارنى باشقۇرۇڭ</string>
|
||||
<string name="prefs_synced_folders_local_path_title">يەرلىك ھۆججەت قىسقۇچ</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">يىراقتىن قىسقۇچ</string>
|
||||
|
|
|
@ -680,7 +680,7 @@
|
|||
<string name="prefs_show_ecosystem_apps_summary">Пропозиції застосунків Nextcloud у заголовку навігації</string>
|
||||
<string name="prefs_show_hidden_files">Показувати приховані файли</string>
|
||||
<string name="prefs_sourcecode">Отримати вихідний код</string>
|
||||
<string name="prefs_storage_path">Місце збереження файлів</string>
|
||||
<string name="prefs_data_storage_location">Місце збереження файлів</string>
|
||||
<string name="prefs_sycned_folders_summary">Налаштуйте каталоги, які будуть автоматично завантажуватися</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Каталог на пристрої</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Віддалений каталог</string>
|
||||
|
|
|
@ -556,7 +556,7 @@
|
|||
<string name="prefs_setup_e2e">Thiết lập mã hoá đầu cuối</string>
|
||||
<string name="prefs_show_hidden_files">Hiển thị các tệp ẩn</string>
|
||||
<string name="prefs_sourcecode">Lấy mã nguồn</string>
|
||||
<string name="prefs_storage_path">Thư mục lưu trữ dữ liệu</string>
|
||||
<string name="prefs_data_storage_location">Thư mục lưu trữ dữ liệu</string>
|
||||
<string name="prefs_sycned_folders_summary">Quản lý các thư mục để tự động tải lên</string>
|
||||
<string name="prefs_synced_folders_local_path_title">Thư mục cục bộ</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">Thư mục từ xa</string>
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue