diff --git a/app/src/androidTest/java/com/nmc/android/ui/SettingsPreferenceIT.kt b/app/src/androidTest/java/com/nmc/android/ui/SettingsPreferenceIT.kt new file mode 100644 index 000000000000..dde7af362273 --- /dev/null +++ b/app/src/androidTest/java/com/nmc/android/ui/SettingsPreferenceIT.kt @@ -0,0 +1,212 @@ +package com.nmc.android.ui + +import android.preference.ListPreference +import android.preference.Preference +import androidx.test.espresso.Espresso.onData +import androidx.test.espresso.assertion.ViewAssertions.matches +import androidx.test.espresso.matcher.PreferenceMatchers +import androidx.test.espresso.matcher.PreferenceMatchers.withKey +import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed +import androidx.test.ext.junit.rules.ActivityScenarioRule +import com.owncloud.android.AbstractIT +import com.owncloud.android.R +import com.owncloud.android.ui.AppVersionPreference +import com.owncloud.android.ui.PreferenceCustomCategory +import com.owncloud.android.ui.ThemeableSwitchPreference +import com.owncloud.android.ui.activity.SettingsActivity +import org.hamcrest.Matchers.allOf +import org.hamcrest.Matchers.instanceOf +import org.hamcrest.Matchers.`is` +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class SettingsPreferenceIT : AbstractIT() { + + @get:Rule + val activityRule = ActivityScenarioRule(SettingsActivity::class.java) + + @Test + fun verifyPreferenceSectionCustomClass() { + activityRule.scenario.onActivity { + val preferenceAccountInfo = it.findPreference("account_info") + val preferenceGeneral = it.findPreference("general") + val preferenceDetails = it.findPreference("details") + val preferenceMore = it.findPreference("more") + val preferenceDataProtection = it.findPreference("data_protection") + val preferenceInfo = it.findPreference("info") + + val preferenceCategoryList = listOf( + preferenceAccountInfo, + preferenceGeneral, + preferenceDetails, + preferenceMore, + preferenceDataProtection, + preferenceInfo + ) + + for (preference in preferenceCategoryList) { + assertEquals(PreferenceCustomCategory::class.java, preference.javaClass) + } + } + } + + @Test + fun verifySwitchPreferenceCustomClass() { + activityRule.scenario.onActivity { + val preferenceShowHiddenFiles = it.findPreference("show_hidden_files") + assertEquals(ThemeableSwitchPreference::class.java, preferenceShowHiddenFiles.javaClass) + } + } + + @Test + fun verifyAppVersionPreferenceCustomClass() { + activityRule.scenario.onActivity { + val preferenceAboutApp = it.findPreference("about_app") + assertEquals(AppVersionPreference::class.java, preferenceAboutApp.javaClass) + } + } + + @Test + fun verifyPreferenceChildCustomLayout() { + activityRule.scenario.onActivity { + val userName = it.findPreference("user_name") + val storagePath = it.findPreference("storage_path") + val lock = it.findPreference("lock") + val showHiddenFiles = it.findPreference("show_hidden_files") + val syncedFolders = it.findPreference("syncedFolders") + val backup = it.findPreference("backup") + val mnemonic = it.findPreference("mnemonic") + val privacySettings = it.findPreference("privacy_settings") + val privacyPolicy = it.findPreference("privacy_policy") + val sourceCode = it.findPreference("sourcecode") + val help = it.findPreference("help") + val imprint = it.findPreference("imprint") + + val preferenceList = listOf( + userName, + storagePath, + lock, + showHiddenFiles, + syncedFolders, + backup, + mnemonic, + privacySettings, + privacyPolicy, + sourceCode, + help, + imprint + ) + + for (preference in preferenceList) { + assertEquals(R.layout.custom_preference_layout, preference.layoutResource) + } + + val aboutApp = it.findPreference("about_app") + assertEquals(R.layout.custom_app_preference_layout, aboutApp.layoutResource) + + } + } + + @Test + fun verifyPreferencesTitleText() { + onData(allOf(`is`(instanceOf(PreferenceCustomCategory::class.java)), withKey("account_info"), + PreferenceMatchers.withTitleText("Account Information"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("user_name"), + PreferenceMatchers.withTitleText("test"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(PreferenceCustomCategory::class.java)), withKey("general"), + PreferenceMatchers.withTitleText("General"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(ListPreference::class.java)), withKey("storage_path"), + PreferenceMatchers.withTitleText("Data storage folder"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(PreferenceCustomCategory::class.java)), withKey("details"), + PreferenceMatchers.withTitleText("Details"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(ListPreference::class.java)), withKey("lock"), + PreferenceMatchers.withTitleText("App passcode"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(ThemeableSwitchPreference::class.java)), withKey("show_hidden_files"), + PreferenceMatchers.withTitleText("Show hidden files"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(PreferenceCustomCategory::class.java)), withKey("more"), + PreferenceMatchers.withTitleText("More"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("syncedFolders"), + PreferenceMatchers.withTitleText("Auto upload"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("backup"), + PreferenceMatchers.withTitleText("Back up contacts"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("mnemonic"), + PreferenceMatchers.withTitleText("E2E mnemonic"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("logger"), + PreferenceMatchers.withTitleText("Logs"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(PreferenceCustomCategory::class.java)), withKey("data_protection"), + PreferenceMatchers.withTitleText("Data Privacy"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("privacy_settings"), + PreferenceMatchers.withTitleText("Privacy Settings"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("privacy_policy"), + PreferenceMatchers.withTitleText("Privacy Policy"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("sourcecode"), + PreferenceMatchers.withTitleText("Used OpenSource Software"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(PreferenceCustomCategory::class.java)), withKey("service"), + PreferenceMatchers.withTitleText("Service"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("help"), + PreferenceMatchers.withTitleText("Help"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("imprint"), + PreferenceMatchers.withTitleText("Imprint"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(PreferenceCustomCategory::class.java)), withKey("info"), + PreferenceMatchers.withTitleText("Info"))) + .check(matches(isCompletelyDisplayed())) + } + + @Test + fun verifyPreferencesSummaryText() { + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("lock"), + PreferenceMatchers.withSummaryText("None"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("syncedFolders"), + PreferenceMatchers.withSummaryText("Manage folders for auto upload"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("backup"), + PreferenceMatchers.withSummaryText("Daily backup of your calendar & contacts"))) + .check(matches(isCompletelyDisplayed())) + + onData(allOf(`is`(instanceOf(Preference::class.java)), withKey("mnemonic"), + PreferenceMatchers.withSummaryText("To show mnemonic please enable device credentials."))) + .check(matches(isCompletelyDisplayed())) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/nmc/android/ui/PrivacySettingsInterface.kt b/app/src/main/java/com/nmc/android/ui/PrivacySettingsInterface.kt new file mode 100644 index 000000000000..860ffada08ab --- /dev/null +++ b/app/src/main/java/com/nmc/android/ui/PrivacySettingsInterface.kt @@ -0,0 +1,13 @@ +package com.nmc.android.ui + +import android.content.Context + +/** + * interface to open privacy settings activity from nmc/1921-settings branch + * for implementation look nmc/1878-privacy branch + * this class will have the declaration for it since it has the PrivacySettingsActivity.java in place + * since we don't have privacy settings functionality in this branch so to handle the redirection we have used interface + */ +interface PrivacySettingsInterface { + fun openPrivacySettingsActivity(context: Context) +} \ No newline at end of file diff --git a/app/src/main/java/com/owncloud/android/ui/AppVersionPreference.kt b/app/src/main/java/com/owncloud/android/ui/AppVersionPreference.kt new file mode 100644 index 000000000000..ee0e0b43402a --- /dev/null +++ b/app/src/main/java/com/owncloud/android/ui/AppVersionPreference.kt @@ -0,0 +1,51 @@ +package com.owncloud.android.ui + +import android.content.Context +import android.content.pm.PackageManager +import android.preference.Preference +import android.util.AttributeSet +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import com.owncloud.android.R +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.utils.StringUtils + +class AppVersionPreference : Preference { + constructor(context: Context?) : super(context) + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) + constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) + + override fun getView(convertView: View?, parent: ViewGroup?): View { + val v = super.getView(convertView, parent) + updatePreferenceView(v.findViewById(R.id.title), v.findViewById(R.id.summary)) + return v + } + + private fun updatePreferenceView(title: TextView, summary: TextView) { + val appVersion = appVersion + val titleColor: Int = context.resources.getColor(R.color.fontAppbar, null) + title.text = StringUtils.getColorSpan( + context.getString(R.string.app_name), + titleColor + ) + summary.text = String.format(context.getString(R.string.about_version), appVersion) + } + + private val appVersion: String + get() { + var temp: String + try { + val pkg = context.packageManager.getPackageInfo(context.packageName, 0) + temp = pkg.versionName + } catch (e: PackageManager.NameNotFoundException) { + temp = "" + Log_OC.e(TAG, "Error while showing about dialog", e) + } + return temp + } + + companion object { + private val TAG = AppVersionPreference::class.java.simpleName + } +} \ No newline at end of file diff --git a/app/src/main/java/com/owncloud/android/ui/PreferenceCustomCategory.kt b/app/src/main/java/com/owncloud/android/ui/PreferenceCustomCategory.kt new file mode 100644 index 000000000000..ec6b920585e1 --- /dev/null +++ b/app/src/main/java/com/owncloud/android/ui/PreferenceCustomCategory.kt @@ -0,0 +1,30 @@ +package com.owncloud.android.ui + +import android.content.Context +import android.graphics.Typeface +import android.preference.PreferenceCategory +import android.util.AttributeSet +import android.util.TypedValue +import android.view.View +import android.widget.TextView +import com.owncloud.android.R + +class PreferenceCustomCategory : PreferenceCategory { + constructor(context: Context?) : super(context) + constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) + constructor( + context: Context?, attrs: AttributeSet?, + defStyle: Int + ) : super(context, attrs, defStyle) + + override fun onBindView(view: View) { + super.onBindView(view) + val titleView = view.findViewById(android.R.id.title) + titleView.setTextColor(context.resources.getColor(R.color.text_color)) + titleView.setTextSize( + TypedValue.COMPLEX_UNIT_PX, + context.resources.getDimensionPixelSize(R.dimen.txt_size_16sp).toFloat() + ) + titleView.setTypeface(null, Typeface.BOLD) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/owncloud/android/ui/ThemeableSwitchPreference.java b/app/src/main/java/com/owncloud/android/ui/ThemeableSwitchPreference.java index 8707cef2d0d0..5aae3ee17f93 100644 --- a/app/src/main/java/com/owncloud/android/ui/ThemeableSwitchPreference.java +++ b/app/src/main/java/com/owncloud/android/ui/ThemeableSwitchPreference.java @@ -21,6 +21,7 @@ package com.owncloud.android.ui; import android.content.Context; +import android.content.res.ColorStateList; import android.preference.SwitchPreference; import android.util.AttributeSet; import android.view.View; @@ -28,10 +29,12 @@ import android.widget.Switch; import com.owncloud.android.MainApp; +import com.owncloud.android.R; import com.owncloud.android.utils.theme.ViewThemeUtils; import javax.inject.Inject; +import androidx.core.content.res.ResourcesCompat; /** * Themeable switch preference TODO Migrate to androidx @@ -65,13 +68,65 @@ protected void onBindView(View view) { } private void findSwitch(ViewGroup viewGroup) { + ColorStateList thumbColorStateList; + ColorStateList trackColorStateList; + for (int i = 0; i < viewGroup.getChildCount(); i++) { View child = viewGroup.getChildAt(i); if (child instanceof Switch) { Switch switchView = (Switch) child; - viewThemeUtils.platform.colorSwitch(switchView); + int[][] states = new int[][]{ + new int[]{android.R.attr.state_enabled, android.R.attr.state_checked}, // enabled and checked + new int[]{android.R.attr.state_enabled, -android.R.attr.state_checked}, // enabled and unchecked + new int[]{-android.R.attr.state_enabled} // disabled + }; + + int thumbColorCheckedEnabled = ResourcesCompat.getColor( + switchView.getContext().getResources(), + R.color.switch_thumb_checked_enabled, + switchView.getContext().getTheme()); + int thumbColorUncheckedEnabled = ResourcesCompat.getColor( + switchView.getContext().getResources(), + R.color.switch_thumb_unchecked_enabled, + switchView.getContext().getTheme()); + int thumbColorDisabled = + ResourcesCompat.getColor( + switchView.getContext().getResources(), + R.color.switch_thumb_disabled, + switchView.getContext().getTheme()); + + int[] thumbColors = new int[]{ + thumbColorCheckedEnabled, + thumbColorUncheckedEnabled, + thumbColorDisabled + }; + + thumbColorStateList = new ColorStateList(states, thumbColors); + + int trackColorCheckedEnabled = ResourcesCompat.getColor( + switchView.getContext().getResources(), + R.color.switch_track_checked_enabled, + switchView.getContext().getTheme()); + int trackColorUncheckedEnabled = ResourcesCompat.getColor( + switchView.getContext().getResources(), + R.color.switch_track_unchecked_enabled, + switchView.getContext().getTheme()); + int trackColorDisabled = ResourcesCompat.getColor( + switchView.getContext().getResources(), + R.color.switch_track_disabled, + switchView.getContext().getTheme()); + + int[] trackColors = new int[]{ + trackColorCheckedEnabled, + trackColorUncheckedEnabled, + trackColorDisabled + }; + trackColorStateList = new ColorStateList(states, trackColors); + + switchView.setThumbTintList(thumbColorStateList); + switchView.setTrackTintList(trackColorStateList); break; } else if (child instanceof ViewGroup) { diff --git a/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java b/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java index da23f3168a8c..ad829cd7a3e0 100644 --- a/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java +++ b/app/src/main/java/com/owncloud/android/ui/activity/SettingsActivity.java @@ -30,8 +30,6 @@ import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; @@ -49,6 +47,7 @@ import android.view.View; import android.view.ViewGroup; import android.webkit.URLUtil; +import android.widget.ListView; import com.nextcloud.client.account.User; import com.nextcloud.client.account.UserAccountManager; @@ -57,9 +56,9 @@ import com.nextcloud.client.logger.ui.LogsActivity; import com.nextcloud.client.network.ClientFactory; import com.nextcloud.client.network.ConnectivityService; +import com.nmc.android.ui.PrivacySettingsInterface; 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.owncloud.android.MainApp; import com.owncloud.android.R; @@ -82,16 +81,17 @@ import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.EncryptionUtils; import com.owncloud.android.utils.MimeTypeUtil; +import com.owncloud.android.utils.StringUtils; import com.owncloud.android.utils.theme.CapabilityUtils; import com.owncloud.android.utils.theme.ViewThemeUtils; import java.util.ArrayList; -import java.util.List; import javax.inject.Inject; import androidx.annotation.LayoutRes; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; @@ -152,6 +152,16 @@ public class SettingsActivity extends PreferenceActivity @Inject ViewThemeUtils viewThemeUtils; @Inject ConnectivityService connectivityService; + /** + * Things to note about both the branches. + * 1. nmc/1921-settings branch: + * --> interface won't be initialised + * --> calling of interface method will be done here + * 2. nmc/1878-privacy + * --> interface will be initialised + * --> calling of interface method won't be done here + */ + private PrivacySettingsInterface privacySettingsInterface; @SuppressWarnings("deprecation") @Override @@ -162,12 +172,15 @@ public void onCreate(Bundle savedInstanceState) { getDelegate().onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); + ListView listView = getListView(); + listView.setDivider(ResourcesCompat.getDrawable(getResources(), R.drawable.item_divider, null)); + setupActionBar(); // Register context menu for list of preferences. registerForContextMenu(getListView()); - String appVersion = getAppVersion(); + int titleColor = getResources().getColor(R.color.fontAppbar, null); PreferenceScreen preferenceScreen = (PreferenceScreen) findPreference("preference_screen"); user = accountManager.getUser(); @@ -175,23 +188,37 @@ public void onCreate(Bundle savedInstanceState) { // retrieve user's base uri setupBaseUri(); + // Account Information + setupAccountInfoCategory(titleColor); + // General - setupGeneralCategory(); + setupGeneralCategory(titleColor); // Synced folders - setupAutoUploadCategory(preferenceScreen); + setupAutoUploadCategory(titleColor, preferenceScreen); // Details - setupDetailsCategory(preferenceScreen); + setupDetailsCategory(titleColor, preferenceScreen); // More - setupMoreCategory(); + setupMoreCategory(titleColor); // About - setupAboutCategory(appVersion); + // Not required in NMC + //setupAboutCategory(appVersion); + // Data Privacy + setupDataPrivacyCategory(titleColor); + + //Service + setUpServiceCategory(titleColor); + + //Info + setUpInfoCategory(titleColor); + + // Not required for NMC // Dev - setupDevCategory(preferenceScreen); + // setupDevCategory(preferenceScreen); // workaround for mismatched color when app dark mode and system dark mode don't agree setListBackground(); @@ -324,15 +351,103 @@ private void setupAboutCategory(String appVersion) { } } - private void setupMoreCategory() { - final PreferenceCategory preferenceCategoryMore = (PreferenceCategory) findPreference("more"); - viewThemeUtils.files.themePreferenceCategory(preferenceCategoryMore); + /** + * NMC customization + */ + private void setupDataPrivacyCategory(int titleColor) { + PreferenceCategory preferenceCategoryAbout = (PreferenceCategory) findPreference("data_protection"); + preferenceCategoryAbout.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_category_data_privacy), + titleColor)); + + //privacy settings + Preference privacySettingPreference = findPreference("privacy_settings"); + if (privacySettingPreference != null) { + privacySettingPreference.setTitle(StringUtils.getColorSpan(getString(R.string.privacy_settings), + titleColor)); + privacySettingPreference.setOnPreferenceClickListener(preference -> { + //implementation and logic will be available in nmc/1878-privacy + if (privacySettingsInterface != null) { + privacySettingsInterface.openPrivacySettingsActivity(SettingsActivity.this); + } + return true; + }); + } + + // privacy policy + Preference privacyPolicyPreference = findPreference("privacy_policy"); - setupAutoUploadPreference(preferenceCategoryMore); + if (privacyPolicyPreference != null) { + privacyPolicyPreference.setTitle(StringUtils.getColorSpan(getString(R.string.privacy_policy), + titleColor)); + if (URLUtil.isValidUrl(getString(R.string.privacy_url))) { + privacyPolicyPreference.setOnPreferenceClickListener(preference -> { + try { + Uri privacyUrl = Uri.parse(getString(R.string.privacy_url)); + String mimeType = MimeTypeUtil.getBestMimeTypeByFilename(privacyUrl.getLastPathSegment()); + + Intent intent; + if (MimeTypeUtil.isPDF(mimeType)) { + intent = new Intent(Intent.ACTION_VIEW, privacyUrl); + DisplayUtils.startIntentIfAppAvailable(intent, this, R.string.no_pdf_app_available); + } else { + intent = new Intent(getApplicationContext(), ExternalSiteWebView.class); + intent.putExtra(ExternalSiteWebView.EXTRA_TITLE, + getResources().getString(R.string.privacy_policy)); + intent.putExtra(ExternalSiteWebView.EXTRA_URL, privacyUrl.toString()); + intent.putExtra(ExternalSiteWebView.EXTRA_SHOW_SIDEBAR, false); + intent.putExtra(ExternalSiteWebView.EXTRA_MENU_ITEM_ID, -1); + } + + startActivity(intent); + } catch (Exception e) { + Log_OC.e(TAG, "Could not parse privacy policy url"); + preferenceCategoryAbout.removePreference(privacyPolicyPreference); + } + return true; + }); + } else { + preferenceCategoryAbout.removePreference(privacyPolicyPreference); + } + } + + // source code + Preference sourcecodePreference = findPreference("sourcecode"); + if (sourcecodePreference != null) { + sourcecodePreference.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_open_source), + titleColor)); + if (URLUtil.isValidUrl(getString(R.string.sourcecode_url))) { + sourcecodePreference.setOnPreferenceClickListener(preference -> { + Intent intent = new Intent(getApplicationContext(), ExternalSiteWebView.class); + intent.putExtra(ExternalSiteWebView.EXTRA_TITLE, + getResources().getString(R.string.prefs_open_source)); + intent.putExtra(ExternalSiteWebView.EXTRA_URL, getResources().getString(R.string.sourcecode_url)); + intent.putExtra(ExternalSiteWebView.EXTRA_SHOW_SIDEBAR, false); + intent.putExtra(ExternalSiteWebView.EXTRA_MENU_ITEM_ID, -1); + startActivity(intent); + return true; + }); + } else { + preferenceCategoryAbout.removePreference(sourcecodePreference); + } + } + } + + private void setUpInfoCategory(int titleColor) { + PreferenceCategory preferenceCategoryAbout = (PreferenceCategory) findPreference("info"); + preferenceCategoryAbout.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_category_info), + titleColor)); + } + + private void setupMoreCategory(int titleColor) { + PreferenceCategory preferenceCategoryMore = (PreferenceCategory) findPreference("more"); + preferenceCategoryMore.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_category_more), + titleColor)); + + setupAutoUploadPreference(preferenceCategoryMore, titleColor); setupCalendarPreference(preferenceCategoryMore); - setupBackupPreference(); + setupBackupPreference(titleColor); setupE2EPreference(preferenceCategoryMore); @@ -342,42 +457,20 @@ private void setupMoreCategory() { removeE2E(preferenceCategoryMore); - setupHelpPreference(preferenceCategoryMore); - setupRecommendPreference(preferenceCategoryMore); - setupLoggingPreference(preferenceCategoryMore); - - setupImprintPreference(preferenceCategoryMore); + setupLoggingPreference(preferenceCategoryMore, titleColor); loadExternalSettingLinks(preferenceCategoryMore); } - private void setupImprintPreference(PreferenceCategory preferenceCategoryMore) { - boolean imprintEnabled = getResources().getBoolean(R.bool.imprint_enabled); - Preference pImprint = findPreference("imprint"); - if (pImprint != null) { - if (imprintEnabled) { - pImprint.setOnPreferenceClickListener(preference -> { - String imprintWeb = getString(R.string.url_imprint); - - if (!imprintWeb.isEmpty()) { - DisplayUtils.startLinkIntent(this, imprintWeb); - } - //ImprintDialog.newInstance(true).show(preference.get, "IMPRINT_DIALOG"); - return true; - }); - } else { - preferenceCategoryMore.removePreference(pImprint); - } - } - } - - private void setupLoggingPreference(PreferenceCategory preferenceCategoryMore) { + private void setupLoggingPreference(PreferenceCategory preferenceCategoryMore, int titleColor) { boolean loggerEnabled = getResources().getBoolean(R.bool.logger_enabled) || BuildConfig.DEBUG; Preference pLogger = findPreference("logger"); if (pLogger != null) { + pLogger.setTitle(StringUtils.getColorSpan(getString(R.string.logs_title), + titleColor)); if (loggerEnabled) { pLogger.setOnPreferenceClickListener(preference -> { Intent loggerIntent = new Intent(getApplicationContext(), LogsActivity.class); @@ -532,23 +625,10 @@ private void removeE2E(PreferenceCategory preferenceCategoryMore) { } } - private void setupHelpPreference(PreferenceCategory preferenceCategoryMore) { - boolean helpEnabled = getResources().getBoolean(R.bool.help_enabled); - Preference pHelp = findPreference("help"); - if (pHelp != null) { - if (helpEnabled) { - pHelp.setOnPreferenceClickListener(preference -> { - DisplayUtils.startLinkIntent(this, R.string.url_help); - return true; - }); - } else { - preferenceCategoryMore.removePreference(pHelp); - } - } - } - - private void setupAutoUploadPreference(PreferenceCategory preferenceCategoryMore) { + private void setupAutoUploadPreference(PreferenceCategory preferenceCategoryMore, int titleColor) { Preference autoUpload = findPreference("syncedFolders"); + autoUpload.setTitle(StringUtils.getColorSpan(getString(R.string.drawer_synced_folders), + titleColor)); if (getResources().getBoolean(R.bool.syncedFolder_light)) { preferenceCategoryMore.removePreference(autoUpload); } else { @@ -560,13 +640,12 @@ private void setupAutoUploadPreference(PreferenceCategory preferenceCategoryMore } } - private void setupBackupPreference() { + private void setupBackupPreference(int titleColor) { Preference pContactsBackup = findPreference("backup"); if (pContactsBackup != null) { boolean showCalendarBackup = getResources().getBoolean(R.bool.show_calendar_backup); - pContactsBackup.setTitle(showCalendarBackup - ? getString(R.string.backup_title) - : getString(R.string.contact_backup_title)); + //NMC Customization + pContactsBackup.setTitle(StringUtils.getColorSpan(getString(R.string.actionbar_contacts), titleColor)); pContactsBackup.setSummary(showCalendarBackup ? getString(R.string.prefs_daily_backup_summary) : getString(R.string.prefs_daily_contact_backup_summary)); @@ -600,9 +679,10 @@ private void setupCalendarPreference(PreferenceCategory preferenceCategoryMore) } } - private void setupDetailsCategory(PreferenceScreen preferenceScreen) { + private void setupDetailsCategory(int titleColor, PreferenceScreen preferenceScreen) { PreferenceCategory preferenceCategoryDetails = (PreferenceCategory) findPreference("details"); - viewThemeUtils.files.themePreferenceCategory(preferenceCategoryDetails); + preferenceCategoryDetails.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_category_details), + titleColor)); boolean fPassCodeEnabled = getResources().getBoolean(R.bool.passcode_enabled); boolean fDeviceCredentialsEnabled = getResources().getBoolean(R.bool.device_credentials_enabled); @@ -611,13 +691,13 @@ private void setupDetailsCategory(PreferenceScreen preferenceScreen) { boolean fSyncedFolderLightEnabled = getResources().getBoolean(R.bool.syncedFolder_light); boolean fShowMediaScanNotifications = preferences.isShowMediaScanNotifications(); - setupLockPreference(preferenceCategoryDetails, fPassCodeEnabled, fDeviceCredentialsEnabled); + setupLockPreference(preferenceCategoryDetails, fPassCodeEnabled, fDeviceCredentialsEnabled, titleColor); - setupHiddenFilesPreference(preferenceCategoryDetails, fShowHiddenFilesEnabled); + setupHiddenFilesPreference(preferenceCategoryDetails, fShowHiddenFilesEnabled, titleColor); setupShowEcosystemAppsPreference(preferenceCategoryDetails, fShowEcosystemAppsEnabled); - setupShowMediaScanNotifications(preferenceCategoryDetails, fShowMediaScanNotifications); + setupShowMediaScanNotifications(preferenceCategoryDetails, fShowMediaScanNotifications, titleColor); if (!fPassCodeEnabled && !fDeviceCredentialsEnabled && !fShowHiddenFilesEnabled && fSyncedFolderLightEnabled && fShowMediaScanNotifications) { @@ -626,18 +706,20 @@ private void setupDetailsCategory(PreferenceScreen preferenceScreen) { } private void setupShowMediaScanNotifications(PreferenceCategory preferenceCategoryDetails, - boolean fShowMediaScanNotifications) { - ThemeableSwitchPreference mShowMediaScanNotifications = - (ThemeableSwitchPreference) findPreference(PREFERENCE_SHOW_MEDIA_SCAN_NOTIFICATIONS); - + boolean fShowMediaScanNotifications, int titleColor) { + SwitchPreference mShowMediaScanNotifications = (SwitchPreference) findPreference(PREFERENCE_SHOW_MEDIA_SCAN_NOTIFICATIONS); + mShowMediaScanNotifications.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_storage_path), + titleColor)); if (fShowMediaScanNotifications) { preferenceCategoryDetails.removePreference(mShowMediaScanNotifications); } } private void setupHiddenFilesPreference(PreferenceCategory preferenceCategoryDetails, - boolean fShowHiddenFilesEnabled) { + boolean fShowHiddenFilesEnabled, int titleColor) { showHiddenFiles = (ThemeableSwitchPreference) findPreference("show_hidden_files"); + showHiddenFiles.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_show_hidden_files), + titleColor)); if (fShowHiddenFilesEnabled) { showHiddenFiles.setOnPreferenceClickListener(preference -> { preferences.setShowHiddenFilesEnabled(showHiddenFiles.isChecked()); @@ -664,8 +746,10 @@ private void setupShowEcosystemAppsPreference(PreferenceCategory preferenceCateg private void setupLockPreference(PreferenceCategory preferenceCategoryDetails, boolean passCodeEnabled, - boolean deviceCredentialsEnabled) { + boolean deviceCredentialsEnabled, int titleColor) { lock = (ListPreference) findPreference(PREFERENCE_LOCK); + lock.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_lock), + titleColor)); if (lock != null && (passCodeEnabled || deviceCredentialsEnabled)) { ArrayList lockEntries = new ArrayList<>(3); lockEntries.add(getString(R.string.prefs_lock_none)); @@ -712,10 +796,11 @@ private void setupLockPreference(PreferenceCategory preferenceCategoryDetails, } } - private void setupAutoUploadCategory(PreferenceScreen preferenceScreen) { - final PreferenceCategory preferenceCategorySyncedFolders = + private void setupAutoUploadCategory(int titleColor, PreferenceScreen preferenceScreen) { + PreferenceCategory preferenceCategorySyncedFolders = (PreferenceCategory) findPreference("synced_folders_category"); - viewThemeUtils.files.themePreferenceCategory(preferenceCategorySyncedFolders); + preferenceCategorySyncedFolders.setTitle(StringUtils.getColorSpan(getString(R.string.drawer_synced_folders), + titleColor)); if (!getResources().getBoolean(R.bool.syncedFolder_light)) { preferenceScreen.removePreference(preferenceCategorySyncedFolders); @@ -724,6 +809,8 @@ private void setupAutoUploadCategory(PreferenceScreen preferenceScreen) { final ArbitraryDataProvider arbitraryDataProvider = new ArbitraryDataProviderImpl(this); final SwitchPreference pUploadOnWifiCheckbox = (SwitchPreference) findPreference("synced_folder_on_wifi"); + pUploadOnWifiCheckbox.setTitle(StringUtils.getColorSpan(getString(R.string.auto_upload_on_wifi), + titleColor)); pUploadOnWifiCheckbox.setChecked( arbitraryDataProvider.getBooleanValue(user, SYNCED_FOLDER_LIGHT_UPLOAD_ON_WIFI)); @@ -749,6 +836,57 @@ private void setupAutoUploadCategory(PreferenceScreen preferenceScreen) { } } + private void setUpServiceCategory(int titleColor) { + PreferenceCategory preferenceCategoryService = (PreferenceCategory) findPreference("service"); + preferenceCategoryService.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_category_service), + titleColor)); + setupHelpPreference(titleColor); + setupImprintPreference(titleColor); + } + + private void setupHelpPreference(int titleColor) { + Preference pHelp = findPreference("help"); + if (pHelp != null) { + pHelp.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_help), + titleColor)); + pHelp.setOnPreferenceClickListener(preference -> { + String helpWeb = getString(R.string.url_help); + if (!helpWeb.isEmpty()) { + openLinkInWebView(helpWeb, R.string.prefs_help); + } + return true; + }); + + } + } + + private void setupImprintPreference(int titleColor) { + Preference pImprint = findPreference("imprint"); + if (pImprint != null) { + pImprint.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_imprint), + titleColor)); + pImprint.setOnPreferenceClickListener(preference -> { + String imprintWeb = getString(R.string.url_imprint_nmc); + if (!imprintWeb.isEmpty()) { + openLinkInWebView(imprintWeb, R.string.prefs_imprint); + } + //ImprintDialog.newInstance(true).show(preference.get, "IMPRINT_DIALOG"); + return true; + }); + } + + } + + private void openLinkInWebView(String url, @StringRes int title) { + Intent externalWebViewIntent = new Intent(getApplicationContext(), ExternalSiteWebView.class); + externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_TITLE, + getResources().getString(title)); + externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_URL, url); + externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_SHOW_SIDEBAR, false); + externalWebViewIntent.putExtra(ExternalSiteWebView.EXTRA_MENU_ITEM_ID, -1); + startActivity(externalWebViewIntent); + } + private void enableLock(String lock) { pendingLock = LOCK_NONE; if (LOCK_PASSCODE.equals(lock)) { @@ -782,11 +920,24 @@ private void disableLock(String lock) { } } - private void setupGeneralCategory() { - final PreferenceCategory preferenceCategoryGeneral = (PreferenceCategory) findPreference("general"); - viewThemeUtils.files.themePreferenceCategory(preferenceCategoryGeneral); + private void setupAccountInfoCategory(int titleColor) { + PreferenceCategory preferenceCategoryAccountInfo = (PreferenceCategory) findPreference("account_info"); + preferenceCategoryAccountInfo.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_category_account_info), + titleColor)); + + Preference autoUpload = findPreference("user_name"); + autoUpload.setTitle(StringUtils.getColorSpan(accountManager.getUser().toOwnCloudAccount().getDisplayName(), + titleColor)); + } + + private void setupGeneralCategory(int titleColor) { + PreferenceCategory preferenceCategoryGeneral = (PreferenceCategory) findPreference("general"); + preferenceCategoryGeneral.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_category_general), + titleColor)); prefStoragePath = (ListPreference) findPreference(AppPreferencesImpl.STORAGE_PATH); + prefStoragePath.setTitle(StringUtils.getColorSpan(getString(R.string.prefs_storage_path), + titleColor)); if (prefStoragePath != null) { StoragePoint[] storageOptions = DataStorageProvider.getInstance().getAvailableStoragePoints(); String[] entries = new String[storageOptions.length]; @@ -814,52 +965,12 @@ private void setupGeneralCategory() { loadStoragePath(); - ListPreference themePref = (ListPreference) findPreference("darkMode"); - - List themeEntries = new ArrayList<>(3); - themeEntries.add(getString(R.string.prefs_value_theme_light)); - themeEntries.add(getString(R.string.prefs_value_theme_dark)); - themeEntries.add(getString(R.string.prefs_value_theme_system)); - - List themeValues = new ArrayList<>(3); - themeValues.add(DarkMode.LIGHT.name()); - themeValues.add(DarkMode.DARK.name()); - themeValues.add(DarkMode.SYSTEM.name()); - - themePref.setEntries(themeEntries.toArray(new String[0])); - themePref.setEntryValues(themeValues.toArray(new String[0])); - - if (TextUtils.isEmpty(themePref.getEntry())) { - themePref.setValue(DarkMode.SYSTEM.name()); - themePref.setSummary(TextUtils.isEmpty(themePref.getEntry()) ? DarkMode.SYSTEM.name() : themePref.getEntry()); - } - - themePref.setOnPreferenceChangeListener((preference, newValue) -> { - DarkMode mode = DarkMode.valueOf((String) newValue); - preferences.setDarkThemeMode(mode); - MainApp.setAppTheme(mode); - setListBackground(); - - return true; - }); } private void setListBackground() { getListView().setBackgroundColor(ContextCompat.getColor(this, R.color.bg_default)); } - private String getAppVersion() { - String temp; - try { - PackageInfo pkg = getPackageManager().getPackageInfo(getPackageName(), 0); - temp = pkg.versionName; - } catch (NameNotFoundException e) { - temp = ""; - Log_OC.e(TAG, "Error while showing about dialog", e); - } - return temp; - } - @Override public boolean onOptionsItemSelected(MenuItem item) { finish(); @@ -1120,8 +1231,9 @@ private void saveStoragePath(String newStoragePath) { SharedPreferences.Editor editor = appPrefs.edit(); editor.putString(AppPreferencesImpl.STORAGE_PATH, storagePath); editor.apply(); - String storageDescription = DataStorageProvider.getInstance().getStorageDescriptionByPath(storagePath); - prefStoragePath.setSummary(storageDescription); + //Not required for NMC + //String storageDescription = DataStorageProvider.getInstance().getStorageDescriptionByPath(storagePath); + //prefStoragePath.setSummary(storageDescription); prefStoragePath.setValue(newStoragePath); } @@ -1133,8 +1245,9 @@ private void loadStoragePath() { // 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); + //Not required for NMC + //String storageDescription = DataStorageProvider.getInstance().getStorageDescriptionByPath(storagePath); + //prefStoragePath.setSummary(storageDescription); } @Override diff --git a/app/src/main/java/com/owncloud/android/utils/StringUtils.java b/app/src/main/java/com/owncloud/android/utils/StringUtils.java index 5c6871dcab73..cab320ee9901 100644 --- a/app/src/main/java/com/owncloud/android/utils/StringUtils.java +++ b/app/src/main/java/com/owncloud/android/utils/StringUtils.java @@ -21,6 +21,10 @@ package com.owncloud.android.utils; +import android.text.Spannable; +import android.text.SpannableString; +import android.text.style.ForegroundColorSpan; + import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -69,6 +73,15 @@ String searchAndColor(@Nullable String text, @Nullable String searchText, } } + public static Spannable getColorSpan(@NonNull String title, @ColorInt int color) { + Spannable text = new SpannableString(title); + text.setSpan(new ForegroundColorSpan(color), + 0, + text.length(), + Spannable.SPAN_INCLUSIVE_INCLUSIVE); + return text; + } + public static @NonNull String removePrefix(@NonNull String s, @NonNull String prefix) { diff --git a/app/src/main/res/drawable/item_divider.xml b/app/src/main/res/drawable/item_divider.xml new file mode 100644 index 000000000000..9f742e91d67c --- /dev/null +++ b/app/src/main/res/drawable/item_divider.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/app/src/main/res/layout/custom_app_preference_layout.xml b/app/src/main/res/layout/custom_app_preference_layout.xml new file mode 100644 index 000000000000..5c8ab83fae4c --- /dev/null +++ b/app/src/main/res/layout/custom_app_preference_layout.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/custom_preference_layout.xml b/app/src/main/res/layout/custom_preference_layout.xml new file mode 100644 index 000000000000..9184eeab87a1 --- /dev/null +++ b/app/src/main/res/layout/custom_preference_layout.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml new file mode 100644 index 000000000000..56687e19ad40 --- /dev/null +++ b/app/src/main/res/values-de/strings.xml @@ -0,0 +1,1020 @@ + + + %1$s Android App + Über + Version %1$s + Version %1$s, Build #%2$s + Kontoerstellung fehlgeschlagen + Konto-Icon + Kein Konto gefunden + Fehlgeschlagene Uploads entfernen + Bearbeiten + Alle Benachrichtigungen löschen + Papierkorb leeren + Senden/Teilen + Rasteransicht + Listenansicht + Kontakte & Kalender wiederherstellen + Kontakte sichern + Kopieren + Neuer Ordner + Verschieben + Öffnen mit + Suche + Details + Senden + Einstellungen + Sortieren + Aktiver Nutzer + Bislang keine Aktivitäten + Bisher keine Ereignisse wie Hinzugekommenes, Änderungen und Freigaben + Senden + Link senden an… + Aktivitäten + Weiteren Link hinzufügen + Öffentlichen Link zum Teilen hinzufügen + Neue sichere Dateiablage hinzufügen + Hinzufügen zu %1$s + Erweiterte Einstellungen + Weiterteilen erlauben + Zeigt ein Widget aus dem Dashboard an + Suche in %s + Verknüpftes Konto nicht gefunden! + Zugriffsfehler: %1$s + Das Konto ist bislang auf dem Gerät nicht vorhanden + Ein Konto für den gleichen Benutzer und Server existiert auf diesem Gerät bereits + Der eingegebene Benutzer passt nicht zu dem Benutzer dieses Kontos + Unbekannte Serverversion + Verbindung hergestellt + Ihr Server gibt keine korrekte Benutzer-ID zurück, bitte kontaktieren Sie einen Administrator. + Serveradresse https://… + Falsches Adressformat für den Server + Server nicht gefunden + Keine Netzwerkverbindung + Sichere Verbindung nicht verfügbar. + Fehlerhafte Serverkonfiguration + Autorisierung nicht erfolgreich + Zugriff durch den Autorisierungsserver abgelehnt + Die gesicherte Verbindung wird durch eine ungesicherte Route geleitet. + Sichere Verbindung hergestellt + SSL-Initialisierung fehlgeschlagen + SSL-Server-Identität konnte nicht überprüft werden + Verbindung testen + Der Server braucht zu lange für eine Antwort. + Versuche Anmeldung… + Falscher Benutzername oder Passwort + Unbekannter Fehler: %1$s + Es ist ein unbekannter HTTP-Fehler aufgetreten! + Es ist ein unbekannter Fehler aufgetreten. + Konnte den Host nicht finden + %1$s unterstützt nicht mehrere Benutzerkonten + Verbindung konnte nicht hergestellt werden + im Original-Verzeichnis belassen, da nur lesbar + Nur über gebührenfreies WLAN hochladen + /AutoUpload + Einrichten + Erstellen Sie ein Setup für den eigenen Ordner + Erstellen Sie einen eigenen Ordner + Energiesparmodus deaktivieren + Ordner verstecken + Avatar + Abwesend + Sicherungseinstellungen + Kontakte & Kalender-Sicherung + Schliessen + Deaktivieren + Ihr Gerät hat möglicherweise Batterieoptimierung aktiv. AutoUpload funktioniert nur dann richtig, wenn Sie diese App davon ausschließen. + Batterie-Optimierung + Durch zu viele Fehlversuche verzögert + Kalender + Kalender + Beim Laden des Zertifikats ist ein Fehler aufgetreten. + Änderungen in der Entwicklerversion + Schauen Sie später noch einmal vorbei oder laden Sie neu. + Checkbox + Wähle einen lokalen Ordner… + Ort wählen + Wähle einen entfernten Ordner … + Bitte eine Vorlage auswählen und einen Dateinamen eingeben. + Wählen Sie, welche Datei behalten werden soll! + Widget auswählen + Löschen der Benachrichtigungen fehlgeschlagen. + Statusnachricht löschen + Statusnachricht löschen nach + Text von %1$s kopiert + Kein Text zum Kopieren in die Zwischenablage empfangen + Link kopiert + Unerwarteter Fehler beim Kopieren in die Zwischenablage + Zurück + Abbrechen + Synchronisierung abbrechen + Konto auswählen + Bestätigen + Kopieren + Löschen + Fehler + Nicht genügend Speicher + Unbekannter Fehler + Lade… + Nächste + Nein + OK + Ausstehend + Löschen + Umbenennen + Speichern + Auswählen + Senden + Teilen + Überspringen + Konto wechseln + Zu Konto wechseln + Ja + Testen Sie die Entwickler-Version + Dies beinhaltet neue Funktionalitäten und ist nicht komplett qualitätsgesichert. Es können daher Fehler/Bugs auftreten, melden Sie uns solche bitte. + Forum + Helfen Sie anderen auf + Überprüfen, Ändern und Schreiben von Code, weitere Enzelheiten finden Sie hier: %1$s. + Aktiv etwas beitragen + die App + Übersetzen + Entwicklungs-Version direkt herunterladen + Entwicklungs-Version über die F-Droid-App beziehen + Release-Kandidat über die F-Droid-App beziehen + Release-Kandidat über den Google-Play-Store beziehen + Vorabversion + Der Release-Kandidat (RC) ist eine Vorschau auf die kommende Version und sollte stabil sein. Das Testen des RC unter Ihrer individuellen Umgebung kann helfen, die Stabilität und Qualität zu sichern. Registrieren Sie sich als Tester im Play-Store oder schauen Sie in die \"Version\"-Sektion auf F-Droid. + Fehler gefunden? Komisches Verhalten? + Helfen Sie durch Testen + Fehlerbericht auf GitHub erstellen + Konfigurieren + Lokale Verschlüsselung entfernen + Wollen Sie %1$s wirklich löschen? + Möchten Sie die ausgewählten Elemente wirklich löschen? + Wollen Sie %1$s und deren Inhalte wirklich löschen? + Möchten Sie die ausgewählten Elemente und deren inhalt wirklich löschen? + Nur lokal + Fehler beim Erstellen des Konfliktdialoges + Konflikt-Datei %1$s + Lokale Datei + Falls beide Versionen gewählt werden, wird bei der lokalen Datei eine Zahl am Ende des Dateinamens hinzugefügt. + Server-Datei + Kontakte-Backup + Nutzericon für Kontaktliste + Keine Berechtigung vergeben, es wurde nichts importiert. + Kontakte + Jetzt sichern + Sicherung geplant und wird in Kürze starten + Import geplant und wird in Kürze starten + Keine Datei gefunden + Wir können Ihr letztes Backup nicht finden! + In die Zwischenablage kopiert + Es ist ein Fehler beim Kopieren der Datei oder des Ordners aufgetreten. + Es ist nicht möglich, einen Ordner in einen seiner Unterordner zu kopieren + Die Datei existiert bereits im Zielverzeichnis + Kopieren nicht möglich. Bitte prüfen Sie, ob die Datei existiert. + Link kopieren + In verschlüsselten Ordner kopieren/verschieben wird aktuell nicht unterstützt. + Kopieren nach… + Originalbild konnte nicht heruntergeladen werden + Konnte die Freigaben nicht abrufen + Konnte URL nicht abrufen + Erstellen + Verzeichnis konnte nicht erstellt werden + Neu erstellen + Neues Dokument erstellen + Neuen Ordner erstellen + Neue Präsentation erstellen + Neue Tabelle erstellen + Ordnerinfo hinzufügen + Ordnerinfo erstellen + Zugangsdaten ausgeschaltet + Tägliche Sicherung + Zu sichernde Daten + Zugangsdaten falsch + Benutzerkonto löschen + Konto %s und alle lokalen Dateien löschen?\n\nLöschung kann nicht rückgängig gemacht werden. + Einträgen entfernen + Link löschen + Auswahl aufheben + Ziel-Dateiname + Neue Version verfügbar + Keine Information verfügbar. + Keine neue Version verfügbar. + Schließen + Es wurde nicht auf Duplikate geprüft. + Dieser Algorithmus-Auszug ist auf Ihrem Handy nicht verfügbar. + Anmeldung über Direktlink fehlgeschlagen! + Mit %1$s an %2$s anmelden + Ausschalten + Ausblenden + Benachrichtigung verwerfen + Zeigt Ihre 12-Wörter-Passphrase an + Bitte nicht stören + Mehrere Bilder + PDF-Datei + Exporttyp wählen + PDF-Erstellung fehlgeschlagen + Erstelle PDF… + Fertig + Nicht löschen + Datei kann lokal nicht erstellt werden + Ungültiger Dateiname für lokale Datei + Die neueste Entwicklerversion herunterladen + Konnte %1$s nicht herunterladen + Herunterladen fehlgeschlagen, erneute Anmeldung erforderlich + Herunterladen fehlgeschlagen + Diese Datei steht auf dem Server nicht mehr zur Verfügung + %1$d%% Herunterladen %2$s + Lade herunter… + %1$s heruntergeladen + Heruntergeladen + Noch nicht Heruntergeladen + Hauptmenü schließen + Gemeinschaft + Hintergrundbild des Kopfbereiches + Aktivitäten + Alle Dateien + Favoriten + Medien + Gruppenordner + Home + Benachrichtigungen + Auf dem Gerät + Kürzlich geändert + Geteilt + Gelöschte Dateien + Uploads + Abmelden + Hauptmenü öffnen + %1$s von %2$s verwendet + %1$s verwendet + Automatisches Hochladen + E2E bislang nicht eingerichtet + Ohne Internetverbindung nicht möglich + Mehr + Notizen + Talk + Weitere Nextcloud-Apps + Nextcloud Notizen + Nextcloud Talk + Als verschlüsselt festlegen + Verschlüsselung einrichten + Entschlüssele… + Schließen + Geben Sie bitte das Passwort ein, um den privaten Schlüssel zu entschlüsseln. + Dieser Ordner ist nicht leer. + Neue Schlüssel generieren… + Diese 12 Wörter-Phrase ist wie ein sehr starkes Passwort: Sie bietet vollen Zugriff um Ihre verschlüsselten Dateien anzusehen und zu verwenden. Bitte schreiben Sie sie auf und verwahren sie an einem sicheren Ort. + Ende-zu-Ende Verschlüsselung ist auf diesem Server deaktiviert. + Notieren Sie Ihre Verschlüsselungs-Passphrase + Passwort… + Schlüssel abrufen… + Schlüssel speichern + Verschlüsselung einrichten + Die Schlüssel konnten nicht gespeichert werden. Bitte erneut versuchen. + Fehler beim Entschlüsseln. Falsches Passwort? + Ziel-Dateiname eingeben + Bitte Dateinamen eingeben + %1$s konnte nicht in den lokalen %2$s Ordner kopiert werden + Kritischer Fehler: Operationen können nicht ausgeführt werden + Fehler beim Auswählen des Datums + Fehler beim Kommentieren der Datei + %1$s abgestürzt + Fehler beim Erzeugen einer Datei aus der Vorlage + Fehler beim Anzeigen von Dateiaktionen + Fehler beim Ändern des Sperr-Status + Melden + Problem melden? (benötigt ein GitHub-Konto) + Fehler beim Abruf der Datei + Fehler beim Laden der Vorlagen + Fehler beim Anzeigen des Setup-Dialogs für Verschlüsselung! + Fehler beim Starten der Kamera + Start des Dokumentenscans fehlgeschlagen + Konten + Aufgabenname + Fortschritt + Gestartet + Status + Benutzer + UUID + Hintergrund-Aufgaben + Alle Aufgaben abbrechen + Inaktive Aufgaben bereinigen + Test-Aufgabe planen + Test-Aufgabe starten + Test-Aufgabe stoppen + Migrationen (App-Aktualisierung) + Einstellungen + Technischer Testmodus + Dateiübertragung + Test-Download in die Warteschlange stellen + Test-Upload in die Warteschlange stellen + Entfernter Pfad + Übertragen + Herunterladen + Hochladen + Hinzufügen oder hochladen + Datei konnte nicht an den Downloadmanager übergeben werden + Drucken der Datei fehlgeschlagen + Starten des Editors fehlgeschlagen + Oberfläche konnte nicht aktualisiert werden + Zu den Favoriten hinzufügen + Favoriten + Dateiname bereits vorhanden + Löschen + Fehler beim Abrufen der Aktivitäten für die Datei + Fehler beim Laden der Details + Datei + Behalten + Laden Sie Inhalt hoch oder synchronisieren Sie mit Ihren Geräten. + Noch keine Favoriten vorhanden + Dateien und Ordner, die als Favoriten markiert werden, erscheinen hier. + Keine Bilder oder Videos gefunden + Keine Dateien vorhanden + Keine Ergebnisse in diesem Ordner + Keine Ergebnisse + Noch nichts vorhanden. Sie können einen Ordner hinzufügen. + Heruntergeladene Dateien und Ordner werden hier angezeigt werden. + Keine, innerhalb der letzten 7 Tage, geänderten Dateien gefunden + Vielleicht befindet es sich in einem anderen Ordner? + Von Ihnen geteilte Dateien und Ordner werden hier angezeigt. + Noch nichts geteilt + Keine Ergebnisse für Ihre Suche gefunden + Ordner + Lade… + Es wurde keine App für diesen Dateityp gefunden. + Gerade eben + Berechtigungen erforderlich + Speicherberechtigungen + %1$s funktioniert am besten mit Berechtigungen für den Zugriff auf den Speicher. Sie können vollen Zugriff auf alle Dateien oder schreibgeschützten Zugriff auf Fotos und Videos wählen. + %1$s benötigt Dateiverwaltungsberechtigungen, um Dateien hochzuladen. Sie können vollen Zugriff auf alle Dateien oder schreibgeschützten Zugriff auf Fotos und Videos wählen.  + Prüfe Zielort… + Aufräumen… + Aktualisiere Speicherordner + Daten-Verzeichnis existiert bereits. Bitte auswählen: + Nextcloud-Verzeichnis existiert bereits + Mehr Speicherplatz benötigt + Quelldatei kann nicht gelesen werden + Für das Ziel existieren keine Schreibrechte + Migration fehlgeschlagen + Aktualisierung des Index fehlgeschlagen + Verschiebe Daten… + Abgeschlossen + Überschreiben + Bereite Migration vor… + Konfiguration der Konten wiederherstellen… + Sichere Konfiguration der Konten… + Möchten Sie wirklich den Speicherordner in %1$s ändern?\n\nHinweis: Alle Daten müssen dann erneut heruntergeladen werden. + Quellverzeichnis kann nicht gelesen werden! + Aktualisiere Index… + Verwende bestehenden + Warte auf die Fertigstellung aller Synchronisierungen … + Datei nicht gefunden + Die gewünschte Datei konnte nicht synchronisiert werden. Die letzte verfügbare Version wird angezeigt. + Umbenennen + Fehler beim Wiederherstellen der Dateiversion! + Dateiversion erfolgreich wiederhergestellt + Details + Herunterladen + Exportieren + Datei während des Hochladens in %1$s umbenannt + Synchronisieren + Keine Datei gewählt + Dateiname darf nicht leer sein + Verbotene Zeichen: / \\ < > : \" | ? * + Der Dateiname enthält mindestens ein ungültiges Zeichen + Dateiname + Halten Sie Ihre Daten sicher und unter Ihrer Kontrolle + Sichere Zusammenarbeit & Dateiaustausch + Benutzerfreundliche Webmailer, Kalender & Kontakte + Bildschirm teilen, Online-Meetings& Web-Konferenzen + Ordner existiert bereits + Erstellen + Keine Ordner vorhanden + Auswählen + Ihnen fehlt die Erlaubnis %s + diese Datei zu kopieren + diese Datei zu erstellen + diese Datei zu löschen + um diese Datei zu verschieben + diese Datei umzubenennen + Dateien werden heruntergeladen… + Dateien werden hochgeladen… + Einige Dateien konnten nicht verschoben werden + Lokal: %1$s + Alle verschieben + Remote: %1$s + Alle Dateien wurden verschoben + Weiterleiten + 4 Stunden + Dateiname führt dazu, das die Datei versteckt sein wird. + Name + Notiz + Passwort + Server nicht verfügbar + Eigenen Server betreiben + Symbol für leere Liste + Symbol des Dashboard-Widgets + Symbol des Widget-Eintrags + Bearbeitet + Horizontal spiegeln + Vertikal spiegeln + Gegen den Uhrzeigersinn drehen + Im Uhrzeigersinn drehen + Bild konnte nicht bearbeitet werden. + Dateidetails + Bedingungen für die Bildaufnahme + ƒ/%s + ISO %s + %s MP + %s mm + %s s + in Ordner %1$s + Vorhandene Dateien ebenfalls hochladen + Nur während des Ladens der Batterie hochladen + /SofortUpload + Ungültige URL + Unsichtbar + Bezeichnung darf nicht leer sein + Letzte Sicherung:%1$s + Link + Link-Name + Hochladen und Bearbeiten erlauben + Bearbeitung + Dateien ablegen (nur Hochladen) + Nur anzeigen + Layout der Liste + Weitere Ergebnisse laden + Es befinden sich keine Dateien in diesem Ordner. + Die Datei wurde im lokalen Dateisystem nicht gefunden + %1$s/%2$s + Hier gibt es keine weiteren Ordner. + Ordner finden + Läuft ab: %1$s + Datei sperren + Gesperrt von %1$s + Gesperrt von der App %1$s + %1$s Android-App Meldungen + Keine App zum Senden von Protokolldateien gefunden. Bitte installieren Sie einen E-Mail-Client. + Angemeldet als %1$s + Anmelden + Der Link zu Ihrer %1$s Webseite, wenn Sie diese im Browser öffnen. + Lösche Logs + Aktualisieren + Suche Logs + Protokolldateien per E-Mail versenden + Logs: %1$d kB, Abfragetreffer %2$d / %3$d in %4$d ms + Lade… + Logs: %1$d kB, kein Filter + Protokolle (Logs) + Server befindet sich im Wartungsmodus + Daten löschen + Einstellungen, Datenbank und Server-Zertifikate von %1$s\'s Daten werden dauerhaft gelöscht.\n\nHerunter geladene Dateien bleiben unangetastet.\n\nDieser Vorgang kann eine Zeit dauern. + Verwalte Speicherplatz + Die Mediendatei kann nicht gestreamt werden + Konnte die Mediendatei nicht lesen + Mediendatei ist nicht korrekt encodiert + Wartezeit beim Abspielversuch abgelaufen + Der interne Player kann die Mediendatei nicht abspielen + Medien-Codec wird nicht unterstützt + Vorspulknopf + %1$s Musik Player + Wiedergabe-/Pause Knopf + Rückspulknopf + %1$s (wird abgespielt) + Neue zuerst + Älteste zuerst + A - Z + Z - A + Größte zuerst + Kleinste zuerst + Mehr + Es ist ein Fehler beim Verschieben der Datei oder des Ordners aufgetreten. + Es ist nicht möglich, einen Ordner in einen seiner Unterordner zu verschieben + Die Datei ist bereits im Zielordner vorhanden + Verschieben nicht möglich. Bitte prüfen Sie, ob die Datei existiert. + Verschieben nach… + Es ist ein Fehler beim Warten auf den Server aufgetreten, die Operation konnte nicht abgeschlossen werden. + Es ist ein Fehler beim Verbinden mit dem Server aufgetreten. + Es ist ein Fehler beim Warten auf den Server aufgetreten, die Operation konnte nicht abgeschlossen werden + Die Operation kann nicht abgeschlossen werden, der Server ist nicht erreichbar. + Neuer Kommentar… + Neuer Medienordner %1$s gefunden. + Foto + Video + Neue Benachrichtigung + Neue Version erstellt + Keine Aktionen für diesen Benutzer + Keine App verfügbar um Links zu öffnen + Es existieren keine Kalender + Keine App verfügbar, um E-Mail-Adressen zu verarbeiten + Keine Elemente + Keine App zur Kartenverwaltung verfügbar + Nur ein Konto zulässig + Keine App verfügbar um PDFs anzuzeigen + Keine App zum Senden der ausgewählten Dateien verfügbar + Bitte mindestens eine Berechtigung zum Teilen auswählen. + Senden + Notiz konnte nicht versandt werden + Notiz-Symbol + Ausführen der Aktion fehlgeschlagen. + Zeigt den Herunterlade-Fortschritt an + Downloads + Zeigt den Fortschritt der Dateisynchronisierung und die Ergebnisse an + Dateisynchronisierung + Für neue Medienordner und ähnliches Benachrichtigungen anzeigen + Allgemeine Benachrichtigungen + Musik-Player Fortschritt + Media-Player + Vom Server gesendete Push-Benachrichtigungen anzeigen: Erwähnungen in Kommentaren, Zugriff auf externe Freigaben erhalten, Ankündigungen von Administratoren erhalten, etc. + Push-Benachrichtigungen + Zeigt den Hochlade-Fortschritt an + Uploads + Benachrichtigungssymbol + Keine Benachrichtigungen + Bitte später noch einmal nachsehen. + Keine Internetverbindung + 1 Stunde + Online + Online-Status + Die Serverversion wird nicht mehr unterstützt, bitte aktualisieren Sie diesen! + Weiteres Menü + PIN eingeben + Die PIN wird jedes mal beim Start der App abgefragt + Bitte geben Sie Ihre PIN ein + Die PINs stimmen nicht überein + Bitte Ihre PIN nochmals eingeben + Ihre PIN löschen + PIN gelöscht + PIN gespeichert + PIN nicht korrekt + Passwortgeschützte PDF-Datei konnte nicht geöffnet werden. Bitte verwenden Sie einen externen PDF-Viewer. + Auf eine Seite klicken um hereinzuzoomen + Zulassen + Ablehnen + Sie haben nicht die erforderlichen Rechte, um Dateien hoch- oder herunterzuladen. + Keine App gefunden, mit der ein Bid gesetzt werden könnte + An Startbildschirm anheften + %1$s öffnen + 389 KB + platzhalter.txt + 12:23:45 + Dies ist ein Platzhalter + 18.5.2012 12:23 + Stopp + Umschalten + Bei deaktiviertem Energiesparmodus werden Daten auch bei niedrigem Batterieladezustand hochgeladen. + gelöscht + im Originalordner behalten + in den App-Ordner verschoben + Was tun, wenn die Datei bereits vorhanden ist? + Mich jedesmal fragen + Hochladen überspringen + Version auf dem Server überschreiben + Neue Version umbenennen + Was tun, wenn die Datei bereits vorhanden ist? + Konto hinzufügen + Kalender & Kontakte synchronisieren + Weder F-Droid noch Google-Play sind installiert + DAVx5 (zuvor bekannt als DAVdroid) (v1.3.0+) für aktuelles Konto einrichten + Kalender- & Adress-Synchronisierung konfigurieren + Über + Details + Dev + Allgemein + Mehr + Tägliche Sicherung Ihrer Kalender & Kontakte + Tägliche Sicherung Ihrer Kontakte + Unerwarteter Fehler beim Einrichten von DAVx5 (früher bekannt als DAVdroid) + Ende-zu-Ende-Verschlüsselung ist eingerichtet! + E2E-Gedächtnisstütze + Um die Gedächtnisstütze anzuzeigen, aktivieren Sie bitte Geräte-Zugangsdaten + 12-Wort-Schlüssel anzeigen (Passphrase) + Benachrichtigungen der Mediensuche anzeigen + Über neu gefundene Medienordner informieren + GNU General Public Lizenz, version 2 + Hilfe + Impressum + Originaldatei wird… + Originaldatei wird… + Nach Datum in Unterordnern speichern + Unterordner benutzen + Unterordneroptionen + Diesem Client Ende-zu-Ende-Verschlüsselung hinzufügen + Lizenz + App-PIN + Geräte-Anmeldedaten aktiviert + Keine Geräte-Anmeldedaten eingerichtet. + Nichts + App schützen mittels + Geräte-Anmeldedaten + PIN + Konten verwalten + Einem Freund empfehlen + Verschlüsselung lokal entfernen + Ende-zu-Ende-Verschlüsselung einrichten + App-Umschalter anzeigen + Nextcloud-App-Vorschläge in der Navigationsüberschrift + Versteckte Dateien anzeigen + Zum Programmcode + Speicherordner + Ordner für \"Automatisches Hochladen\" verwalten + Lokaler Ordner + Remote-Ordner + Design + Dunkel + Hell + Systemvorgaben verwenden + Bildvorschau + Keine lokale Datei für die Vorschau vorhanden + Bild kann nicht angezeigt werden + Entschuldigung + Datenschutz + Neuer Name + Push Benachrichtigungen deaktiviert aufgrund der Abhängigkeiten zu proprietären Google Play Diensten. + Keine Push Benachrichtigungen aufgrund veralteter Benutzersitzung. Bitte erwägen Sie das erneute Hinzufügen Ihres Kontos. + Push Benachrichtigungen aktuell nicht verfügbar. + QR-Code konnte nicht gelesen werden! + Probieren Sie %1$s auf Ihrem Smartphone + Ich empfehle Ihnen %1$s auf Ihrem Smartphone zu nutzen.\nHerunterladen: %2$s + %1$s oder %2$s + Inhalt aktualisieren + Neu laden + (entfernt) + Datei nicht gefunden! + Sie können die Ende-zu-Ende-Verschlüsselung lokal auf diesem Client entfernen + Sie können die Ende-zu-Ende-Verschlüsselung lokal auf diesem Client entfernen. Die verschlüsselten Dateien bleiben auf dem Server, werden aber nicht mehr mit diesem Computer synchronisiert. + Löschung fehlgeschlagen + Entfernen der Benachrichtigungen fehlgeschlagen. + Entfernen + Gelöscht + Geben Sie einen neuen Namen ein + Die lokale Kopie konnte nicht umbenannt werden. Versuche es mit einem anderen Namen. + Umbenennen nicht möglich. Der Name wird bereits verwendet. + Das Weiterverteilen ist nicht erlaubt + Resharing/Wiederteilen ist nicht erlaubt. + Kein verkleinertes Bild verfügbar. Vollbild herunterladen? + Datei wiederherstellen + Letzte Sicherung wiederherstellen + Gelöschte Datei wiederherstellen + Ausgewählte wiederherstellen + Abrufen der Datei… + Laden des Dokuments fehlgeschlagen! + Anmelden mit QR-Code + Seite scannen + Schützt Ihre Daten + Selbst gehostete Produktivität + Durchsuchen und teilen + Alle Aktionen schnell erreichbar + Aktivitäten, Freigaben, … + Alles schnell erreichbar + All ihre Konten + an einem Ort + Automatisches Hochladen + ihrer Fotos & Videos + Kalender & Kontakte + Synchronisiere mit DAVx5 + Fehler beim Abrufen der Suchergebnisse + Alle auswählen + Medien-Ordner auswählen + Bitte eine Vorlage auswählen + Vorlage auswählen + Senden + Notiz an Empfänger senden + Freigabe senden + Icon für den Senden-Button + Setze als + Notiz setzen + Nutze Bild als + Status setzen + Statusnachricht setzen + Während der Einrichtung der Ende-zu-Ende-Verschlüsselung erhalten Sie eine zufällige 12-Wörter-Gedächtnisstütze, die Sie benötigen, um Ihre Dateien auf anderen Geräten zu öffnen. Diese wird nur auf diesem Gerät gespeichert und kann in diesem Bildschirm erneut angezeigt werden. Bitte notieren Sie es an einem sicheren Ort! + Teilen + Teilen & Link kopieren + Teilen + %1$s + Läuft am %1$s ab + Teile %1$s + %1$s (Gruppe) + Internen Link teilen + Der interne Freigabelink funktioniert nur für Benutzer mit Zugriff auf diese Datei + Der interne Freigabelink funktioniert nur für Benutzer mit Zugriff auf diesen Ordner + auf %1$s + Link teilen + Sie müssen ein Passwort eingeben + Es ist ein Fehler beim Freigeben der Datei oder des Ordners aufgetreten. + Teilen nicht möglich. Bitte prüfen Sie, ob die Datei existiert. + diese Datei zu teilen + Passwort eingeben (optional) + Passwort eingeben + Teile Link (%1$s) + Ablaufdatum setzen + Passwort setzen + Passwortgeschützt + Kann bearbeiten + Dateiablage + Sichere Dateiablage + Nur anzeigen + Berechtigungen zum Teilen + %1$s (remote) + %1$s (Unterhaltung) + Name, Federated-Cloud-ID oder E-Mail-Adresse … + Neue E-Mail senden + Notiz an Empfänger + Einstellungen + Download verbergen + Link teilen + Link teilen + Entfernen + Teilen mit… + Avatar des geteilten Nutzers + Teilen + geteilt + Über einen Link geteilt + Geteilt mit Ihnen von %1$s + Freigeben fehlgeschlagen + Fotos anzeigen + Videos anzeigen + Mit Provider anmelden + Zulassen, dass %1$s auf Ihr Nextcloud Konto %2$s zugreifen darf? + Sortiere nach + Neue zuerst + Älteste zuerst + A - Z + Z - A + Kleinste zuerst + Größste zuerst + Ausblenden + Details + Die Identität des Servers konnte nicht verifiziert werden + Land: + Üblicher Name: + Ort: + Organisation: + Organisationseinheit: + Bundesland: + Fingerabdruck: + Ausgestellt von: + Signatur: + Algorithmus: + Ausgestellt für: + Gültigkeit: + Von: + Bis: + - Keine Informationen über den Fehler + Das Zertifikat konnte nicht gespeichert werden + Das Zertifikat konnte nicht angezeigt werden. + Soll diesem Zertifikat trotzdem vertraut werden? + - Das Zertifikat des Servers ist abgelaufen + - Das Zertifikat des Servers ist nicht vertrauenswürdig + - Das Gültigkeitsdatum des Serverzertifikats liegt in der Zukunft + - Die Adresse stimmt nicht mit dem im Zertifikat angegebenen Hostnamen überein + Statusnachricht + Kamera + Speicherort auswählen + Standard + Dokumente + Downloads + Interner Speicher + Filme + Musik + Voller Zugriff + Medien schreibgeschützt + Bilder + Die selbst gehostete Produktivitätsplattform gibt Ihnen die volle Kontrolle.\n\nFunktionen:\n* Einfache, moderne Oberfläche. Angepasst an das Design Ihres Servers\n* +.\n\nEigenschaften:\n* Einfache, moderne an Ihr Design angepasste Oberfläche\n* Laden Sie Ihre Dateien auf Ihren Nextcloud Server\n* Teilen Sie Ihre Dateien mit anderen\n* Halten Sie Ihre favorisierten Dateien und Ordner synchron\n* Suche über alle Ordner auf Ihrem Server\n* Automatisches Hochladen von Fotos und Videos von Ihrem Gerät\n* Bleiben Sie auf dem Laufenden durch Benachrichtigungen\n* Mehrere Konten gleichzeitig\n* Geschützter Zugriff durch Fingerabdruck oder PIN\n* Integration mit DAVx5 (ehemals DAVdroid) für einfaches Konfigurieren der Kalender- & Kontakte-Synchronisierung\n\nBitte melden Sie alle Probleme unter https://github.com/nextcloud/android/issues oder diskutieren Sie über die App auf https://help.nextcloud.com/c/clients/android\n\nWas ist die Nextcloud? Die Nextcloud ist ein privater Dateiaustausch & -synchronisierungs Server. Nextcloud ist Open Source und kann auf einem eigenen Server installiert werden. So behalten Sie die Kontrolle über Ihre Fotos, Ihre Kalender und Kontakte, Ihre Dokumente und alle anderen Daten.\n\nSchauen Sie sich Nextcloud an unter https://nextcloud.com. + Die selbst gehostete Produktivitätsplattform gibt Ihnen die volle Kontrolle.\nDies ist die offizielle Entwicklungsversion und bietet neue, ungetestete Funkitionen. Dies kann zu Instabilitäten und Datenverlust führen. Die App ist für alle Benutzer, die Testen wollen und falls nötig Fehlerberichte erstellen. Nutzen Sie diese Version nicht für Ihre Produktivarbeit!\n\nSowohl die reguläre als auch die Entwicklerversion sind auf F-droid verfügbar und können parallel installiert werden. + Die selbst gehostete Produktivitätsplattform gibt Ihnen die volle Kontrolle + Die selbst gehostete Produktivitätsplattform gibt Ihnen die volle Kontrolle (Vorab- Entwicklungsversion) + Streamen mit… + Internes Streamen nicht möglich + Laden Sie sich den Inhalt herunter oder nutzen Sie eine externe App. + Strikter Modus: keine HTTP-Verbindung erlaubt! + Jahr/Monat/Tag + Jahr/Monat + Jahr + \"%1$s\" wurde mit Ihnen geteilt + %1$s hat \"%2$s\" mit Ihnen geteilt + Nur Fotos + Fotos & Videos + Nur Videos + Vorschlagen + Konflikte gefunden + Der Ordner %1$s existiert nicht mehr + Synchronisierung von %1$s konnte nicht abgeschlossen werden + Falsches Passwort für %1$s + Synchronhalten schlug fehl. + Synchronisierung fehlgeschlagen + Synchronisierung fehlgeschlagen. Sie müssen sich erneut anmelden + Dateiinhalte bereits synchronisiert + Synchronisation von Ordner %1$s konnte nicht fertiggestellt werden + Seit Version 1.3.16 werden Dateien, die von diesem Gerät aus hochgeladen werden, in den lokalen Ordner %1$s kopiert, um Datenverlust zu vermeiden, wenn eine einzelne Datei mit mehreren Konten synchronisiert wird.\n\nInfolge dieser Änderung wurden alle Dateien, die mit vorherigen Versionen dieser App hochgeladen wurden, in den Ordner %2$s verschoben. Jedoch ist während der Konto-Synchronisierung ein Fehler aufgetreten, der das Abschließen dieses Vorgangs verhindert hat. Sie können die Datei(en) entweder wie sie sind belassen und den Link zu %3$s löschen oder die Datei(en) in den Ordner %1$s verschieben und den Link zu %4$s beibehalten.\n\nUnten befindet sich eine Liste der lokalen Datei(en) und der mit ihnen verbundenen entfernten Datei(en) in %5$s. + Einige lokale Dateien wurden vergessen + Neueste Version der Datei wird geladen. + Zu synchronisierende Elemente auswählen + Speicherplatz freimachen + %1$s ist %2$s, jedoch ist nur noch %3$s auf diesem Gerät verfügbar. + Nicht genügend Speicherplatz + Status-synchronisieren-Button + Dateien + Einstellungs-Button + Ordner konfigurieren + Die Sofort-Uploads wurden vollständig überarbeitet. Konfiguriere Sie Ihren automatischen Uploader im Hauptmenü.\n\nGenießen Sie den verbesserten Auto-Upload. + Keine Medien-Ordner gefunden + Für %1$s + Typ + Synchronisiert + Schlagworte + Prüfe Server-Verbindung + 30 Minuten + Diese Woche + Vorschaubild + Miniaturbild für vorhandene Datei + Miniaturbild für neue Datei + Laden dauert länger als erwartet + Heute + Gelöschte Dateien + Keine gelöschten Dateien + Hier können Sie gelöschte Dateien wiederherstellen. + Datei %1$s konnte nicht gelöscht werden! + Datei %1$s konnte nicht wiederhergestellt werden! + Endgültig löschen + Laden des Papierkorbs fehlgeschlagen! + Dateien konnten nicht endgültig gelöscht werden! + Datei entsperren + Es gibt ungelesene Kommentare + Verschlüsselung aufheben + Aus den Favoriten entfernen + Es ist ein Fehler beim Entfernen der Freigabe für diese Datei oder den Ordner aufgetreten. + Entfernen der Freigabe nicht möglich. Bitte prüfen Sie, ob die Datei existiert. + diese Datei nicht mehr zu teilen + Freigabe aufheben fehlgeschlagen + Zugriff über nicht vertrauenswürdige Domain. Weitere Informationen finden sich in der Dokumentation. + Es ist ein Fehler bei der Aktualisierungd der Freigabe aufgetreten. + Aktualisierung nicht möglich. Bitte prüfen Sie, ob die Datei existiert. + zum Aktualisieren dieser Freigabe + Aktualisierung der Freigabe fehlgeschlagen + Datei kann lokal nicht erstellt werden + Dateien hochladen von… + Inhalt anderer Apps hochladen + Von Kamera hochladen + Dateiname + Dateityp + Google Maps Abkürzungs-Datei (%s) + Internet Abkürzungs-Datei (%s) + Schnipsel Textdatei (.txt) + Dateinamen und -typ zum Hochladen eingeben + Dateien hochladen + Button, um Objekt hochzuladen + Löschen + Keine Uploads verfügbar + Laden Sie Inhalte hoch oder aktivieren Sie den Auto Upload. + Konflikt lösen + Lokaler Speicher voll + Datei konnte nicht in den lokalen Speicher kopiert werden + Fehler beim Sperren des Ordners + Verschlüsselung ist nur möglich mit >= Android 5.0 + Es steht nicht genügend Speicherplatz zur Verfügung, um die ausgewählten Dateien in das Verzeichnis %1$s zu kopieren. Sollen diese stattdessen verschoben werden? + Dokument von der Kamera scannen + Synchronisierungskonflikt, bitte manuell beheben + Unbekannter Fehler + Auswählen + Hochladen + Empfangene Daten enthalten keine gültige Datei. + %1$s darf eine empfangene Datei nicht lesen + Es ist ein Fehler beim Kopieren dieser Datei in einen temporären Ordner aufgetreten. Bitte versuchen Sie erneut die Datei zu senden. + Die zum Hochladen ausgewählte Datei kann nicht gefunden werden. Bitte prüfen Sie ob die Datei existiert. + Diese Datei kann nicht hochgeladen werden + Keine Datei zum Hochladen + Ordnername + Kontoinformationen + Datenschutz + Datenschutz + Datenschutzbestimmungen + Verwendete OpenSource Software + Info + Bedienung + Die Ende-zu-Ende Verschlüsselung wurde bereits auf einem anderen Gerät eingerichtet. Bitte geben Sie Ihre Passphrase ein, damit die Dateien synchronisiert und entschlüsselt werden. + Hochladeordner auswählen + Konnte %1$s nicht hochladen + Hochladen fehlgeschlagen, bitte erneut anmelden + Dateikonflikt beim Hochladen + Wählen Sie, welche Version von %1$s behalten werden soll + Hochladen fehlgeschlagen + Upload Option: + Datei in Ordner %1$s verschieben + Quellverzeichnis ist nur lesbar; Datei wird nur hochgeladen + Hochladen und im Quellordner behalten + Hochladen und Datei im Quellordner löschen + diesen Ordner hochzuladen + %1$d%% Hochladen %2$s + Lade hoch… + %1$s hochgeladen + Beenden + Einrichten + Es sind keine %1$s Konten auf Ihrem Gerät eingerichtet. Bitte erstellen Sie zuerst ein Konto. + Kein Konto gefunden + Aktuell + Fehlgeschlagene/Wartende neustarten + Hochgeladen + Warte auf Hochladen + Uploads + Abgebrochen + Konflikt + Verbindungsfehler + Zugangsdaten falsch + Dateifehler + Ordnerfehler + Lokale Datei nicht gefunden + Berechtigungsfehler + Serverzertifikat ist nicht vertrauenswürdig + Serverversion wird abgerufen … + App beendet + Fertiggestellt + Unbekannter Fehler + Virus gefunden. Das Hochladen kann nicht abgeschlossen werden! + Warte auf Verlassen des Energiesparmodus + Warte auf das Aufladen des Gerätes + Warte auf nicht gebührenpflichtiges WLAN + Nutzer + Adresse + E-Mail + Telefonnummer + Twitter + Webseite + Fehler beim Laden der Nutzer-Informationen + Keine persönlichen Infos eingestellt + Fügen Sie Name, Bild und Kontaktdaten auf Ihrer Profilseite hinzu. + Benutzername + Herunterladen + Video Überlagerungsicon + Bitte warten… + Überprüfe gespeicherte Anmeldeinformationen + Kopiere Datei von privatem Speicher + Was-gibt\'s-Neues-Bild + Überspringen + Neu in %1$s + Wie ist Ihr Status? + Widgets sind nur auf %1$s 25 oder neuer verfügbar + Nicht verfügbar + E-Mail senden + Speicherordner existiert nicht! + Ursache könnte die Wiederherstellung einer Sicherungskopie auf einem anderen Gerät sein. Der Standard-Ordner wird jetzt wieder verwendet. Bitte überprüfen Sie die Einstellungen bezüglich des Speicherortes. + + Inhalte von %1$d Datei konnten nicht synchronisiert werden (Konflikte: %2$d) + Inhalte von %1$d Dateien konnten nicht synchronisiert werden (Konflikte: %2$d) + + + %1$d Datei im %2$s-Verzeichnis konnten nicht kopiert werden nach + %1$d Dateien im %2$s-Verzeichnis konnten nicht kopiert werden nach + + + %1$d Termin in %2$s geschrieben + %1$d Termine in %2$s geschrieben + + + %1$d neue UID erstellt + %1$d neue UIDs erstellt + + + %d Eintrag verarbeitet. + %d Einträge verarbeitet. + + + %d doppelter Eintrag gefunden. + %d doppelte Einträge gefunden. + + + %d Datei exportiert + %d Dateien exportiert + + + %d Datei konnte nicht exportiert werden + %d Dateien konnten nicht exportiert werden + + + %d Datei exportiert, der Rest wurde aufgrund von Fehlern übersprungen + %d Dateien exportiert, der Rest wurde aufgrund von Fehlern übersprungen + + + %d Datei wird exportiert. Einzelheiten finden Sie in der Benachrichtigung. + %d Dateien werden exportiert. Einzelheiten finden Sie in der Benachrichtigung. + + + %1$d Ordner + %1$d Ordner + + + %1$d Datei + %1$d Dateien + + + Zeige %1$dversteckten Ordner + Zeige %1$d versteckte Ordner + + + %d ausgewählt + %d ausgewählt + + diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index 08bf64d552ad..e926fdcc432f 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -48,4 +48,68 @@ #1E1E1E @android:color/white + + + #FFFFFF + @color/grey_30 + @color/grey_30 + #CCCCCC + @color/grey_70 + @color/grey_80 + #2D2D2D + @color/grey_70 + @color/grey_70 + + + @color/grey_80 + @color/grey_0 + + + @color/grey_80 + @color/grey_0 + + + @color/grey_60 + @color/grey_0 + @color/grey_0 + @color/grey_30 + #FFFFFF + @color/grey_30 + @color/grey_80 + #FFFFFF + + + @color/grey_80 + @color/grey_30 + @color/grey_0 + + + @color/grey_80 + @color/grey_0 + @color/grey_80 + + + @color/grey_70 + @color/grey_60 + + + @color/grey_70 + @color/grey_70 + + + #FFFFFF + @color/grey_30 + @color/grey_0 + @color/grey_0 + @color/grey_0 + @color/grey_0 + @color/grey_60 + @color/grey_0 + #FFFFFF + + + #121212 + @color/grey_0 + @color/grey_80 + @color/grey_80 diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 58fcdecf1fc2..b05b582157a7 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -82,4 +82,93 @@ @android:color/white #666666 #A5A5A5 + + + #191919 + @color/primary + #191919 + #191919 + @color/grey_30 + @android:color/white + #FFFFFF + @color/grey_0 + #CCCCCC + #77c4ff + #B3FFFFFF + @color/grey_10 + + + #101010 + #F2F2F2 + #E5E5E5 + #B2B2B2 + #666666 + #4C4C4C + #333333 + + + @color/design_snackbar_background_color + @color/white + + + #FFFFFF + #191919 + + + @color/grey_0 + #191919 + @color/primary + #191919 + @color/primary + @color/grey_30 + @color/white + #191919 + + + #FFFFFF + #191919 + #191919 + + + #FFFFFF + #191919 + #FFFFFF + + + @color/primary + #F399C7 + #FFFFFF + @color/grey_30 + @color/grey_10 + @color/grey_0 + + + @color/primary + @color/grey_30 + @color/grey_30 + #CCCCCC + + + #191919 + @color/grey_30 + #191919 + #191919 + #191919 + #191919 + @color/grey_30 + #191919 + #000000 + #191919 + #F6E5EB + #C16F81 + #0D39DF + #0099ff + + + @color/grey_0 + #191919 + @color/grey_0 + @color/grey_30 + #77b6bb + #5077b6bb diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml new file mode 100644 index 000000000000..cc9e25255a10 --- /dev/null +++ b/app/src/main/res/values/dimens.xml @@ -0,0 +1,31 @@ + + + 4dp + 16dp + 24dp + 6dp + 18sp + 15sp + 15dp + 56dp + 86dp + 80dp + 11sp + 30dp + 55dp + 258dp + 17sp + 20dp + 160dp + 50dp + 150dp + 55dp + 48dp + 48dp + 24dp + 26dp + 20sp + 145dp + 1dp + 13sp + \ No newline at end of file diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml index 6786cf27db48..0c9758b4dc37 100644 --- a/app/src/main/res/values/setup.xml +++ b/app/src/main/res/values/setup.xml @@ -79,6 +79,9 @@ "https://play.google.com/store/apps/details?id=com.nextcloud.client" https://nextcloud.com/install + + https://www.telekom.de/impressum false diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c60ee567ec2a..0581eee238c3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -53,6 +53,7 @@ Calendar & contacts sync set up Daily backup of your calendar & contacts Daily backup of your contacts + Displays your 12 word key (passhprase) Manage folders for auto upload Help Recommend to a friend @@ -61,6 +62,7 @@ Dark Follow system Theme + End-to-end encryption was already set up on another client. Please enter your mnemonic to allow this client to sync and decrypt the files. Try %1$s on your device! I want to invite you to use %1$s on your device.\nDownload here: %2$s @@ -516,6 +518,7 @@ Grid view List view + Back up contacts Manage space Settings, database and server certificates from %1$s\'s data will be deleted permanently. \n\nDownloaded files will be kept untouched.\n\nThis process can take a while. @@ -1033,6 +1036,7 @@ Storage permissions %1$s needs file management permissions to upload files. You can choose full access to all files, or read-only access to photos and videos. %1$s works best with permissions to access storage. You can choose full access to all files, or read-only access to photos and videos. + Account Information No results found for your query Found no images or videos Error creating file from template @@ -1085,6 +1089,12 @@ Not possible without internet connection Scan page Done + Info + Data Privacy + Privacy Settings + Privacy Policy + Used OpenSource Software + Service Generating PDF… Error starting document scan PDF generation failed diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index ae3af70d4889..4b5d27e447bd 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -19,123 +19,182 @@ along with this program. If not, see . --> - - + android:key="preference_screen"> + + + + + + + - - - + android:key="storage_path" + android:layout="@layout/custom_preference_layout" + android:title="@string/prefs_storage_path" /> + + + + + - - - - - + android:id="@+id/synced_folders_configure_folders" + android:key="synced_folders_configure_folders" + android:layout="@layout/custom_preference_layout" + android:title="@string/synced_folders_configure_folders" /> + + + + + - + android:title="@string/prefs_enable_media_scan_notifications" /> + - + + android:layout="@layout/custom_preference_layout" + android:summary="@string/prefs_sycned_folders_summary" + android:title="@string/drawer_synced_folders" /> + - + android:layout="@layout/custom_preference_layout" + android:summary="@string/prefs_daily_backup_summary" + android:title="@string/backup_title" /> + android:layout="@layout/custom_preference_layout" + android:summary="@string/setup_e2e" + android:title="@string/prefs_setup_e2e" /> + android:layout="@layout/custom_preference_layout" + android:summary="@string/prefs_keys_exist_summary" + android:title="@string/prefs_keys_exist" /> + android:layout="@layout/custom_preference_layout" + android:summary="@string/prefs_mnemonic_summary" + android:title="@string/prefs_e2e_mnemonic" /> + android:layout="@layout/custom_preference_layout" + android:summary="@string/remove_e2e" + android:title="@string/prefs_remove_e2e" /> + + + + + android:id="@+id/privacy_settings" + android:key="privacy_settings" + android:layout="@layout/custom_preference_layout" + android:title="@string/privacy_settings" /> + android:id="@+id/privacy_policy" + android:key="privacy_policy" + android:layout="@layout/custom_preference_layout" + android:title="@string/privacy_policy" /> + + + + + + android:key="help" + android:layout="@layout/custom_preference_layout" + android:title="@string/prefs_help" /> - - - - - - - - - - - - - - - + android:key="imprint" + android:layout="@layout/custom_preference_layout" + android:title="@string/prefs_imprint" /> + + + + + + +