mirror of
https://github.com/nextcloud/android.git
synced 2024-12-19 15:33:00 +03:00
Merge remote-tracking branch 'origin/master' into dev
This commit is contained in:
commit
7148238c7c
18 changed files with 279 additions and 12 deletions
2
.github/workflows/scorecard.yml
vendored
2
.github/workflows/scorecard.yml
vendored
|
@ -34,7 +34,7 @@ jobs:
|
|||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Your Name <your@email.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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -126,6 +126,10 @@
|
|||
android:usesCleartextTraffic="true"
|
||||
tools:ignore="UnusedAttribute"
|
||||
tools:replace="android:allowBackup">
|
||||
|
||||
<meta-data android:name="android.content.APP_RESTRICTIONS"
|
||||
android:resource="@xml/app_config" />
|
||||
|
||||
<activity
|
||||
android:name="com.nextcloud.ui.composeActivity.ComposeActivity"
|
||||
android:exported="false" />
|
||||
|
|
|
@ -21,9 +21,12 @@ import android.app.ActivityManager;
|
|||
import android.app.Application;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
@ -55,6 +58,7 @@ import com.nextcloud.client.onboarding.OnboardingService;
|
|||
import com.nextcloud.client.preferences.AppPreferences;
|
||||
import com.nextcloud.client.preferences.AppPreferencesImpl;
|
||||
import com.nextcloud.client.preferences.DarkMode;
|
||||
import com.nextcloud.utils.extensions.ContextExtensionsKt;
|
||||
import com.nmc.android.ui.LauncherActivity;
|
||||
import com.owncloud.android.authentication.AuthenticatorActivity;
|
||||
import com.owncloud.android.authentication.PassCodeManager;
|
||||
|
@ -63,6 +67,7 @@ import com.owncloud.android.datamodel.ArbitraryDataProviderImpl;
|
|||
import com.owncloud.android.datamodel.MediaFolder;
|
||||
import com.owncloud.android.datamodel.MediaFolderType;
|
||||
import com.owncloud.android.datamodel.MediaProvider;
|
||||
import com.owncloud.android.datamodel.ReceiverFlag;
|
||||
import com.owncloud.android.datamodel.SyncedFolder;
|
||||
import com.owncloud.android.datamodel.SyncedFolderProvider;
|
||||
import com.owncloud.android.datamodel.ThumbnailsCacheManager;
|
||||
|
@ -75,6 +80,7 @@ import com.owncloud.android.lib.resources.status.NextcloudVersion;
|
|||
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
|
||||
import com.owncloud.android.ui.activity.SyncedFoldersActivity;
|
||||
import com.owncloud.android.ui.notifications.NotificationUtils;
|
||||
import com.owncloud.android.utils.appConfig.AppConfigManager;
|
||||
import com.owncloud.android.utils.DisplayUtils;
|
||||
import com.owncloud.android.utils.FilesSyncHelper;
|
||||
import com.owncloud.android.utils.PermissionUtil;
|
||||
|
@ -191,6 +197,8 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
|
|||
@SuppressWarnings("unused")
|
||||
private boolean mBound;
|
||||
|
||||
private AppConfigManager appConfigManager;
|
||||
|
||||
private static AppComponent appComponent;
|
||||
|
||||
/**
|
||||
|
@ -281,6 +289,7 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
|
|||
return appComponent;
|
||||
}
|
||||
|
||||
|
||||
@SuppressFBWarnings("ST")
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
@ -314,11 +323,15 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
|
|||
|
||||
OwnCloudClientManagerFactory.setUserAgent(getUserAgent());
|
||||
|
||||
try {
|
||||
OwnCloudClientManagerFactory.setProxyHost(getResources().getString(R.string.proxy_host));
|
||||
OwnCloudClientManagerFactory.setProxyPort(getResources().getInteger(R.integer.proxy_port));
|
||||
} catch (Resources.NotFoundException e) {
|
||||
// no proxy set
|
||||
if (isClientBrandedPlus()) {
|
||||
RestrictionsManager restrictionsManager = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
appConfigManager = new AppConfigManager(this, restrictionsManager.getApplicationRestrictions());
|
||||
appConfigManager.setProxyConfig(isClientBrandedPlus());
|
||||
|
||||
// Listen app config changes
|
||||
ContextExtensionsKt.registerBroadcastReceiver(this, restrictionsReceiver, restrictionsFilter, ReceiverFlag.NotExported);
|
||||
} else {
|
||||
setProxyForNonBrandedPlusClients();
|
||||
}
|
||||
|
||||
// initialise thumbnails cache on background thread
|
||||
|
@ -364,9 +377,35 @@ public class MainApp extends MultiDexApplication implements HasAndroidInjector {
|
|||
} else if (event == Lifecycle.Event.ON_STOP) {
|
||||
passCodeManager.setCanAskPin(true);
|
||||
Log_OC.d(TAG, "APP IN BACKGROUND");
|
||||
} else if (event == Lifecycle.Event.ON_RESUME) {
|
||||
if (appConfigManager == null) return;
|
||||
appConfigManager.setProxyConfig(isClientBrandedPlus());
|
||||
Log_OC.d(TAG, "APP ON RESUME");
|
||||
}
|
||||
});
|
||||
|
||||
private void setProxyForNonBrandedPlusClients() {
|
||||
try {
|
||||
OwnCloudClientManagerFactory.setProxyHost(getResources().getString(R.string.proxy_host));
|
||||
OwnCloudClientManagerFactory.setProxyPort(getResources().getInteger(R.integer.proxy_port));
|
||||
} catch (Resources.NotFoundException e) {
|
||||
Log_OC.d(TAG, "Error caught at setProxyForNonBrandedPlusClients: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isClientBrandedPlus() {
|
||||
return (getAppContext().getResources().getBoolean(R.bool.is_branded_plus_client));
|
||||
}
|
||||
|
||||
private final IntentFilter restrictionsFilter = new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
|
||||
|
||||
private final BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
|
||||
@Override public void onReceive(Context context, Intent intent) {
|
||||
if (appConfigManager == null) return;
|
||||
appConfigManager.setProxyConfig(isClientBrandedPlus());
|
||||
}
|
||||
};
|
||||
|
||||
private void registerGlobalPassCodeProtection() {
|
||||
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ 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;
|
||||
|
@ -83,6 +84,7 @@ import com.owncloud.android.lib.common.OwnCloudClientManagerFactory;
|
|||
import com.owncloud.android.lib.common.OwnCloudCredentials;
|
||||
import com.owncloud.android.lib.common.OwnCloudCredentialsFactory;
|
||||
import com.owncloud.android.lib.common.UserInfo;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils.AccountNotFoundException;
|
||||
import com.owncloud.android.lib.common.accounts.AccountUtils.Constants;
|
||||
import com.owncloud.android.lib.common.network.CertificateCombinedException;
|
||||
|
@ -111,6 +113,7 @@ 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;
|
||||
|
||||
|
@ -318,9 +321,18 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
mIsFirstAuthAttempt = savedInstanceState.getBoolean(KEY_AUTH_IS_FIRST_ATTEMPT_TAG);
|
||||
}
|
||||
|
||||
String webloginUrl = null;
|
||||
boolean webViewLoginMethod;
|
||||
if (getIntent().getBooleanExtra(EXTRA_USE_PROVIDER_AS_WEBLOGIN, false)) {
|
||||
String webloginUrl = null;
|
||||
|
||||
if (MainApp.isClientBrandedPlus()) {
|
||||
RestrictionsManager restrictionsManager = (RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
AppConfigManager appConfigManager = new AppConfigManager(this, restrictionsManager.getApplicationRestrictions());
|
||||
webloginUrl = appConfigManager.getBaseUrl(MainApp.isClientBrandedPlus());
|
||||
}
|
||||
|
||||
if (webloginUrl != null) {
|
||||
webViewLoginMethod = true;
|
||||
} else if (getIntent().getBooleanExtra(EXTRA_USE_PROVIDER_AS_WEBLOGIN, false)) {
|
||||
webViewLoginMethod = true;
|
||||
webloginUrl = getString(R.string.provider_registration_server);
|
||||
} else {
|
||||
|
@ -1375,7 +1387,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
// can be anything: email, name, name with whitespaces
|
||||
String loginName = webViewUser;
|
||||
|
||||
String accountName = com.owncloud.android.lib.common.accounts.AccountUtils.buildAccountName(uri, loginName);
|
||||
String accountName = AccountUtils.buildAccountName(uri, loginName);
|
||||
Account newAccount = new Account(accountName, accountType);
|
||||
if (accountManager.exists(newAccount)) {
|
||||
// fail - not a new account, but an existing one; disallow
|
||||
|
@ -1480,7 +1492,7 @@ public class AuthenticatorActivity extends AccountAuthenticatorActivity
|
|||
public void onRequestPermissionsResult(int requestCode,
|
||||
@NonNull String[] permissions,
|
||||
@NonNull int[] grantResults) {
|
||||
if (requestCode == PermissionUtil.PERMISSIONS_CAMERA) {// If request is cancelled, result arrays are empty.
|
||||
if (requestCode == PERMISSIONS_CAMERA) {// If request is cancelled, result arrays are empty.
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
// permission was granted
|
||||
startQRScanner();
|
||||
|
|
|
@ -46,6 +46,7 @@ import com.nextcloud.client.network.ClientFactory;
|
|||
import com.nextcloud.common.NextcloudClient;
|
||||
import com.nextcloud.ui.fileactions.FileActionsBottomSheet;
|
||||
import com.nextcloud.utils.extensions.BundleExtensionsKt;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.databinding.FragmentPreviewMediaBinding;
|
||||
import com.owncloud.android.datamodel.OCFile;
|
||||
|
|
|
@ -11,6 +11,7 @@ import android.content.res.Resources;
|
|||
import android.view.Menu;
|
||||
|
||||
import com.nextcloud.client.account.User;
|
||||
import com.owncloud.android.MainApp;
|
||||
import com.owncloud.android.R;
|
||||
import com.owncloud.android.lib.resources.status.OCCapability;
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
package com.owncloud.android.utils.appConfig
|
||||
|
||||
/**
|
||||
* These keys are connected to app_config.xml
|
||||
*/
|
||||
enum class AppConfigKeys(val key: String) {
|
||||
BaseUrl("base_url"),
|
||||
ProxyHost("proxy_host"),
|
||||
ProxyPort("proxy_port")
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Nextcloud - Android Client
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2024 Your Name <your@email.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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -665,6 +665,7 @@
|
|||
<string name="preview_image_description">معاينة الصورة</string>
|
||||
<string name="preview_image_error_no_local_file">لا يوجد ملف محلي للمعاينة</string>
|
||||
<string name="preview_image_error_unknown_format">تعذرت عملية عرض الصورة</string>
|
||||
<string name="preview_media_unhandled_http_code_message">الملف مقفلٌ حالياً من قِبَل مستخدِمٍ أو عمليةٍ أخرى؛ وبالتالي لا يمكن حذفه. الرجاء معاودة المحاولة في وقتٍ لاحقٍ.</string>
|
||||
<string name="preview_sorry">آسف</string>
|
||||
<string name="privacy">الخصوصية</string>
|
||||
<string name="public_share_name">اسم جديد</string>
|
||||
|
|
|
@ -661,6 +661,7 @@
|
|||
<string name="preview_image_description">Image preview</string>
|
||||
<string name="preview_image_error_no_local_file">There is no local file to preview</string>
|
||||
<string name="preview_image_error_unknown_format">Unable to show image</string>
|
||||
<string name="preview_media_unhandled_http_code_message">File is currently locked by another user or process and therefore not deletable. Please try again later.</string>
|
||||
<string name="preview_sorry">Sorry</string>
|
||||
<string name="privacy">Privacy</string>
|
||||
<string name="public_share_name">New name</string>
|
||||
|
|
|
@ -661,6 +661,7 @@
|
|||
<string name="preview_image_description">Bildvorschau</string>
|
||||
<string name="preview_image_error_no_local_file">Keine lokale Datei für die Vorschau vorhanden</string>
|
||||
<string name="preview_image_error_unknown_format">Bild kann nicht angezeigt werden</string>
|
||||
<string name="preview_media_unhandled_http_code_message">Die Datei ist derzeit von einem anderen Benutzer oder Prozess gesperrt und kann daher nicht gelöscht werden. Bitte später noch einmal versuchen.</string>
|
||||
<string name="preview_sorry">Entschuldigung</string>
|
||||
<string name="privacy">Datenschutz</string>
|
||||
<string name="public_share_name">Neuer Name</string>
|
||||
|
|
|
@ -661,6 +661,7 @@
|
|||
<string name="preview_image_description">Преглед слике</string>
|
||||
<string name="preview_image_error_no_local_file">Нема локалног фајла за преглед</string>
|
||||
<string name="preview_image_error_unknown_format">Не могу да прикажем слику</string>
|
||||
<string name="preview_media_unhandled_http_code_message">Фајл је тренутно закључао други корисник или процес, па не може да се обрише. Молимо вас покушајте касније.</string>
|
||||
<string name="preview_sorry">Извините</string>
|
||||
<string name="privacy">Приватност</string>
|
||||
<string name="public_share_name">Ново име</string>
|
||||
|
|
|
@ -655,12 +655,13 @@
|
|||
<string name="prefs_synced_folders_local_path_title">近端資料夾</string>
|
||||
<string name="prefs_synced_folders_remote_path_title">遠端資料夾</string>
|
||||
<string name="prefs_theme_title">佈景主題</string>
|
||||
<string name="prefs_value_theme_dark">暗色</string>
|
||||
<string name="prefs_value_theme_light">亮色</string>
|
||||
<string name="prefs_value_theme_dark">深色</string>
|
||||
<string name="prefs_value_theme_light">淺色</string>
|
||||
<string name="prefs_value_theme_system">跟隨系統</string>
|
||||
<string name="preview_image_description">圖像預覽</string>
|
||||
<string name="preview_image_error_no_local_file">沒有可供預覽的近端檔案</string>
|
||||
<string name="preview_image_error_unknown_format">無法顯示圖像</string>
|
||||
<string name="preview_media_unhandled_http_code_message">檔案目前已被其他用戶或進程鎖定,因此無法刪除。 請稍後再試。</string>
|
||||
<string name="preview_sorry">很抱歉</string>
|
||||
<string name="privacy">私隱政策</string>
|
||||
<string name="public_share_name">新名稱</string>
|
||||
|
|
|
@ -661,6 +661,7 @@
|
|||
<string name="preview_image_description">圖片預覽</string>
|
||||
<string name="preview_image_error_no_local_file">沒有可供預覽的本機檔案</string>
|
||||
<string name="preview_image_error_unknown_format">無法顯示圖片</string>
|
||||
<string name="preview_media_unhandled_http_code_message">檔案目前已被其他使用者或處理程序鎖定,因此無法刪除。請稍後再試。</string>
|
||||
<string name="preview_sorry">很抱歉</string>
|
||||
<string name="privacy">隱私權</string>
|
||||
<string name="public_share_name">新名稱</string>
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
<bool name="show_external_links">true</bool>
|
||||
<bool name="show_outdated_server_warning">true</bool>
|
||||
<bool name="is_branded_client">false</bool>
|
||||
<bool name="is_branded_plus_client">false</bool>
|
||||
|
||||
<!-- Calendar & Contacts backup -->
|
||||
<string name="contacts_backup_folder">/.Contacts-Backup</string>
|
||||
|
|
|
@ -26,6 +26,10 @@
|
|||
|
||||
<string name="ecosystem_apps_display_assistant">Assistant</string>
|
||||
|
||||
<string name="app_config_base_url_title">Base Url</string>
|
||||
<string name="app_config_proxy_host_title">Proxy Host Name</string>
|
||||
<string name="app_config_proxy_port_title">Proxy Port</string>
|
||||
|
||||
<string name="assistant_screen_task_types_error_state_message">Unable to fetch task types, please check your internet connection.</string>
|
||||
<string name="assistant_screen_task_list_error_state_message">Unable to fetch task list, please check your internet connection.</string>
|
||||
|
||||
|
|
28
app/src/main/res/xml/app_config.xml
Normal file
28
app/src/main/res/xml/app_config.xml
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ Nextcloud - Android Client
|
||||
~
|
||||
~ SPDX-FileCopyrightText: 2024 Your Name <your@email.com>
|
||||
~ SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-->
|
||||
|
||||
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<restriction
|
||||
android:key="proxy_host"
|
||||
android:defaultValue=""
|
||||
android:restrictionType="string"
|
||||
android:title="@string/app_config_proxy_host_title" />
|
||||
|
||||
<restriction
|
||||
android:key="proxy_port"
|
||||
android:defaultValue="-1"
|
||||
android:restrictionType="integer"
|
||||
android:title="@string/app_config_proxy_port_title" />
|
||||
|
||||
<restriction
|
||||
android:key="base_url"
|
||||
android:defaultValue=""
|
||||
android:restrictionType="string"
|
||||
android:title="@string/app_config_base_url_title" />
|
||||
|
||||
</restrictions>
|
Loading…
Reference in a new issue