Compare commits

..

57 Commits

Author SHA1 Message Date
Arnau Mora
e2d5f8b7ac Replace Weblate engage WebView with a button (#2016)
* Replace Weblate engage WebView with a button

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Move engagement button to the top

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

---------

Signed-off-by: Arnau Mora <arnyminerz@proton.me>
2026-02-18 13:48:05 +01:00
Sunik Kupfer
f183676fc2 Add account to beforeSync validation (#2011)
Add account to SyncValidators beforeSync
2026-02-18 10:38:17 +01:00
Ricki Hirner
8838db25c5 Issue templates: add needs triage (#2008)
Update issue template labels

- Change qualified feature request label from "enhancement" to "needs-triage"
- Change qualified bug report label from "bug" to "needs-triage"
2026-02-16 17:43:09 +01:00
dependabot[bot]
515360876e Bump the app-dependencies group with 6 updates (#2007)
Bumps the app-dependencies group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| androidx.activity:activity-compose | `1.12.3` | `1.12.4` |
| androidx.compose:compose-bom | `2026.01.01` | `2026.02.00` |
| androidx.paging:paging-runtime-ktx | `3.4.0` | `3.4.1` |
| androidx.paging:paging-compose | `3.4.0` | `3.4.1` |
| com.android.application | `9.0.0` | `9.0.1` |
| com.android.library | `9.0.0` | `9.0.1` |


Updates `androidx.activity:activity-compose` from 1.12.3 to 1.12.4

Updates `androidx.compose:compose-bom` from 2026.01.01 to 2026.02.00

Updates `androidx.paging:paging-runtime-ktx` from 3.4.0 to 3.4.1

Updates `androidx.paging:paging-compose` from 3.4.0 to 3.4.1

Updates `androidx.paging:paging-compose` from 3.4.0 to 3.4.1

Updates `com.android.application` from 9.0.0 to 9.0.1

Updates `com.android.library` from 9.0.0 to 9.0.1

Updates `com.android.library` from 9.0.0 to 9.0.1

---
updated-dependencies:
- dependency-name: androidx.activity:activity-compose
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: androidx.compose:compose-bom
  dependency-version: 2026.02.00
  dependency-type: direct:production
  dependency-group: app-dependencies
- dependency-name: androidx.paging:paging-runtime-ktx
  dependency-version: 3.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: androidx.paging:paging-compose
  dependency-version: 3.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: androidx.paging:paging-compose
  dependency-version: 3.4.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.android.application
  dependency-version: 9.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.android.library
  dependency-version: 9.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.android.library
  dependency-version: 9.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 17:01:40 +01:00
Sunik Kupfer
78bf028938 Remove unused launcher colors (#2000)
Rename colors.xml to launcher_colors.xml and remove unused colors

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
2026-02-16 10:43:26 +01:00
Ricki Hirner
24de99a4fa Remove @rfc2822 as code owner (#2002)
- Delete global CODEOWNERS rule for @rfc2822
- Keep Dependabot ownership for Gradle files
2026-02-16 10:29:29 +01:00
Arnau Mora
6518ad2066 Add SyncValidator (#1987)
* Add `SyncValidator`

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Use `SyncValidator` in `Syncer`

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Adjust kdoc

Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>

---------

Signed-off-by: Arnau Mora <arnyminerz@proton.me>
Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>
2026-02-11 12:20:57 +01:00
Ricki Hirner
795616a613 Reduce HTTP User-Agent string (#1998)
Refactor HTTP user agent string

- Simplify user agent to include only app name, version, and package name
2026-02-11 11:30:48 +01:00
Ricki Hirner
2799bf33f7 [CI] Fix paths and configuration after subproject split (#1997)
* Update release workflow configuration

- Update Java version environment variable naming
- Enable submodule checkout during build
- Fix APK file path for release artifacts
- Use consistent Java version reference in workflow

* Update AVD cache key path

- Change cache key reference from `app/build.gradle.kts` to `app-ose/build.gradle.kts` for AVD cache in test workflow

* Move signing configs before build types

- Reorder signingConfigs block to appear before buildTypes
- Ensure signingConfig reference in release build type comes after signingConfigs definition

* Don't checkout submodules
2026-02-10 17:04:52 +01:00
Ricki Hirner
ff3780ee01 Split subprojects: fix ProGuard configuration (#1995)
* Fix ProGuard rules for subprojects

- Rename `proguard-rules-release.pro` to `core-proguard-rules.pro`
- Include ProGuard rules in the core library's build configuration
- Remove redundant R8 usage comments and flags from the rules file

* Add ProGuard rules for release build

- Create new ProGuard rules file for release builds
- Disable obfuscation with `-dontobfuscate`
- Enable usage reporting to `build/reports/r8-usage.txt`
- Reference keep rules from core module
2026-02-10 14:56:46 +01:00
Ricki Hirner
63422b6e0e Update release workflow configuration
- Add Gradle cache encryption key
- Disable build cache for deterministic builds
- Update build command to target OSE app bundle
2026-02-10 12:24:02 +01:00
Ricki Hirner
ba2cc5c46b Update version to 4.5.10-alpha.1
- Bump version code to 405100000
- Update version name to 4.5.10-alpha.1
2026-02-10 12:06:05 +01:00
Weblate (bot)
7e7e56e35c Translations update from Hosted Weblate (#1986)
* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/pt_BR/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/zh_Hans/

* Translated using Weblate (Estonian)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/et/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/nl/

* Added translation using Weblate (Lithuanian)

* Translated using Weblate (Lithuanian)

Currently translated at 7.6% (33 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/lt/

* Translated using Weblate (Georgian)

Currently translated at 84.6% (364 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/ka/

* Translated using Weblate (Romanian)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/ro/

* Translated using Weblate (Italian)

Currently translated at 88.1% (379 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (4 of 4 strings)

Translation: davx5/DAVx⁵ app metadata (for F-Droid)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-fastlane/it/

* Translated using Weblate (Estonian)

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/et/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/zh_Hans/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/nl/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/pt_BR/

* Translated using Weblate (German)

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/de/

* Translated using Weblate (Romanian)

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/ro/

---------

Co-authored-by: LucasMZ <git@lucasmz.dev>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>
Co-authored-by: Stephan Paternotte <stephan@paternottes.net>
Co-authored-by: Vaclovas Intas <Gateway_31@protonmail.com>
Co-authored-by: Temuri Doghonadze <temuri.doghonadze@gmail.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: Alì Mortacci <newscpq@vivaldi.net>
Co-authored-by: nautilusx <translate@disroot.org>
2026-02-10 11:59:10 +01:00
Ricki Hirner
1b8f215ffc Update intro page factory module name
- Rename `Global` interface to `IntroPageFactoryModule` for clarity
2026-02-10 11:56:43 +01:00
Ricki Hirner
e796448bad Split subprojects: fix aboutLibraries (bitfireAT/davx5#794)
Fix aboutLibraries plugin

- Add aboutLibraries plugin to root build.gradle.kts
- Apply aboutLibraries plugin in app-non-ose module
2026-02-10 11:55:16 +01:00
Ricki Hirner
bb6be3c9cc [CI] Rename main branch references (#1993)
Rename main branch references

- Update branch name from `main-ose` to `main` in test-dev workflow
- Remove deprecated dependency-submission workflow
- Add JAVA_VERSION environment variable in release workflow
- Replace hardcoded Java version with JAVA_VERSION variable in test-dev and release workflows
- Update comment in release workflow for cache cleanup clarity
2026-02-10 11:42:22 +01:00
Ricki Hirner
a436e8181a [CI] Fix tests after splitting into subprojects (#1991)
* Update dependency submission workflow

- Enable submodule checkout in GitHub Actions workflow
- Ensures subprojects are properly included during dependency analysis

* Update test workflow for split projects

- Set Java version as variable
- Replace `app` with `app-ose` in Gradle tasks
- Remove Android environment caching
- Update configuration cache population tasks
- Add unit and instrumented tests for `app-ose`
- Simplify cache handling by removing redundant steps

* Updated tests to only run for core module (app-ose has no unit tests)

* Remove CodeQL job
2026-02-10 11:17:15 +01:00
Ricki Hirner
ea81b929ca Fix tests with latest Kotlin 2026-02-09 23:16:55 +01:00
Ricki Hirner
55202dff87 Fix tests after subproject split
- Replace TestTasksAppWatcherModule with TestStartupPluginsModule to provide empty set of startup plugins
2026-02-09 22:49:08 +01:00
dependabot[bot]
fb2c8cdd68 Bump the app-dependencies group with 7 updates (#1985)
Bumps the app-dependencies group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [com.google.dagger:hilt-android](https://github.com/google/dagger) | `2.59` | `2.59.1` |
| [com.google.dagger:hilt-android-compiler](https://github.com/google/dagger) | `2.59` | `2.59.1` |
| [com.google.dagger:hilt-android-testing](https://github.com/google/dagger) | `2.59` | `2.59.1` |
| [com.google.dagger.hilt.android](https://github.com/google/dagger) | `2.59` | `2.59.1` |
| [org.jetbrains.kotlin:kotlin-stdlib](https://github.com/JetBrains/kotlin) | `2.2.21` | `2.3.10` |
| [org.jetbrains.kotlin.plugin.compose](https://github.com/JetBrains/kotlin) | `2.2.21` | `2.3.10` |
| [org.jetbrains.kotlin.plugin.serialization](https://github.com/JetBrains/kotlin) | `2.2.21` | `2.3.10` |


Updates `com.google.dagger:hilt-android` from 2.59 to 2.59.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.59...dagger-2.59.1)

Updates `com.google.dagger:hilt-android-compiler` from 2.59 to 2.59.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.59...dagger-2.59.1)

Updates `com.google.dagger:hilt-android-testing` from 2.59 to 2.59.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.59...dagger-2.59.1)

Updates `com.google.dagger.hilt.android` from 2.59 to 2.59.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.59...dagger-2.59.1)

Updates `com.google.dagger:hilt-android-compiler` from 2.59 to 2.59.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.59...dagger-2.59.1)

Updates `com.google.dagger:hilt-android-testing` from 2.59 to 2.59.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.59...dagger-2.59.1)

Updates `org.jetbrains.kotlin:kotlin-stdlib` from 2.2.21 to 2.3.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.21...v2.3.10)

Updates `org.jetbrains.kotlin.plugin.compose` from 2.2.21 to 2.3.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.21...v2.3.10)

Updates `org.jetbrains.kotlin.plugin.serialization` from 2.2.21 to 2.3.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.21...v2.3.10)

Updates `org.jetbrains.kotlin.plugin.compose` from 2.2.21 to 2.3.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.21...v2.3.10)

Updates `com.google.dagger.hilt.android` from 2.59 to 2.59.1
- [Release notes](https://github.com/google/dagger/releases)
- [Changelog](https://github.com/google/dagger/blob/master/CHANGELOG.md)
- [Commits](https://github.com/google/dagger/compare/dagger-2.59...dagger-2.59.1)

Updates `org.jetbrains.kotlin.plugin.serialization` from 2.2.21 to 2.3.10
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v2.2.21...v2.3.10)

---
updated-dependencies:
- dependency-name: com.google.dagger:hilt-android
  dependency-version: 2.59.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.google.dagger:hilt-android-compiler
  dependency-version: 2.59.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.google.dagger:hilt-android-testing
  dependency-version: 2.59.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.google.dagger.hilt.android
  dependency-version: 2.59.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.google.dagger:hilt-android-compiler
  dependency-version: 2.59.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.google.dagger:hilt-android-testing
  dependency-version: 2.59.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: org.jetbrains.kotlin:kotlin-stdlib
  dependency-version: 2.3.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: org.jetbrains.kotlin.plugin.compose
  dependency-version: 2.3.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: org.jetbrains.kotlin.plugin.serialization
  dependency-version: 2.3.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: org.jetbrains.kotlin.plugin.compose
  dependency-version: 2.3.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: com.google.dagger.hilt.android
  dependency-version: 2.59.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: org.jetbrains.kotlin.plugin.serialization
  dependency-version: 2.3.10
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-09 21:02:58 +01:00
Ricki Hirner
a9b24e5c45 Apply Gradle plugins once in root build.gradle.kts (bitfireAT/davx5#789) 2026-02-09 18:12:46 +01:00
Ricki Hirner
a55ce927f7 Better DI modules (#1982)
* Rename "app" subproject to core

* Split core and app-ose

* Update test workflows

* Update test configuration

- Add managed device for testing
- Set device to "Pixel 3" with API level 34
- Use AOSP system image source

* Add OpenID AppAuth library

* Fix core instrumentation tests

* Move WorkManagerInitializer from core to app-ose AndroidManifest

* Don't run app-ose tests yet because there are none

* Refactor App Initialization

- Introduce `CoreApp` for common initialization logic
- Refactor `App` to extend `CoreApp` and handle WorkManager configuration

* Update package references and permissions

- Update references from `com.davx5.ose.App` to `at.bitfire.davdroid.CoreApp`
- Enable archive naming in `app-ose/build.gradle.kts`
- Remove redundant permission declarations in `core/src/main/AndroidManifest.xml`

* Remove build.gradle.kts and update settings.gradle.kts

- Remove `build.gradle.kts` file
- Update `settings.gradle.kts` to use `gradlePluginPortal` for plugins
- Set `repositoriesMode` to `PREFER_SETTINGS`
- Add comments for clarity in `settings.gradle.kts`

* Update AndroidManifest to set install location to internal only (again)

* Refactor DI modules and qualifiers

- Move `ColorSchemeScopes` to `ColorSchemeQualifiers`
- Rename `CustomCertManagerModule` to `Cert4AndroidModule`
- Move `CoroutineScopes` to `CoroutineQualifiers`
- Add `ApplicationScope` qualifier to `CoroutineQualifiers`
- Remove redundant DI module declarations
- Add new `CoreSettingsProvidersModule`
- Add new `StartupPluginsModule`
- Add new `UncaughtExceptionHandlerModule`
- Add new `AuthorizationServiceModule`
- Add new `AppLicenseInfoProviderModule`
- Add new `IntroPageFactoryModule`
- Add new `LoginTypesProviderModule`
- Add new `AccountsDrawerHandlerModule`
2026-02-09 12:22:16 +01:00
Ricki Hirner
7861cffa2e Split app into core and app-ose subprojects (#1975)
* Rename "app" subproject to core

* Split core and app-ose

* Update test workflows

* Update test configuration

- Add managed device for testing
- Set device to "Pixel 3" with API level 34
- Use AOSP system image source

* Add OpenID AppAuth library

* Fix core instrumentation tests

* Move WorkManagerInitializer from core to app-ose AndroidManifest

* Don't run app-ose tests yet because there are none

* Refactor App Initialization

- Introduce `CoreApp` for common initialization logic
- Refactor `App` to extend `CoreApp` and handle WorkManager configuration

* Update package references and permissions

- Update references from `com.davx5.ose.App` to `at.bitfire.davdroid.CoreApp`
- Enable archive naming in `app-ose/build.gradle.kts`
- Remove redundant permission declarations in `core/src/main/AndroidManifest.xml`

* Remove build.gradle.kts and update settings.gradle.kts

- Remove `build.gradle.kts` file
- Update `settings.gradle.kts` to use `gradlePluginPortal` for plugins
- Set `repositoriesMode` to `PREFER_SETTINGS`
- Add comments for clarity in `settings.gradle.kts`

* Update AndroidManifest to set install location to internal only (again)

* Update CoreApp to be abstract

- Change `CoreApp` from open to abstract class.
2026-02-09 11:54:54 +01:00
Ricki Hirner
eab054d1c3 Move OSE code to separate package (#1974)
- Move DebugInfoCrashHandler.kt to com.davx5.ose
- Move StandardLoginTypePage.kt to com.davx5.ose.ui.setup
- Move StandardLoginTypesProvider.kt to com.davx5.ose.ui.setup
- Move CustomCertManagerModule.kt to com.davx5.ose.di
- Move OseIntroPageFactory.kt to com.davx5.ose.ui.intro
- Move OseColorSchemesModule.kt to com.davx5.ose.di
- Move OseFlavorModule.kt to com.davx5.ose.di
- Move OpenSourceLicenseInfoProvider.kt to com.davx5.ose.ui.about
- Move OseTheme.kt to com.davx5.ose.ui
2026-02-05 17:21:57 +01:00
Ricki Hirner
5e84648fb4 Replace BuildConfig.allowCustomCerts by DI (#1971)
* Update IntroScreen colors

- Replace M3ColorScheme with MaterialTheme.colorScheme
- Update background and icon colors to use MaterialTheme

* Update color scheme references

- Replace `M3ColorScheme.primaryLight` with `MaterialTheme.colorScheme.primary` in `WelcomePage.kt` and `AccountsDrawerHandler.kt`.

* Update AppTheme to accept custom color schemes

- Add `lightColorScheme` and `darkColorScheme` parameters
- Replace hardcoded color schemes with the new parameters

* Add color scheme dependency injection

- Add `LightColorScheme` and `DarkColorScheme` qualifiers
- Create `OseColorSchemes` module for providing color schemes
- Update `AppTheme` to use injected color schemes

* Update glance material dependency to material3

- Update `androidx.glance.material` to `androidx.glance.material3`
- Adjust imports and usage in `IconSyncButtonWidget.kt` and `LabeledSyncButtonWidget.kt` to use `GlanceTheme` and `ColorProviders` for color schemes
- Replace deprecated `ColorProvider` with `GlanceTheme.colors` for primary and onPrimary colors

* Refactor widget receivers and widgets to use dependency injection more properly

- Update `LabeledSyncButtonWidgetReceiver` and `IconSyncButtonWidgetReceiver` to use Hilt for dependency injection.
- Inject `SyncWidgetModel`, `LightColorScheme`, and `DarkColorScheme` into both widget receivers.
- Remove the use of `EntryPoint` and `EntryPointAccessors` from `LabeledSyncButtonWidget` and `IconSyncButtonWidget`.
- Pass injected dependencies directly to the widget constructors.

* Rename ThemeColors to OseTheme

- Update imports and references to use OseTheme
- Rename object M3ColorScheme to OseTheme

* Move AppTheme to ui.composable package because it's a reusable Composable

* Update AboutApp to use dynamic version info instead of BuildConfig

- Pass versionName and versionCode from AboutModel to AboutApp
- Remove dependency on BuildConfig in AboutApp
- Update AboutApp_Preview with sample version info

* Update URI statistics parameters

- Update `withStatParams` to include package name and version
- Replace `BuildConfig.APPLICATION_ID` with `context.packageName`
- Add context parameter to `withStatParams` in various activities

* Don't depend on BuildConfig for application name and version

- Introduce `ProductIds` for managing product IDs and User-Agent
- Update various classes to use `ProductIds` for product ID generation
- Move `TextTable` class from `at.bitfire.davdroid` to `at.bitfire.davdroid.util`

* Refactor OAuth classes for dependency injection

- Convert `OAuthFastmail` and `OAuthGoogle` to injectable classes
- Update `FastmailLoginModel` and `GoogleLoginModel` to use injected instances
- Move `redirectUri` initialization to `OAuthIntegration` constructor

* Adapt DI

- Move CustomCertManagerModule to ose configuration
- Move coroutine scopes to scope package

* minor changes

* Remove custom certificate build config

- Remove `allowCustomCerts` build config field
- Replace `@Singleton` with `@Reusable` in CustomCertManagerModule

* Update imports and LogcatHandler initialization

- Update imports to use scoped dispatchers
- Replace BuildConfig.APPLICATION_ID with javaClass.name in LogcatHandler initialization
2026-02-05 13:59:31 +01:00
Ricki Hirner
490abcb88a Reduce BuildConfig dependencies (#1969)
* Update IntroScreen colors

- Replace M3ColorScheme with MaterialTheme.colorScheme
- Update background and icon colors to use MaterialTheme

* Update color scheme references

- Replace `M3ColorScheme.primaryLight` with `MaterialTheme.colorScheme.primary` in `WelcomePage.kt` and `AccountsDrawerHandler.kt`.

* Update AppTheme to accept custom color schemes

- Add `lightColorScheme` and `darkColorScheme` parameters
- Replace hardcoded color schemes with the new parameters

* Add color scheme dependency injection

- Add `LightColorScheme` and `DarkColorScheme` qualifiers
- Create `OseColorSchemes` module for providing color schemes
- Update `AppTheme` to use injected color schemes

* Update glance material dependency to material3

- Update `androidx.glance.material` to `androidx.glance.material3`
- Adjust imports and usage in `IconSyncButtonWidget.kt` and `LabeledSyncButtonWidget.kt` to use `GlanceTheme` and `ColorProviders` for color schemes
- Replace deprecated `ColorProvider` with `GlanceTheme.colors` for primary and onPrimary colors

* Refactor widget receivers and widgets to use dependency injection more properly

- Update `LabeledSyncButtonWidgetReceiver` and `IconSyncButtonWidgetReceiver` to use Hilt for dependency injection.
- Inject `SyncWidgetModel`, `LightColorScheme`, and `DarkColorScheme` into both widget receivers.
- Remove the use of `EntryPoint` and `EntryPointAccessors` from `LabeledSyncButtonWidget` and `IconSyncButtonWidget`.
- Pass injected dependencies directly to the widget constructors.

* Rename ThemeColors to OseTheme

- Update imports and references to use OseTheme
- Rename object M3ColorScheme to OseTheme

* Move AppTheme to ui.composable package because it's a reusable Composable

* Update AboutApp to use dynamic version info instead of BuildConfig

- Pass versionName and versionCode from AboutModel to AboutApp
- Remove dependency on BuildConfig in AboutApp
- Update AboutApp_Preview with sample version info

* Update URI statistics parameters

- Update `withStatParams` to include package name and version
- Replace `BuildConfig.APPLICATION_ID` with `context.packageName`
- Add context parameter to `withStatParams` in various activities

* Don't depend on BuildConfig for application name and version

- Introduce `ProductIds` for managing product IDs and User-Agent
- Update various classes to use `ProductIds` for product ID generation
- Move `TextTable` class from `at.bitfire.davdroid` to `at.bitfire.davdroid.util`

* Refactor OAuth classes for dependency injection

- Convert `OAuthFastmail` and `OAuthGoogle` to injectable classes
- Update `FastmailLoginModel` and `GoogleLoginModel` to use injected instances
- Move `redirectUri` initialization to `OAuthIntegration` constructor
2026-02-05 12:20:21 +01:00
Ricki Hirner
cca12e79d8 [UI] Properly provide color schemes over DI (#1966)
* Update IntroScreen colors

- Replace M3ColorScheme with MaterialTheme.colorScheme
- Update background and icon colors to use MaterialTheme

* Update color scheme references

- Replace `M3ColorScheme.primaryLight` with `MaterialTheme.colorScheme.primary` in `WelcomePage.kt` and `AccountsDrawerHandler.kt`.

* Update AppTheme to accept custom color schemes

- Add `lightColorScheme` and `darkColorScheme` parameters
- Replace hardcoded color schemes with the new parameters

* Add color scheme dependency injection

- Add `LightColorScheme` and `DarkColorScheme` qualifiers
- Create `OseColorSchemes` module for providing color schemes
- Update `AppTheme` to use injected color schemes

* Update glance material dependency to material3

- Update `androidx.glance.material` to `androidx.glance.material3`
- Adjust imports and usage in `IconSyncButtonWidget.kt` and `LabeledSyncButtonWidget.kt` to use `GlanceTheme` and `ColorProviders` for color schemes
- Replace deprecated `ColorProvider` with `GlanceTheme.colors` for primary and onPrimary colors

* Refactor widget receivers and widgets to use dependency injection more properly

- Update `LabeledSyncButtonWidgetReceiver` and `IconSyncButtonWidgetReceiver` to use Hilt for dependency injection.
- Inject `SyncWidgetModel`, `LightColorScheme`, and `DarkColorScheme` into both widget receivers.
- Remove the use of `EntryPoint` and `EntryPointAccessors` from `LabeledSyncButtonWidget` and `IconSyncButtonWidget`.
- Pass injected dependencies directly to the widget constructors.

* Rename ThemeColors to OseTheme

- Update imports and references to use OseTheme
- Rename object M3ColorScheme to OseTheme

* Move AppTheme to ui.composable package because it's a reusable Composable

* Always use Light Color Scheme for certain intro UI

- Inject `lightColorScheme` in `IntroActivity`
- Pass `lightColorScheme` to `IntroScreen`
- Use `lightColorScheme` for background and color in `IntroScreen` and `WelcomePage`

* Minor syntax
2026-02-05 11:43:55 +01:00
Ricki Hirner
915cf73027 Update version to 4.5.9 2026-02-04 10:58:57 +01:00
Ricki Hirner
53773eaf83 Go back to 4.5.9-rc.2 (4.5.9 with version code 405090003 was never released) 2026-02-03 16:00:55 +01:00
Ricki Hirner
9cd685982d Update synctools to correctly process tel: URIs in vCards (#1963) 2026-02-03 15:59:46 +01:00
Sunik Kupfer
d4902e84ce [synctools] Tasks rewrite: Use reader/writer (#1959)
* Update synctools; Use writer/reader

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Update synctools

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

---------

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
2026-02-03 15:22:15 +01:00
dependabot[bot]
ec485fcfa5 Bump the app-dependencies group with 8 updates (#1961)
Bumps the app-dependencies group with 8 updates:

| Package | From | To |
| --- | --- | --- |
| gradle-wrapper | `9.3.0` | `9.3.1` |
| androidx.activity:activity-compose | `1.12.2` | `1.12.3` |
| androidx.compose:compose-bom | `2026.01.00` | `2026.01.01` |
| androidx.paging:paging-runtime-ktx | `3.3.6` | `3.4.0` |
| androidx.paging:paging-compose | `3.3.6` | `3.4.0` |
| androidx.work:work-runtime-ktx | `2.11.0` | `2.11.1` |
| androidx.work:work-testing | `2.11.0` | `2.11.1` |
| [com.google.devtools.ksp](https://github.com/google/ksp) | `2.3.4` | `2.3.5` |


Updates `gradle-wrapper` from 9.3.0 to 9.3.1

Updates `androidx.activity:activity-compose` from 1.12.2 to 1.12.3

Updates `androidx.compose:compose-bom` from 2026.01.00 to 2026.01.01

Updates `androidx.paging:paging-runtime-ktx` from 3.3.6 to 3.4.0

Updates `androidx.paging:paging-compose` from 3.3.6 to 3.4.0

Updates `androidx.paging:paging-compose` from 3.3.6 to 3.4.0

Updates `androidx.work:work-runtime-ktx` from 2.11.0 to 2.11.1

Updates `androidx.work:work-testing` from 2.11.0 to 2.11.1

Updates `androidx.work:work-testing` from 2.11.0 to 2.11.1

Updates `com.google.devtools.ksp` from 2.3.4 to 2.3.5
- [Release notes](https://github.com/google/ksp/releases)
- [Commits](https://github.com/google/ksp/compare/2.3.4...2.3.5)

---
updated-dependencies:
- dependency-name: gradle-wrapper
  dependency-version: 9.3.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: androidx.activity:activity-compose
  dependency-version: 1.12.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: androidx.compose:compose-bom
  dependency-version: 2026.01.01
  dependency-type: direct:production
  dependency-group: app-dependencies
- dependency-name: androidx.paging:paging-runtime-ktx
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: androidx.paging:paging-compose
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: androidx.paging:paging-compose
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: androidx.work:work-runtime-ktx
  dependency-version: 2.11.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: androidx.work:work-testing
  dependency-version: 2.11.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: androidx.work:work-testing
  dependency-version: 2.11.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: com.google.devtools.ksp
  dependency-version: 2.3.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-03 14:57:10 +01:00
Ricki Hirner
5709aaa2e5 Bump version to 4.5.9 2026-02-03 12:12:05 +01:00
Ricki Hirner
a19c397ef6 Sync files with davx5 repo (#1958)
* Sync changes with davx5 repo

* Remove unnecessary test launcher icons
2026-02-02 12:30:04 +01:00
Ricki Hirner
dad4298dd5 Bump version to 4.5.9-rc.1 2026-02-02 10:12:52 +01:00
Weblate (bot)
8e78e6e3ac Translations update from Hosted Weblate (#1955)
* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/pt_BR/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/zh_Hans/

* Translated using Weblate (Estonian)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/et/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/nl/

* Added translation using Weblate (Lithuanian)

* Translated using Weblate (Lithuanian)

Currently translated at 7.6% (33 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/lt/

* Translated using Weblate (Georgian)

Currently translated at 84.6% (364 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/ka/

* Translated using Weblate (Romanian)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/ro/

* Translated using Weblate (Italian)

Currently translated at 88.1% (379 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (4 of 4 strings)

Translation: davx5/DAVx⁵ app metadata (for F-Droid)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-fastlane/it/

* Translated using Weblate (Estonian)

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/et/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/zh_Hans/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/nl/

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (437 of 437 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/pt_BR/

---------

Co-authored-by: LucasMZ <git@lucasmz.dev>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>
Co-authored-by: Stephan Paternotte <stephan@paternottes.net>
Co-authored-by: Vaclovas Intas <Gateway_31@protonmail.com>
Co-authored-by: Temuri Doghonadze <temuri.doghonadze@gmail.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: Alì Mortacci <newscpq@vivaldi.net>
2026-02-02 10:12:10 +01:00
Ricki Hirner
fc878d519f Update synctools to process phone numbers with VALUE=URI (#1956) 2026-02-02 10:11:40 +01:00
Ricki Hirner
45d5d809fc Bump version to 4.5.9-alpha.2 2026-01-29 14:17:59 +01:00
Ricki Hirner
ef1d90f740 Cache SSLSocketFactories to allow okhttp HTTPS connection reuse (#1942)
* Reuse CustomCertManager

- Update bitfire-cert4android to 75cc6913fd
- Refactor HttpClientBuilder to use Optional for customTrustManager and customHostnameVerifier
- Add CustomCertManagerModule for dependency injection

* Implement connection security manager for HTTP client

- Introduce `ConnectionSecurityManager` and `ConnectionSecurityContext` classes
- Refactor `HttpClientBuilder` to use the new security manager for SSL context setup

* [WIP] Cache SSLContext by certificate alias

- Add context cache using Guava CacheBuilder
- Cache SSLContext in getContext method

* Update comments in HttpClientBuilder.kt for clarity

* Update ConnectionSecurityManager to use SSLSocketFactory caching

* Refactor socket factory caching logic for better clarity

* Add tests

* Refactor socket factory cache to store only SSLSocketFactory

* Minor changes
- Change socketFactoryCache to use LinkedHashMap instead of ConcurrentHashMap
- Update cache key handling to use String? instead of Optional<String>

* Add tests for caching

* Add logging

* Indenting

* Minor simplification

* Fix tests
2026-01-29 14:09:09 +01:00
Arnau Mora
5efcbfc5a3 Set Calendars.IS_PRIMARY to 0 by default (#1945)
* Start setting `IS_PRIMARY`

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Set `IS_PRIMARY` to `0`

* Remove unused injection

Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>

* Improve explanation

Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>

---------

Signed-off-by: Arnau Mora <arnyminerz@proton.me>
Signed-off-by: Arnau Mora Gras <arnyminerz@proton.me>
2026-01-29 12:30:23 +01:00
Sunik Kupfer
4f3ff69b43 Update synctools (#1952)
Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
2026-01-29 12:18:29 +01:00
Ricki Hirner
afe00c275e Update CODEOWNERS (#1949) 2026-01-28 13:18:28 +01:00
Sunik Kupfer
03c4aa9938 Ignore AccountSettingsMigration21Test.testCancelsSyncAndClearsPendingState with flaky behaviour in CI (#1948)
Ignore test with flaky behaviour in CI

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
2026-01-28 11:25:00 +01:00
dependabot[bot]
63a5359c06 Bump the app-dependencies group with 7 updates (#1944)
Bumps the app-dependencies group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [io.ktor:ktor-client-content-negotiation](https://github.com/ktorio/ktor) | `3.3.3` | `3.4.0` |
| [io.ktor:ktor-client-core](https://github.com/ktorio/ktor) | `3.3.3` | `3.4.0` |
| [io.ktor:ktor-client-okhttp](https://github.com/ktorio/ktor) | `3.3.3` | `3.4.0` |
| [io.ktor:ktor-serialization-kotlinx-json](https://github.com/ktorio/ktor) | `3.3.3` | `3.4.0` |
| [io.mockk:mockk](https://github.com/mockk/mockk) | `1.14.7` | `1.14.9` |
| [io.mockk:mockk-android](https://github.com/mockk/mockk) | `1.14.7` | `1.14.9` |
| [org.robolectric:robolectric](https://github.com/robolectric/robolectric) | `4.16` | `4.16.1` |


Updates `io.ktor:ktor-client-content-negotiation` from 3.3.3 to 3.4.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/3.3.3...3.4.0)

Updates `io.ktor:ktor-client-core` from 3.3.3 to 3.4.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/3.3.3...3.4.0)

Updates `io.ktor:ktor-client-okhttp` from 3.3.3 to 3.4.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/3.3.3...3.4.0)

Updates `io.ktor:ktor-serialization-kotlinx-json` from 3.3.3 to 3.4.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/3.3.3...3.4.0)

Updates `io.ktor:ktor-client-core` from 3.3.3 to 3.4.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/3.3.3...3.4.0)

Updates `io.ktor:ktor-client-okhttp` from 3.3.3 to 3.4.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/3.3.3...3.4.0)

Updates `io.ktor:ktor-serialization-kotlinx-json` from 3.3.3 to 3.4.0
- [Release notes](https://github.com/ktorio/ktor/releases)
- [Changelog](https://github.com/ktorio/ktor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ktorio/ktor/compare/3.3.3...3.4.0)

Updates `io.mockk:mockk` from 1.14.7 to 1.14.9
- [Release notes](https://github.com/mockk/mockk/releases)
- [Commits](https://github.com/mockk/mockk/compare/1.14.7...1.14.9)

Updates `io.mockk:mockk-android` from 1.14.7 to 1.14.9
- [Release notes](https://github.com/mockk/mockk/releases)
- [Commits](https://github.com/mockk/mockk/compare/1.14.7...1.14.9)

Updates `io.mockk:mockk-android` from 1.14.7 to 1.14.9
- [Release notes](https://github.com/mockk/mockk/releases)
- [Commits](https://github.com/mockk/mockk/compare/1.14.7...1.14.9)

Updates `org.robolectric:robolectric` from 4.16 to 4.16.1
- [Release notes](https://github.com/robolectric/robolectric/releases)
- [Commits](https://github.com/robolectric/robolectric/compare/robolectric-4.16...robolectric-4.16.1)

---
updated-dependencies:
- dependency-name: io.ktor:ktor-client-content-negotiation
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: io.ktor:ktor-client-core
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: io.ktor:ktor-client-okhttp
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: io.ktor:ktor-serialization-kotlinx-json
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: io.ktor:ktor-client-core
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: io.ktor:ktor-client-okhttp
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: io.ktor:ktor-serialization-kotlinx-json
  dependency-version: 3.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: app-dependencies
- dependency-name: io.mockk:mockk
  dependency-version: 1.14.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: io.mockk:mockk-android
  dependency-version: 1.14.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: io.mockk:mockk-android
  dependency-version: 1.14.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
- dependency-name: org.robolectric:robolectric
  dependency-version: 4.16.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-26 17:26:59 +01:00
Weblate (bot)
89a7cd2885 Translations update from Hosted Weblate (#1943)
* Translated using Weblate (Portuguese (Brazil))

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/pt_BR/

* Translated using Weblate (Chinese (Simplified Han script))

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/zh_Hans/

* Translated using Weblate (Estonian)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/et/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/nl/

* Added translation using Weblate (Lithuanian)

* Translated using Weblate (Lithuanian)

Currently translated at 7.6% (33 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/lt/

* Translated using Weblate (Georgian)

Currently translated at 84.6% (364 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/ka/

* Translated using Weblate (Romanian)

Currently translated at 100.0% (430 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/ro/

* Translated using Weblate (Italian)

Currently translated at 88.1% (379 of 430 strings)

Translation: davx5/DAVx⁵ app strings (main)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-strings/it/

* Translated using Weblate (Italian)

Currently translated at 100.0% (4 of 4 strings)

Translation: davx5/DAVx⁵ app metadata (for F-Droid)
Translate-URL: https://hosted.weblate.org/projects/davx5/davx5-ose-fastlane/it/

---------

Co-authored-by: LucasMZ <git@lucasmz.dev>
Co-authored-by: 大王叫我来巡山 <hamburger2048@users.noreply.hosted.weblate.org>
Co-authored-by: Priit Jõerüüt <jrthwlate@users.noreply.hosted.weblate.org>
Co-authored-by: Stephan Paternotte <stephan@paternottes.net>
Co-authored-by: Vaclovas Intas <Gateway_31@protonmail.com>
Co-authored-by: Temuri Doghonadze <temuri.doghonadze@gmail.com>
Co-authored-by: Igor Sorocean <sorocean.igor@gmail.com>
Co-authored-by: Alì Mortacci <newscpq@vivaldi.net>
2026-01-25 18:14:56 +01:00
Ricki Hirner
db25570581 Bump version to 4.5.9-alpha.1 2026-01-25 17:52:15 +01:00
Arnau Mora
3de34e53d0 Migrate translation contributors credits to Weblate (#1918)
* Update loading method for Weblate

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Add fetch script

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Add test function

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Add credits from Transifex

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Add workflow for updating Weblate credits

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Improve styling

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Add line break at the end

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Filter Ricki in translation contributions

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Display Transifex translations

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Modify PRs, not the base branch

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Fix paddings

Signed-off-by: Arnau Mora <arnyminerz@proton.me>

* Rename weblateTranslations flow and loadWeblateTranslations function

* Rename variables and functions from `translations` to `translators`

* - Move AboutActivity.Model class to AboutModel

* Rename translators files

* Minor renaming

* Refactor sorting logic into `sortTranslators` function

* Rename script to fetch Weblate translators

* - Remove `AboutActivityTest` class
- Move `loadTransifexTranslators` function to `AboutModel`
- Update `loadWeblateTranslators` function in `AboutModel`

* Update Weblate workflow

* - Combine Weblate and Transifex translators into a single list
- Update AboutActivity to use the combined list
- Add tests for the new functionality

* Merge Transifex and Weblate translators by username, don't show language, add Engage widget

* Extract TranslationsTab

* AboutModel: update tests

* Add thanks message for translation contributors

* Move translation credits to Weblate

- Update `OpenSourceLicenseInfoProvider` path
- Add new strings for translations credits
- Update `TranslationsTab` with new strings

* Add Accept-Language, update Context

* Update Weblate Translators Workflow

- Allow workflow to run on specific branch for testing
- Remove unnecessary fetch-depth comment

* Update Weblate Translators Workflow (2)

* Remove workflow

---------

Signed-off-by: Arnau Mora <arnyminerz@proton.me>
Co-authored-by: Ricki Hirner <hirner@bitfire.at>
2026-01-25 17:51:34 +01:00
Ricki Hirner
af084fb5d0 Add "Backups reminder" intro screen (#1937)
* Add BackupsPage to intro UI

* Add BackupsPage UI

- Implement BackupsPage composable with UI elements
- Add strings for backups reminder and acceptance

* Add to "Reset hints"

* Add another paragraph

* Update backup screen hints

- Update backups reminder text
- Remove redundant versioning note
- Update acceptance message
2026-01-25 17:48:09 +01:00
Ricki Hirner
47685e6693 [WebDAV] Rewrite COPY/MOVE (including rename) to Ktor (#1940)
* [WebDAV] Refactor RenameDocumentOperation to Ktor

- Update imports to use Ktor-based classes
- Refactor `RenameDocumentOperation` to use Ktor HTTP client
- Add support for both HttpException types in `throwForDocumentProvider`

* Rewrite CopyDocumentOperation.kt to Ktor

* Refactor URLBuilder usage

- Update URLBuilder usage in RenameDocumentOperation.kt
- Update URLBuilder usage in CopyDocumentOperation.kt
- Update URLBuilder usage in MoveDocumentOperation.kt

* - Pass `ioDispatcher` to `runBlocking` in WebDAV operations
- Refactor timeout configuration in HttpClientBuilder for reusability

* Add logging to DocumentProviderUtils

- Introduce a logger instance
- Log URI when notifying folder changes
2026-01-24 19:28:50 +01:00
Ricki Hirner
2c7b36ecd5 Use Ktor for Push registration (#1930)
* Replace OkHttp with Ktor for push notifications

* Use Ktor HttpHeaders for Location and Expires
2026-01-23 10:27:16 +01:00
Ricki Hirner
cf80b11808 [WebDAV] Rewrite OpenDocumentThumbnailOperation to Ktor (#1931)
* Add Ktor HTTP client support

- Introduce `buildKtor` method in `DavHttpClientBuilder` for creating Ktor HTTP clients.
- Update `OpenDocumentThumbnailOperation` to use Ktor for downloading and creating thumbnails.

* Refactor HttpClientBuilder creation

- Extract common logic into `createBuilder` method
- Update `build` and `buildKtor` methods to use `createBuilder`

* Refactor OpenDocumentThumbnailOperation

- Remove unnecessary `withContext` call
- Use `HttpHeaders.Accept` and `ContentType.Image.Any` for HTTP header
- Simplify the function structure

* Refactor thumbnail generation

- Remove redundant `accessScope`
- Simplify and encapsulate thumbnail creation logic
- Ensure proper cancellation handling

* Update OpenDocumentThumbnailOperation logging

- Enhance cancellation log message with document ID
- Improve URL conversion warning message

* Update WebDAV operations and document handling

- Add `@MustBeClosed` annotation to `buildKtor` method in `DavHttpClientBuilder`
- Remove unnecessary imports and update URL conversion in `OpenDocumentThumbnailOperation`
- Add `toKtorUrl` method in `WebDavDocument` for URL conversion

* Use streaming bitmap decoding

* Add comments to OpenDocumentThumbnailOperation for future improvements

---------

Co-authored-by: Arnau Mora <arnyminerz@proton.me>
2026-01-22 17:05:32 +01:00
Sunik Kupfer
18649f711a DmfsTaskList refactoring (#1934)
* DmfsTaskList refactoring

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

* Update synctools

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>

---------

Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
2026-01-21 13:17:34 +01:00
Sunik Kupfer
377a159e75 Ignore test with flaky behaviour in CI (#1936)
Signed-off-by: Sunik Kupfer <kupfer@bitfire.at>
2026-01-21 13:17:23 +01:00
Ricki Hirner
393d22f720 AGP 9.0: update Hilt, remove Kotlin Android plugin (#1935)
- Remove `android.builtInKotlin` from `gradle.properties`
- Update Hilt version to 2.59
- Remove Kotlin Android plugin from `libs.versions.toml` and build scripts
2026-01-21 11:28:40 +01:00
dependabot[bot]
5b12ecf6b6 Bump the app-dependencies group across 1 directory with 2 updates (#1933)
Bumps the app-dependencies group with 2 updates in the / directory: androidx.compose:compose-bom and [dnsjava:dnsjava](https://github.com/dnsjava/dnsjava).


Updates `androidx.compose:compose-bom` from 2025.12.01 to 2026.01.00

Updates `dnsjava:dnsjava` from 3.6.3 to 3.6.4
- [Release notes](https://github.com/dnsjava/dnsjava/releases)
- [Changelog](https://github.com/dnsjava/dnsjava/blob/master/Changelog)
- [Commits](https://github.com/dnsjava/dnsjava/compare/v3.6.3...v3.6.4)

---
updated-dependencies:
- dependency-name: androidx.compose:compose-bom
  dependency-version: 2026.01.00
  dependency-type: direct:production
  dependency-group: app-dependencies
- dependency-name: dnsjava:dnsjava
  dependency-version: 3.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: app-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-20 16:34:51 +01:00
Ricki Hirner
f8f6134640 Update AGP to 9.0.0 (#1929)
* Update gradle wrapper

* Update AGP to 9.0.0 (legacy mode) and synctools (which now also uses AGP 9.0.0)
2026-01-20 12:45:58 +01:00
Ricki Hirner
0f7908da23 Remove Transifex config/scripts (#1924) 2026-01-19 10:59:34 +01:00
565 changed files with 4131 additions and 2791 deletions

5
.github/CODEOWNERS vendored
View File

@@ -1,4 +1,5 @@
# See https://docs.github.com/de/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners
# For combination with "Require review from code owners" for main-ose branch.
# For combination with "Require review from code owners" for main-ose branch:
* @bitfireAT/app-dev
# Dependabot
gradle/** @bitfireAT/app-dev

View File

@@ -1,7 +1,7 @@
name: Qualified Bug Report
description: "For qualified bug reports. (Use Discussions if unsure.)"
type: bug
labels: ["bug"]
labels: ["needs-triage"]
body:
- type: checkboxes
attributes:

View File

@@ -1,7 +1,7 @@
name: Qualified Feature Request
description: "For qualified feature requests. (Use Discussions if unsure.)"
type: feature
labels: ["enhancement"]
labels: ["needs-triage"]
body:
- type: checkboxes
attributes:

View File

@@ -1,50 +0,0 @@
name: "CodeQL"
on:
push:
branches: [ main-ose ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ main-ose ]
schedule:
- cron: '22 10 * * 1'
concurrency:
group: codeql-${{ github.ref }}
cancel-in-progress: true
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v6
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- uses: gradle/actions/setup-gradle@v5
with:
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
cache-read-only: true # gradle user home cache is generated by test jobs
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: java-kotlin
build-mode: manual # autobuild uses older JDK
- name: Build # we must not use build cache here
run: ./gradlew --no-daemon --configuration-cache app:assembleDebug
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"

View File

@@ -1,24 +0,0 @@
name: Dependency Submission
on:
push:
branches: [ 'main-ose' ]
permissions:
contents: write
jobs:
dependency-submission:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
- name: Generate and submit dependency graph
uses: gradle/actions/dependency-submission@v5
with:
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
dependency-graph-exclude-configurations: '.*[Tt]est.* .*[cC]heck.*'

View File

@@ -9,6 +9,7 @@ concurrency:
cancel-in-progress: true
env:
java-version: 21
prerelease: ${{ contains(github.ref_name, '-alpha') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-rc') }}
jobs:
@@ -23,15 +24,17 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
java-version: ${{ env.java-version }}
- uses: gradle/actions/setup-gradle@v5
with:
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
- name: Prepare keystore
run: echo ${{ secrets.android_keystore_base64 }} | base64 -d >$GITHUB_WORKSPACE/keystore.jks
- name: Build signed package
# Use build cache to speed up building of build variants, but clean caches from previous tests before
run: ./gradlew --build-cache --configuration-cache --no-daemon app:clean app:assembleRelease
# don't use build cache to guarantee deterministic, fresh builds
run: ./gradlew --no-build-cache --configuration-cache --no-daemon app:clean app-ose:assembleRelease
env:
ANDROID_KEYSTORE: ${{ github.workspace }}/keystore.jks
ANDROID_KEYSTORE_PASSWORD: ${{ secrets.android_keystore_password }}
@@ -42,6 +45,6 @@ jobs:
uses: softprops/action-gh-release@v2
with:
prerelease: ${{ env.prerelease }}
files: app/build/outputs/apk/ose/release/*.apk
files: app-ose/build/outputs/apk/ose/release/*.apk
fail_on_unmatched_files: true
generate_release_notes: true

View File

@@ -2,7 +2,7 @@ name: Development tests
on:
push:
branches:
- 'main-ose'
- 'main'
pull_request:
concurrency:
@@ -18,6 +18,7 @@ env:
GRADLE_BUILDCACHE_USERNAME: ${{ secrets.gradle_buildcache_username }}
GRADLE_BUILDCACHE_PASSWORD: ${{ secrets.gradle_buildcache_password }}
GRADLE_OPTS: -Dorg.gradle.caching=true -Dorg.gradle.configuration-cache=true
JAVA_VERSION: 21
jobs:
compile:
@@ -28,31 +29,17 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
java-version: ${{ env.JAVA_VERSION }}
# See https://community.gradle.org/github-actions/docs/setup-gradle/ for more information
- uses: gradle/actions/setup-gradle@v5
with:
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
cache-read-only: false # allow branches to update their configuration cache
cache-read-only: false # allow to update the cache
gradle-home-cache-excludes: caches/build-cache-1 # don't cache local build cache because we use a remote cache
- name: Cache Android environment
uses: actions/cache@v5
with:
path: ~/.config/.android # needs to be cached so that configuration cache can work
key: android-${{ hashFiles('app/build.gradle.kts') }}
- name: Compile
run: ./gradlew app:compileOseDebugSource
# Cache configurations for the other jobs (including assemble for CodeQL)
- name: Populate configuration cache
run: |
./gradlew --dry-run app:assembleDebug
./gradlew --dry-run app:lintOseDebug
./gradlew --dry-run app:testOseDebugUnitTest
./gradlew --dry-run app:virtualOseDebugAndroidTest
run: ./gradlew app-ose:assembleDebug
unit_tests:
needs: compile
@@ -63,23 +50,18 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
java-version: ${{ env.JAVA_VERSION }}
- uses: gradle/actions/setup-gradle@v5
with:
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
cache-read-only: true
- name: Restore Android environment
uses: actions/cache/restore@v5
with:
path: ~/.config/.android
key: android-${{ hashFiles('app/build.gradle.kts') }}
- name: Lint checks
run: ./gradlew app:lintOseDebug
run: ./gradlew core:lintDebug app:lintOseDebug
- name: Unit tests
run: ./gradlew app:testOseDebugUnitTest
# currently no unit tests for app-ose
run: ./gradlew core:testDebugUnitTest
instrumented_tests:
needs: compile
@@ -90,18 +72,12 @@ jobs:
- uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
java-version: ${{ env.JAVA_VERSION }}
- uses: gradle/actions/setup-gradle@v5
with:
cache-encryption-key: ${{ secrets.gradle_encryption_key }}
cache-read-only: true
- name: Restore Android environment
uses: actions/cache/restore@v5
with:
path: ~/.config/.android
key: android-${{ hashFiles('app/build.gradle.kts') }}
# gradle and Android SDK often take more space than what is available on the default runner.
# We try to free a few GB here to make gradle-managed devices more reliable.
- name: Free some disk space
@@ -115,8 +91,8 @@ jobs:
id: restore-avd
uses: actions/cache/restore@v5
with:
path: ~/.config/.android/avd # where AVD is stored
key: avd-${{ hashFiles('app/build.gradle.kts') }} # gradle-managed devices are defined there
path: ~/.config/.android/avd # where AVD is stored
key: avd-${{ hashFiles('app-ose/build.gradle.kts') }} # gradle-managed devices are defined there
# Enable virtualization for Android emulator
- name: Enable KVM group perms
@@ -126,11 +102,12 @@ jobs:
sudo udevadm trigger --name-match=kvm
- name: Instrumented tests
run: ./gradlew app:virtualOseDebugAndroidTest
# currently no instrumented tests for app-ose
run: ./gradlew core:virtualDebugAndroidTest
- name: Cache AVD
uses: actions/cache/save@v5
if: steps.restore-avd.outputs.cache-hit != 'true'
with:
path: ~/.config/.android/avd # where AVD is stored
key: avd-${{ hashFiles('app/build.gradle.kts') }} # gradle-managed devices are defined there
path: ~/.config/.android/avd # where AVD is stored
key: avd-${{ hashFiles('app-ose/build.gradle.kts') }} # gradle-managed devices are defined there

View File

@@ -1,32 +0,0 @@
[main]
host = https://www.transifex.com
lang_map = ar_SA: ar, en_GB: en-rGB, fi_FI: fi, mr_IN: mr-rIN, nb_NO: nb, pt_BR: pt-rBR, sk_SK: sk, sl_SI: sl, tr_TR: tr, zh_CN: zh, zh_TW: zh-rTW
[o:bitfireAT:p:davx5:r:app]
file_filter = app/src/main/res/values-<lang>/strings.xml
source_file = app/src/main/res/values/strings.xml
source_lang = en
type = ANDROID
minimum_perc = 20
resource_name = App strings (all flavors)
# Attention: fastlane directories are like "en-us", not "en-rUS"!
[o:bitfireAT:p:davx5:r:metadata-short-description]
file_filter = fastlane/metadata/android/<lang>/short_description.txt
source_file = fastlane/metadata/android/en-US/short_description.txt
source_lang = en
type = TXT
minimum_perc = 100
resource_name = Metadata: short description
lang_map = ar_SA: ar, en_GB: en-rGB, fi_FI: fi, mr_IN: mr-rIN, nb_NO: nb, pt_BR: pt-rBR, sk_SK: sk, sl_SI: sl, tr_TR: tr, zh_CN: zh, zh_TW: zh-rTW
[o:bitfireAT:p:davx5:r:metadata-full-description]
file_filter = fastlane/metadata/android/<lang>/full_description.txt
source_file = fastlane/metadata/android/en-US/full_description.txt
source_lang = en
type = TXT
minimum_perc = 100
resource_name = Metadata: full description
lang_map = ar_SA: ar, en_GB: en-rGB, fi_FI: fi, mr_IN: mr-rIN, nb_NO: nb, pt_BR: pt-rBR, sk_SK: sk, sl_SI: sl, tr_TR: tr, zh_CN: zh, zh_TW: zh-rTW

130
app-ose/build.gradle.kts Normal file
View File

@@ -0,0 +1,130 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt)
alias(libs.plugins.ksp)
alias(libs.plugins.mikepenz.aboutLibraries.android)
}
android {
compileSdk = 36
defaultConfig {
minSdk = 24 // Android 7.0
targetSdk = 36 // Android 16
applicationId = "at.bitfire.davdroid"
versionCode = 405100000
versionName = "4.5.10-alpha.1"
base.archivesName = "davx5-$versionCode-$versionName"
// currently no instrumentation tests for app-ose, so no testInstrumentationRunner
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
compileOptions {
isCoreLibraryDesugaringEnabled = true
}
buildFeatures {
compose = true
}
// Java namespace for our classes (not to be confused with Android package ID)
namespace = "com.davx5.ose"
flavorDimensions += "distribution"
productFlavors {
create("ose") {
dimension = "distribution"
versionNameSuffix = "-ose"
}
}
androidResources {
generateLocaleConfig = true
}
@Suppress("UnstableApiUsage")
testOptions {
managedDevices {
localDevices {
create("virtual") {
device = "Pixel 3"
// TBD: API level 35 and higher causes network tests to fail sometimes, see https://github.com/bitfireAT/davx5-ose/issues/1525
// Suspected reason: https://developer.android.com/about/versions/15/behavior-changes-all#background-network-access
apiLevel = 34
systemImageSource = "aosp-atd"
}
}
}
}
signingConfigs {
create("bitfire") {
storeFile = file(System.getenv("ANDROID_KEYSTORE") ?: "/dev/null")
storePassword = System.getenv("ANDROID_KEYSTORE_PASSWORD")
keyAlias = System.getenv("ANDROID_KEY_ALIAS")
keyPassword = System.getenv("ANDROID_KEY_PASSWORD")
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules-release.pro")
isShrinkResources = true
// must be after signingConfigs {} block
signingConfig = signingConfigs.findByName("bitfire")
}
}
}
dependencies {
// include core subproject (manages its own dependencies itself, however from same version catalog)
implementation(project(":core"))
// Kotlin / Android
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines)
coreLibraryDesugaring(libs.android.desugaring)
// Hilt
implementation(libs.hilt.android.base)
ksp(libs.androidx.hilt.compiler)
ksp(libs.hilt.android.compiler)
// support libs
implementation(libs.androidx.core)
implementation(libs.androidx.hilt.work)
implementation(libs.androidx.lifecycle.viewmodel.base)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.work.base)
// Jetpack Compose
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.material3)
debugImplementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.compose.ui.toolingPreview)
// own libraries
implementation(libs.bitfire.cert4android)
// third-party libs
implementation(libs.guava)
implementation(libs.okhttp.base)
implementation(libs.openid.appauth)
}

View File

@@ -0,0 +1,5 @@
-dontobfuscate
-printusage build/reports/r8-usage.txt
# keep rules are taken from core/core-proguard-rules.pro

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="internalOnly">
<application android:name=".App">
<!-- Required for Hilt/WorkManager integration. See
- https://developer.android.com/develop/background-work/background-tasks/persistent/configuration/custom-configuration#remove-default
- https://developer.android.com/training/dependency-injection/hilt-jetpack#workmanager
However, we must not disable AndroidX startup completely, as it's needed by other libraries like okhttp. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
</application>
</manifest>

View File

@@ -0,0 +1,30 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose
import androidx.work.Configuration
import at.bitfire.davdroid.CoreApp
import dagger.hilt.android.HiltAndroidApp
/**
* Actual implementation of Application, used for Hilt. Delegates to [CoreApp].
*/
@HiltAndroidApp
class App: CoreApp(), Configuration.Provider {
/**
* Required for Hilt/WorkManager integration, see:
* https://developer.android.com/training/dependency-injection/hilt-jetpack#workmanager
*
* This requires to remove the androidx.work.WorkManagerInitializer from App Startup
* in the AndroidManifest, see:
* https://developer.android.com/develop/background-work/background-tasks/persistent/configuration/custom-configuration#remove-default
*/
override val workManagerConfiguration: Configuration
get() = Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()
}

View File

@@ -1,8 +1,8 @@
/***************************************************************************************************
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
**************************************************************************************************/
*/
package at.bitfire.davdroid
package com.davx5.ose
import android.content.Context
import at.bitfire.davdroid.ui.DebugInfoActivity

View File

@@ -0,0 +1,19 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.AccountsDrawerHandler
import at.bitfire.davdroid.ui.OseAccountsDrawerHandler
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
@Module
@InstallIn(ActivityComponent::class)
interface AccountsDrawerHandlerModule {
@Binds
fun accountsDrawerHandler(impl: OseAccountsDrawerHandler): AccountsDrawerHandler
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.about.AboutActivity
import com.davx5.ose.ui.about.OpenSourceLicenseInfoProvider
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ViewModelComponent
@Module
@InstallIn(ViewModelComponent::class)
interface AppLicenseInfoProviderModule {
@Binds
fun appLicenseInfoProvider(impl: OpenSourceLicenseInfoProvider): AboutActivity.AppLicenseInfoProvider
}

View File

@@ -0,0 +1,61 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import android.content.Context
import at.bitfire.cert4android.CustomCertManager
import at.bitfire.cert4android.CustomCertStore
import at.bitfire.cert4android.SettingsProvider
import at.bitfire.davdroid.settings.Settings
import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.davdroid.ui.ForegroundTracker
import dagger.Module
import dagger.Provides
import dagger.Reusable
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import okhttp3.internal.tls.OkHostnameVerifier
import java.util.Optional
/**
* cert4android integration module
*/
@Module
@InstallIn(SingletonComponent::class)
class Cert4AndroidModule {
@Provides
fun customCertStore(@ApplicationContext context: Context): Optional<CustomCertStore> =
Optional.of(CustomCertStore.getInstance(context))
@Provides
@Reusable
fun customCertManager(
customCertStore: Optional<CustomCertStore>,
settings: SettingsManager
): Optional<CustomCertManager> =
Optional.of(
CustomCertManager(
certStore = customCertStore.get(),
settings = object : SettingsProvider {
override val appInForeground: Boolean
get() = ForegroundTracker.inForeground.value
override val trustSystemCerts: Boolean
get() = !settings.getBoolean(Settings.DISTRUST_SYSTEM_CERTIFICATES)
}
))
@Provides
@Reusable
fun customHostnameVerifier(
customCertManager: Optional<CustomCertManager>
): Optional<CustomCertManager.HostnameVerifier> =
Optional.of(customCertManager.get().HostnameVerifier(OkHostnameVerifier))
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import androidx.compose.material3.ColorScheme
import at.bitfire.davdroid.di.qualifier.DarkColorScheme
import at.bitfire.davdroid.di.qualifier.LightColorScheme
import at.bitfire.davdroid.ui.OseTheme
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
class ColorSchemesModule {
@Provides
@LightColorScheme
fun lightColorScheme(): ColorScheme = OseTheme.lightScheme
@Provides
@DarkColorScheme
fun darkColorScheme(): ColorScheme = OseTheme.darkScheme
}

View File

@@ -0,0 +1,19 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.intro.IntroPageFactory
import com.davx5.ose.ui.intro.OseIntroPageFactory
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
interface IntroPageFactoryModule {
@Binds
fun introPageFactory(impl: OseIntroPageFactory): IntroPageFactory
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package com.davx5.ose.di
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
import at.bitfire.davdroid.ui.setup.StandardLoginTypesProvider
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
interface LoginTypesProviderModule {
@Binds
fun loginTypesProvider(impl: StandardLoginTypesProvider): LoginTypesProvider
}

View File

@@ -2,9 +2,9 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui
package com.davx5.ose.ui.about
import android.app.Application
import android.content.Context
import android.text.Spanned
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -14,15 +14,18 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.text.HtmlCompat
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import at.bitfire.davdroid.di.qualifier.IoDispatcher
import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString
import at.bitfire.davdroid.ui.about.AboutActivity
import com.google.common.io.CharStreams
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.Dispatchers
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.launch
import javax.inject.Inject
class OpenSourceLicenseInfoProvider @Inject constructor(): AboutActivity.AppLicenseInfoProvider {
@@ -40,13 +43,16 @@ class OpenSourceLicenseInfoProvider @Inject constructor(): AboutActivity.AppLice
@HiltViewModel
class Model @Inject constructor(app: Application): AndroidViewModel(app) {
class Model @Inject constructor(
@ApplicationContext private val context: Context,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher
): ViewModel() {
var gpl by mutableStateOf<Spanned?>(null)
init {
viewModelScope.launch(Dispatchers.IO) {
app.resources.assets.open("gplv3.html").use { inputStream ->
viewModelScope.launch(ioDispatcher) {
context.resources.assets.open("gplv3.html").use { inputStream ->
val raw = CharStreams.toString(inputStream.bufferedReader())
gpl = HtmlCompat.fromHtml(raw, HtmlCompat.FROM_HTML_MODE_LEGACY)
}

View File

@@ -2,11 +2,19 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui.intro
package com.davx5.ose.ui.intro
import at.bitfire.davdroid.ui.intro.BackupsPage
import at.bitfire.davdroid.ui.intro.BatteryOptimizationsPage
import at.bitfire.davdroid.ui.intro.IntroPageFactory
import at.bitfire.davdroid.ui.intro.OpenSourcePage
import at.bitfire.davdroid.ui.intro.PermissionsIntroPage
import at.bitfire.davdroid.ui.intro.TasksIntroPage
import at.bitfire.davdroid.ui.intro.WelcomePage
import javax.inject.Inject
class OseIntroPageFactory @Inject constructor(
backupsPage: BackupsPage,
batteryOptimizationsPage: BatteryOptimizationsPage,
openSourcePage: OpenSourcePage,
permissionsIntroPage: PermissionsIntroPage,
@@ -18,6 +26,7 @@ class OseIntroPageFactory @Inject constructor(
tasksIntroPage,
permissionsIntroPage,
batteryOptimizationsPage,
backupsPage,
openSourcePage
)

1
app/src/.gitignore vendored
View File

@@ -1 +0,0 @@
espressoTest

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,22 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid
import at.bitfire.synctools.icalendar.ical4jVersion
import ezvcard.Ezvcard
/**
* Brand-specific constants like (non-theme) colors, homepage URLs etc.
*/
object Constants {
const val DAVDROID_GREEN_RGBA = 0xFF8bc34a.toInt()
// product IDs for iCalendar/vCard
val iCalProdId = "DAVx5/${BuildConfig.VERSION_NAME} ical4j/$ical4jVersion"
const val vCardProdId = "+//IDN bitfire.at//DAVx5/${BuildConfig.VERSION_NAME} ez-vcard/${Ezvcard.VERSION}"
}

View File

@@ -1,360 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui
import android.content.Context
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Home
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Tab
import androidx.compose.material3.TabRow
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import at.bitfire.davdroid.di.IoDispatcher
import at.bitfire.davdroid.ui.ExternalUris.withStatParams
import at.bitfire.davdroid.ui.composable.PixelBoxes
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.ui.compose.LibraryDefaults
import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer
import com.mikepenz.aboutlibraries.util.withContext
import dagger.BindsOptionalOf
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.AndroidEntryPoint
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.text.Collator
import java.util.LinkedList
import java.util.Locale
import java.util.Optional
import java.util.logging.Level
import java.util.logging.Logger
import javax.inject.Inject
import kotlin.jvm.optionals.getOrNull
@AndroidEntryPoint
class AboutActivity: AppCompatActivity() {
val model by viewModels<Model>()
@Inject
lateinit var licenseInfoProvider: Optional<AppLicenseInfoProvider>
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppTheme {
val uriHandler = LocalUriHandler.current
Scaffold(
topBar = {
TopAppBar(
navigationIcon = {
IconButton(onClick = { onSupportNavigateUp() }) {
Icon(
Icons.AutoMirrored.Default.ArrowBack,
contentDescription = stringResource(R.string.navigate_up)
)
}
},
title = {
Text(stringResource(R.string.navigation_drawer_about))
},
actions = {
IconButton(onClick = {
uriHandler.openUri(ExternalUris.Homepage.baseUrl
.buildUpon()
.withStatParams(javaClass.simpleName)
.build().toString())
}) {
Icon(
Icons.Default.Home,
contentDescription = stringResource(R.string.navigation_drawer_website)
)
}
}
)
}
) { paddingValues ->
Column(Modifier.padding(paddingValues)) {
val scope = rememberCoroutineScope()
val state = rememberPagerState(pageCount = { 3 })
TabRow(state.currentPage) {
Tab(state.currentPage == 0, onClick = {
scope.launch { state.scrollToPage(0) }
}) {
Text(
stringResource(R.string.app_name),
modifier = Modifier.padding(8.dp)
)
}
Tab(state.currentPage == 1, onClick = {
scope.launch { state.scrollToPage(1) }
}) {
Text(
stringResource(R.string.about_translations),
modifier = Modifier.padding(8.dp)
)
}
Tab(state.currentPage == 2, onClick = {
scope.launch { state.scrollToPage(2) }
}) {
Text(
stringResource(R.string.about_libraries),
modifier = Modifier.padding(8.dp)
)
}
}
HorizontalPager(
state,
modifier = Modifier
.fillMaxWidth()
.weight(1f),
verticalAlignment = Alignment.Top
) { index ->
when (index) {
0 -> AboutApp(licenseInfoProvider = licenseInfoProvider.getOrNull())
1 -> {
val translations = model.translations.collectAsStateWithLifecycle(emptyList())
TranslatorsGallery(translations.value)
}
2 -> LibrariesContainer(
modifier = Modifier.fillMaxSize(),
padding = LibraryDefaults.libraryPadding(
contentPadding = PaddingValues(8.dp)
),
dimensions = LibraryDefaults.libraryDimensions(
itemSpacing = 8.dp
),
libraries = Libs.Builder()
.withContext(LocalContext.current)
.build()
)
}
}
}
}
}
}
}
@HiltViewModel
class Model @Inject constructor(
@ApplicationContext val context: Context,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher,
private val logger: Logger
): ViewModel() {
data class Translation(
val language: String,
val translators: Set<String>
)
val translations: Flow<List<Translation>> = flow {
val translations = loadTranslations()
emit(translations)
}
private suspend fun loadTranslations(): List<Translation> = withContext(ioDispatcher) {
try {
context.resources.assets.open("translators.json").use { stream ->
val jsonTranslations = JSONObject(stream.readBytes().decodeToString())
val result = LinkedList<Translation>()
for (langCode in jsonTranslations.keys()) {
val jsonTranslators = jsonTranslations.getJSONArray(langCode)
val translators = Array<String>(jsonTranslators.length()) { idx ->
jsonTranslators.getString(idx)
}
val langTag = langCode.replace('_', '-')
val language = Locale.forLanguageTag(langTag).displayName
result += Translation(language, translators.toSet())
}
// sort translations by localized language name
val collator = Collator.getInstance()
result.sortWith { o1, o2 ->
collator.compare(o1.language, o2.language)
}
result
}
} catch (e: Exception) {
logger.log(Level.WARNING, "Couldn't load translators", e)
emptyList()
}
}
}
interface AppLicenseInfoProvider {
@Composable
fun LicenseInfo()
}
@Module
@InstallIn(ActivityComponent::class)
interface AppLicenseInfoProviderModule {
@BindsOptionalOf
fun appLicenseInfoProvider(): AppLicenseInfoProvider
}
}
@Composable
fun AboutApp(licenseInfoProvider: AboutActivity.AppLicenseInfoProvider? = null) {
Column(
modifier = Modifier
.padding(8.dp)
.fillMaxWidth()
.verticalScroll(rememberScrollState())) {
Image(
UiUtils.adaptiveIconPainterResource(R.mipmap.ic_launcher),
contentDescription = stringResource(R.string.app_name),
modifier = Modifier
.size(128.dp)
.align(Alignment.CenterHorizontally)
)
Text(
stringResource(R.string.app_name),
style = MaterialTheme.typography.headlineMedium,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
)
Text(
stringResource(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
Text(
stringResource(R.string.about_copyright),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 8.dp)
)
Text(
stringResource(R.string.about_license_info_no_warranty),
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier
.fillMaxWidth()
.padding(top = 8.dp)
)
PixelBoxes(
arrayOf(Color(0xFFFCF434), Color.White, Color(0xFF9C59D1), Color.Black),
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(16.dp)
)
licenseInfoProvider?.LicenseInfo()
}
}
@Composable
@Preview
fun AboutApp_Preview() {
AboutApp(licenseInfoProvider = object : AboutActivity.AppLicenseInfoProvider {
@Composable
override fun LicenseInfo() {
Text("Some flavored License Info")
}
})
}
@Composable
fun TranslatorsGallery(
translations: List<AboutActivity.Model.Translation>
) {
val collator = Collator.getInstance()
LazyColumn(Modifier.padding(8.dp)) {
items(translations) { translation ->
Text(
translation.language,
style = MaterialTheme.typography.headlineMedium,
modifier = Modifier.padding(vertical = 4.dp)
)
Text(
translation.translators
.sortedWith { a, b -> collator.compare(a, b) }
.joinToString(" · "),
style = MaterialTheme.typography.bodyLarge,
modifier = Modifier.padding(bottom = 16.dp)
)
}
}
}
@Composable
@Preview
fun TranslatorsGallery_Sample() {
TranslatorsGallery(listOf(
AboutActivity.Model.Translation("Some Language", setOf("User 1", "User 2")),
AboutActivity.Model.Translation("Another Language", setOf("User 3", "User 4"))
))
}

View File

@@ -1,12 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui.widget
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
class IconSyncButtonWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = IconSyncButtonWidget()
}

View File

@@ -1,12 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui.widget
import androidx.glance.appwidget.GlanceAppWidget
import androidx.glance.appwidget.GlanceAppWidgetReceiver
class LabeledSyncButtonWidgetReceiver : GlanceAppWidgetReceiver() {
override val glanceAppWidget: GlanceAppWidget = LabeledSyncButtonWidget()
}

View File

@@ -1,66 +0,0 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.webdav.operation
import android.content.Context
import at.bitfire.dav4jvm.okhttp.DavResource
import at.bitfire.dav4jvm.okhttp.exception.HttpException
import at.bitfire.davdroid.db.AppDatabase
import at.bitfire.davdroid.di.IoDispatcher
import at.bitfire.davdroid.webdav.DavHttpClientBuilder
import at.bitfire.davdroid.webdav.DocumentProviderUtils
import at.bitfire.davdroid.webdav.DocumentProviderUtils.displayNameToMemberName
import at.bitfire.davdroid.webdav.throwForDocumentProvider
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.runInterruptible
import java.io.FileNotFoundException
import java.util.logging.Logger
import javax.inject.Inject
class RenameDocumentOperation @Inject constructor(
@ApplicationContext private val context: Context,
private val db: AppDatabase,
private val httpClientBuilder: DavHttpClientBuilder,
@IoDispatcher private val ioDispatcher: CoroutineDispatcher,
private val logger: Logger
) {
private val documentDao = db.webDavDocumentDao()
operator fun invoke(documentId: String, displayName: String): String? = runBlocking {
logger.fine("WebDAV renameDocument $documentId $displayName")
val doc = documentDao.get(documentId.toLong()) ?: throw FileNotFoundException()
val client = httpClientBuilder.build(doc.mountId)
for (attempt in 0..DocumentProviderUtils.MAX_DISPLAYNAME_TO_MEMBERNAME_ATTEMPTS) {
val newName = displayNameToMemberName(displayName, attempt)
val oldUrl = doc.toHttpUrl(db)
val newLocation = oldUrl.newBuilder()
.removePathSegment(oldUrl.pathSegments.lastIndex)
.addPathSegment(newName)
.build()
try {
val dav = DavResource(client, oldUrl)
runInterruptible(ioDispatcher) {
dav.move(newLocation, false) {
// successfully renamed
}
}
documentDao.update(doc.copy(name = newName))
DocumentProviderUtils.notifyFolderChanged(context, doc.parentId)
return@runBlocking doc.id.toString()
} catch (e: HttpException) {
e.throwForDocumentProvider(context, true)
}
}
null
}
}

View File

@@ -1,483 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--common strings-->
<string name="account_invalid">Konto nicht (mehr) vorhanden</string>
<string name="account_title_address_book">DAVx⁵-Adressbuch</string>
<string name="account_prefs_use_app">Konto nicht hier ändern! Um Konten zu verwalten, stattdessen direkt die App nutzen.</string>
<string name="dialog_delete">Löschen</string>
<string name="dialog_remove">Entfernen</string>
<string name="dialog_deny">Abbrechen</string>
<string name="dialog_enable">Aktivieren</string>
<string name="field_required">Feld wird benötigt</string>
<string name="help">Hilfe</string>
<string name="navigate_up">Aufwärts navigieren</string>
<string name="options_menu">Auswahlmenü</string>
<string name="share">Teilen</string>
<string name="sync_started">Synchronisierung gestartet/eingereiht</string>
<string name="database_destructive_migration_title">Datenbank beschädigt</string>
<string name="database_destructive_migration_text">Alle Konten wurden lokal entfernt.</string>
<string name="notification_channel_debugging">Fehlersuche</string>
<string name="notification_channel_general">Andere wichtige Mitteilungen</string>
<string name="notification_channel_status">Weniger wichtige Statusmitteilungen</string>
<string name="notification_channel_sync">Synchronisierung</string>
<string name="notification_channel_sync_errors">Synchronisierungsfehler</string>
<string name="notification_channel_sync_errors_desc">Fehler, die zum Abbruch der Synchronisierung führen, wie z.B. unerwartete Serverantworten</string>
<string name="notification_channel_sync_warnings">Synchronisierungswarnungen</string>
<string name="notification_channel_sync_warnings_desc">Nicht fatale Synchronisierungsprobleme wie bestimmte ungültige Dateien</string>
<string name="notification_channel_sync_io_errors">Netzwerk- und E/A-Fehler</string>
<string name="notification_channel_sync_io_errors_desc">Zeitüberschreitungen, Verbindungsprobleme, usw. (oft vorübergehend)</string>
<!--IntroActivity-->
<string name="intro_slogan1">Dein Leben. Deine Daten.</string>
<string name="intro_slogan2">Deine Entscheidung.</string>
<string name="intro_battery_title">Regelmäßige Sync-Intervalle</string>
<string name="intro_battery_text">Zur Synchronisierung in regelmäßigen Intervallen muss %s im Hintergrund laufen dürfen; ansonsten kann Android die Synchronisierung jederzeit aussetzen.</string>
<string name="intro_battery_dont_show">Ich brauche keine regelmäßigen Sync-Intervalle.*</string>
<string name="intro_autostart_title">%s-Kompatibilität</string>
<string name="intro_autostart_text">Herstellerspezifische Firmware blockiert möglicherweise die Synchronisierung. Wenn Sie davon betroffen sind, können Sie dies nur manuell beheben.</string>
<string name="intro_autostart_dont_show">Ich habe die Einstellungen gemacht, nicht mehr erinnern.*</string>
<string name="intro_leave_unchecked">* Nicht anwählen, um später erinnert zu werden. Kann unter App-Einstellungen / %s zurückgesetzt werden.</string>
<string name="intro_more_info">Mehr Infos</string>
<string name="intro_tasks_jtx">jtx Board</string>
<string name="intro_tasks_jtx_info"><![CDATA[Unterstützt Synchronisierung von Aufgaben, Journalen und Notizen.]]></string>
<string name="intro_tasks_title">Unterstützung für Aufgaben</string>
<string name="intro_tasks_text1">Falls der Server Aufgaben unterstützt, können sie mit einer unterstützten App synchronisiert werden:</string>
<string name="intro_tasks_opentasks">OpenTasks</string>
<string name="intro_tasks_opentasks_info">Wird anscheinend nicht weiterentwickelt nicht empfohlen.</string>
<string name="intro_tasks_tasks_org">Tasks.org</string>
<string name="intro_tasks_tasks_org_info"><![CDATA[Einige Funktionen <a href="https://www.davx5.com/faq/tasks/advanced-task-features">werden nicht unterstützt</a>.]]></string>
<string name="intro_tasks_no_app_store">Kein App-Store verfügbar</string>
<string name="intro_tasks_dont_show">Ich brauche keine Unterstützung für Aufgaben.*</string>
<string name="intro_open_source_title">Open-Source-Software</string>
<string name="intro_open_source_text">Wir freuen uns, dass Sie die Open-Source-Software %s verwenden. Entwicklung, Wartung und Support sind viel Arbeit. Ziehen Sie daher bitte in Betracht, mitzuhelfen (dazu gibt es viele Möglichkeiten) oder zu spenden. Vielen Dank!</string>
<string name="intro_open_source_details">Infos zum Mithelfen/Spenden</string>
<string name="intro_open_source_dont_show">Nicht daran erinnern für</string>
<plurals name="intro_open_source_dont_show_months">
<item quantity="one">%d Monat</item>
<item quantity="other">%d Monate</item>
</plurals>
<string name="intro_next">Weiter</string>
<!--PermissionsActivity-->
<string name="permissions_title">Berechtigungsverwaltung</string>
<string name="permissions_text">%s benötigt Berechtigungen, um ordnungsgemäß zu funktionieren.</string>
<string name="permissions_all_title">Alles darunter</string>
<string name="permissions_all_status_off">Hiermit können alle Funktionen aktiviert werden (empfohlen)</string>
<string name="permissions_all_status_on">Alle Berechtigungen gewährt</string>
<string name="permissions_contacts_title">Kontakte-Berechtigungen</string>
<string name="permissions_contacts_status_off">Keine Kontakte-Synchronisierung (nicht empfohlen)</string>
<string name="permissions_contacts_status_on">Kontakte-Synchronisierung möglich</string>
<string name="permissions_calendar_title">Kalender-Berechtigungen</string>
<string name="permissions_calendar_status_off">Keine Kalender-Synchronisierung (nicht empfohlen)</string>
<string name="permissions_calendar_status_on">Kalender-Synchronisierung möglich</string>
<string name="permissions_notification_title">Benachrichtigungsberechtigung</string>
<string name="permissions_notification_status_off">Benachrichtigungen deaktiviert (nicht empfohlen)</string>
<string name="permissions_notification_status_on">Benachrichtigungen aktiviert</string>
<string name="permissions_jtx_title">jtx Board-Berechtigungen</string>
<string name="permissions_opentasks_title">OpenTasks-Berechtigungen</string>
<string name="permissions_tasksorg_title">Tasks-Berechtigungen</string>
<string name="permissions_tasks_status_off">Keine Aufgaben-Synchronisierung</string>
<string name="permissions_tasks_status_on">Aufgaben-Synchronisierung möglich</string>
<string name="permissions_autoreset_title">Berechtigungen behalten</string>
<string name="permissions_autoreset_status_off">Berechtigungen können automatisch entzogen werden (nicht empfohlen)</string>
<string name="permissions_autoreset_status_on">Berechtigungen werden nicht automatisch entzogen</string>
<string name="permissions_autoreset_instruction">Berechtigungen &gt; \"Berechtigungen entfernen, wenn die App nicht verwendet wird\" abwählen</string>
<string name="permissions_app_settings_hint">Wenn ein Schalter nicht funktioniert, App-Einstellungen / Berechtigungen verwenden.</string>
<string name="permissions_app_settings">App-Einstellungen</string>
<!--WifiPermissionsActivity-->
<string name="wifi_permissions_label">WLAN-SSID-Berechtigungen</string>
<string name="wifi_permissions_intro">Um auf den aktuellen WLAN-Namen (SSID) zugreifen zu können, müssen folgende Bedingungen erfüllt werden:</string>
<string name="wifi_permissions_location_permission">Exakter Standort-Berechtigung</string>
<string name="wifi_permissions_location_permission_on">Standort-Zugriff erlaubt</string>
<string name="wifi_permissions_location_permission_off">Standort-Zugriff verweigert</string>
<string name="wifi_permissions_background_location_permission">Hintergrund-Standort-Berechtigung</string>
<string name="wifi_permissions_background_location_permission_label">Immer zulassen</string>
<string name="wifi_permissions_background_location_permission_on">Standort-Zugriff eingestellt auf: %s</string>
<string name="wifi_permissions_background_location_permission_off">Standort-Zugriff nicht eingestellt auf: %s</string>
<string name="wifi_permissions_background_location_disclaimer">%s benutzt Standortdaten (nur WLAN-SSID) ausschließlich, um die Synchronisierung auf ein bestimmtes WLAN zu beschränken. Dies geschieht auch dann, wenn die Synchronisierung im Hintergrund ausgeführt wird.</string>
<string name="wifi_permissions_background_location_disclaimer2">Alle Standortdaten (nur WLAN-SSID) werden nur lokal verwendet und nicht an Dritte weitergegeben.</string>
<string name="wifi_permissions_location_enabled">Standort-Dienst immer aktiviert</string>
<string name="wifi_permissions_location_enabled_on">Standort-Dienst aktiv</string>
<string name="wifi_permissions_location_enabled_off">Standort-Dienst inaktiv</string>
<!--AboutActivity-->
<string name="about_translations">Übersetzungen</string>
<string name="about_libraries">Bibliotheken</string>
<string name="about_version">Version %1$s (%2$d)</string>
<string name="about_copyright">© Ricki Hirner, Bernhard Stockmann (bitfire web engineering GmbH) und Mitwirkende</string>
<string name="about_license_info_no_warranty">Dieses Programm wird OHNE JEDE GEWÄHRLEISTUNG bereitgestellt. Es ist freie Software Sie können es also unter bestimmten Bedingungen weiterverbreiten.</string>
<!--global settings-->
<string name="logging_couldnt_create_file">Protokolldatei konnte nicht angelegt werden</string>
<string name="logging_notification_text">Alle %s-Aktivitäten werden protokolliert</string>
<string name="logging_notification_view_share">Anzeigen/teilen</string>
<string name="logging_notification_disable">Deaktivieren</string>
<!--AccountsScreen-->
<string name="navigation_drawer_subtitle">CalDAV/CardDAV-Sync-Adapter</string>
<string name="navigation_drawer_about">Über / Lizenz</string>
<string name="navigation_drawer_beta_feedback">Beta-Rückmeldung</string>
<string name="install_browser">Bitte installieren Sie einen Web-Browser</string>
<string name="navigation_drawer_settings">Einstellungen</string>
<string name="navigation_drawer_news_updates">Aktuelles</string>
<string name="navigation_drawer_tools">Werkzeuge</string>
<string name="navigation_drawer_external_links">Externe Links</string>
<string name="navigation_drawer_website">Homepage</string>
<string name="navigation_drawer_manual">Handbuch</string>
<string name="navigation_drawer_faq">FAQ</string>
<string name="navigation_drawer_managed">Für Organisationen</string>
<string name="navigation_drawer_community">Community</string>
<string name="navigation_drawer_support_project">Projekt unterstützen</string>
<string name="navigation_drawer_contribute">Einen Beitrag leisten</string>
<string name="navigation_drawer_privacy_policy">Datenschutzerklärung</string>
<string name="account_list_welcome">Willkommen bei DAVx⁵!</string>
<string name="account_list_empty">Verbinden Sie sich mit Ihrem Server und synchronisieren Sie Ihre Kalender und Kontakte.</string>
<string name="accounts_sync_all">Alle Konten synchronisieren</string>
<!--Sync warnings-->
<string name="sync_warning_no_notification_permission">Benachrichtigungen deaktiviert. Sie werden nicht über Fehler bei der Synchronisierung informiert.</string>
<string name="sync_warning_no_internet">Automatische Synchronisation nicht aktiv (keine überprüfte Internetverbindung).</string>
<string name="sync_warning_manage_connections">Verbindungen steuern</string>
<string name="sync_warning_datasaver_enabled">Datensparen aktiviert. Hintergrundsynchronisierung ist eingeschränkt.</string>
<string name="sync_warning_manage_datasaver">Datensparen verwalten</string>
<string name="sync_warning_battery_saver_enabled">Energiesparmodus aktiviert. Synchronisierung kann eingeschränkt sein.</string>
<string name="sync_warning_manage_battery_saver">Energieeinstellungen verwalten</string>
<string name="sync_warning_low_storage">Wenig Speicherplatz. Android wird lokale Änderungen nicht sofort synchronisieren, sondern bei der nächsten regulären Synchronisierung.</string>
<string name="sync_warning_manage_storage">Speicherplatz verwalten</string>
<string name="sync_warning_calendar_storage_disabled_title">Kalender-Provider fehlt</string>
<string name="sync_warning_calendar_storage_disabled_description">Haben Sie die »Kalender«-System-App deaktiviert?</string>
<string name="sync_warning_contacts_storage_disabled_title">Kontakte-Provider fehlt</string>
<string name="sync_warning_contacts_storage_disabled_description">Haben Sie die »Kontakte«-System-App deaktiviert?</string>
<string name="sync_warning_manage_apps">Apps verwalten</string>
<!--RefreshCollectionsWorker-->
<string name="refresh_collections_worker_refresh_failed">Diensterkennung fehlgeschlagen</string>
<string name="refresh_collections_worker_refresh_couldnt_refresh">Ordnerliste konnte nicht aktualisiert werden</string>
<!--Foreground service used by WorkManager on Android <12-->
<string name="foreground_service_notify_title">Läuft im Vordergrund</string>
<string name="foreground_service_notify_text">Auf manchen Geräten für die automatische Synchronisierung benötigt</string>
<!--AppSettingsActivity-->
<string name="app_settings">Einstellungen</string>
<string name="app_settings_debug">Fehlersuche</string>
<string name="app_settings_show_debug_info">Informationen zur Fehlersuche</string>
<string name="app_settings_show_debug_info_details">Einstellungsdetails und Logs anzeigen/teilen</string>
<string name="app_settings_logging">Ausführliche Protokollierung</string>
<string name="app_settings_logging_on">Logging ist aktiv. Sie können die Logs in den Debuginformationen anzeigen.</string>
<string name="app_settings_logging_off">Keine Protokollierung</string>
<string name="app_settings_battery_optimization">Akku-Optimierung</string>
<string name="app_settings_battery_optimization_exempted">App ist ausgenommen (empfohlen)</string>
<string name="app_settings_battery_optimization_optimized">Akku-Einschränkungen gelten (nicht empfohlen)</string>
<string name="app_settings_connection">Verbindung</string>
<string name="app_settings_proxy">Proxy-Typ</string>
<string-array name="app_settings_proxy_types">
<item>System-Standard</item>
<item>Kein Proxy</item>
<item>HTTP</item>
<item>SOCKS (für Orbot)</item>
</string-array>
<string name="app_settings_proxy_host">Proxy-Rechnername</string>
<string name="app_settings_proxy_port">Proxy-Port</string>
<string name="app_settings_security">Sicherheit</string>
<string name="app_settings_security_app_permissions">App-Berechtigungen</string>
<string name="app_settings_security_app_permissions_summary">Für die Synchronisierung benötigte Berechtigungen prüfen</string>
<string name="app_settings_distrust_system_certs">Systemzertifikaten nicht vertrauen</string>
<string name="app_settings_distrust_system_certs_on">System- und installierten CAs wird nicht vertraut</string>
<string name="app_settings_distrust_system_certs_off">System- und installierten CAs wird vertraut (empfohlen)</string>
<string name="app_settings_distrust_system_certs_dialog_message">Wenn diese Einstellung aktiv ist, werden Systemzertifikate als nicht vertrauenswürdig erachtet. Das bedeutet, dass Sie jedes Zertifikat (auch wenn der Server sein Zertifikat auffrischt) von Hand akzeptieren müssen; sonst werden Kontoeinrichtung und Synchronisierung nicht funktionieren.</string>
<string name="app_settings_reset_certificates">Zertifikat-Vertrauen zurücksetzen</string>
<string name="app_settings_reset_certificates_summary">Setzt angenommene/abgelehnte Zertifikate zurück</string>
<string name="app_settings_reset_certificates_success">Angenommene/abgelehnte Zertifikate zurückgesetzt</string>
<string name="app_settings_user_interface">Oberfläche</string>
<string name="app_settings_notification_settings">Benachrichtigungseinstellungen</string>
<string name="app_settings_notification_settings_summary">Benachrichtigungskanäle und -einstellungen verwalten</string>
<string name="app_settings_theme_title">Aussehen wählen</string>
<string-array name="app_settings_theme_names">
<item>wie System</item>
<item>heller Stil</item>
<item>dunkler Stil</item>
</string-array>
<string name="app_settings_reset_hints">Hinweise zurücksetzen</string>
<string name="app_settings_reset_hints_summary">Hinweise, die deaktiviert wurden, wieder anzeigen</string>
<string name="app_settings_reset_hints_success">Alle Hinweise werden wieder angezeigt</string>
<string name="app_settings_integration">Integration</string>
<string name="app_settings_tasks_provider">Aufgaben-App</string>
<string name="app_settings_tasks_provider_none">Keine kompatible Aufgaben-App gefunden</string>
<string name="app_settings_unifiedpush">UnifiedPush (experimentell)</string>
<string name="app_settings_unifiedpush_disable">Keiner (Push deaktivieren)</string>
<string name="app_settings_unifiedpush_choose_distributor">Anbieter auswählen</string>
<string name="app_settings_unifiedpush_no_distributor">Kein Push-Anbieter installiert</string>
<string name="app_settings_unifiedpush_no_endpoint">Kein Endpunkt konfiguriert</string>
<string name="app_settings_unifiedpush_ready">Bereit, Push-Mitteilungen über %s zu empfangen</string>
<string name="app_settings_unifiedpush_distributor_fcm">FCM (Google Play)</string>
<string name="app_settings_unifiedpush_encrypted">Push-Nachrichten sind immer verschlüsselt.</string>
<!--AccountScreen-->
<string name="account_invalid_account">Konto wurde entfernt</string>
<string name="account_carddav">CardDAV</string>
<string name="account_caldav">CalDAV</string>
<string name="account_webcal">Webcal</string>
<string name="account_missing_permissions">Für die Synchronisierung dieser Ordner sind zusätzliche Berechtigungen erforderlich.</string>
<string name="account_manage_permissions">Berechtigungen verwalten</string>
<string name="account_synchronize_now">Jetzt synchronisieren</string>
<string name="account_settings">Konto-Einstellungen</string>
<string name="account_rename">Konto umbenennen</string>
<string name="account_rename_new_name_description">Nicht gespeicherte lokale Daten können verloren gehen. Nach dem Umbenennen ist eine erneute Synchronisierung erforderlich.</string>
<string name="account_rename_new_name">Neuer Kontoname</string>
<string name="account_rename_rename">Umbenennen</string>
<string name="account_rename_exists_already">Kontoname bereits verwendet</string>
<string name="account_rename_couldnt_rename">Konto konnte nicht umbenannt werden</string>
<string name="account_delete">Konto löschen</string>
<string name="account_delete_confirmation_title">Konto wirklich löschen?</string>
<string name="account_delete_confirmation_text">Alle Adressbücher, Kalender und Aufgabenlisten werden vom Gerät (nicht am Server) gelöscht.</string>
<string name="account_synchronize_this_collection">Diesen Ordner synchronisieren</string>
<string name="account_read_only">schreibgeschützt</string>
<string name="account_calendar">Kalender</string>
<string name="account_contacts">Kontakte</string>
<string name="account_journal">Journal</string>
<string name="account_task_list">Aufgaben</string>
<string name="account_only_personal">Nur eigene anzeigen</string>
<string name="account_refresh_collections">Liste aktualisieren</string>
<string name="account_webcal_external_app">Webcal-Abonnements können mit externen Apps synchronisiert werden.</string>
<string name="account_no_webcal_handler_found">Keine Webcal-App gefunden</string>
<string name="account_install_icsx5">ICSx⁵ installieren</string>
<!--AddAccountActivity-->
<string name="login_title">Konto hinzufügen</string>
<string name="login_privacy_hint"><![CDATA[Alle Daten werden nur zwischen Ihrem Server und Ihrem Gerät übertragen. %1$s wird sie nirgendwohin sonst schicken. Siehe die <a href="%2$s">Datenschutzbestimmungen</a>.]]></string>
<string name="login_generic_login">Allgemeine Anmeldung</string>
<string name="login_provider_login">Provider-spezifische Anmeldung</string>
<string name="login_continue">Fortfahren</string>
<string name="login_login">Anmelden</string>
<string name="login_type_email">Mit E-Mail-Adresse anmelden</string>
<string name="login_email_address">E-Mail-Adresse</string>
<string name="login_email_address_error">Gültige E-Mail-Adresse benötigt</string>
<string name="login_email_address_info"><![CDATA[Die E-Mail-Domäne wird als Basis-URL verwendet. <a href="%s">Dienst-Erkennung</a> erfolgt über DNS-Einträge und well-known-URLs.]]></string>
<string name="login_password">Passwort</string>
<string name="login_password_hide">Passwort ausblenden</string>
<string name="login_password_show">Passwort anzeigen</string>
<string name="login_password_optional">Passwort (optional)</string>
<string name="login_type_url">Mit URL und Benutzername anmelden</string>
<string name="login_user_name">Benutzername</string>
<string name="login_user_name_optional">Benutzername (optional)</string>
<string name="login_base_url">Basis-URL</string>
<string name="login_base_url_info"><![CDATA[Basis-URL wird direkt geprüft, aber es erfolgt auch <a href="%s">Dienst-Erkennung</a> über DNS-Einträge und well-known-URLs.]]></string>
<string name="login_select_certificate">Zertifikat auswählen</string>
<string name="login_add_account">Konto hinzufügen</string>
<string name="login_account_name">Kontoname</string>
<string name="login_account_avoid_apostrophe">Das Verwenden von Apostrophen (\') scheint auf einigen Geräten Probleme zu verursachen.</string>
<string name="login_account_name_info">Verwenden Sie Ihre E-Mail-Adresse als Kontonamen, da Android den Kontonamen als ORGANIZER einsetzt. Es kann allerdings keine zwei Konten mit dem gleichen Namen geben.</string>
<string name="login_account_contact_group_method">Kontaktgruppen-Methode:</string>
<string name="login_account_name_required">Kontoname wird benötigt</string>
<string name="login_account_name_already_taken">Kontoname bereits verwendet</string>
<string name="login_account_not_added">Konto konnte nicht hinzugefügt werden</string>
<string name="login_finish">Abschließen</string>
<string name="login_type_advanced">Erweiterte Anmeldung</string>
<string name="login_no_client_certificate_optional">Kein Client-Zertifikat (optional)</string>
<string name="login_client_certificate_selected">Client-Zertifikat: %s</string>
<string name="login_no_certificate_found">Kein Zertifikat gefunden</string>
<string name="login_install_certificate">Zertifikat installieren </string>
<string name="login_fastmail">Fastmail</string>
<string name="login_fastmail_account">Fastmail-Konto</string>
<string name="login_fastmail_sign_in">Mit Fastmail anmelden</string>
<string name="login_type_google">Google-Kontakte / -Kalender</string>
<string name="login_google_account">Google-Konto</string>
<string name="login_google">Mit Google anmelden</string>
<string name="login_google_client_id">Client-ID (optional)</string>
<string name="login_google_client_privacy_policy"><![CDATA[%1$s überträgt Ihre Google-Kontakte und -Kalenderdaten zur Synchronisierung mit diesem Gerät. Siehe auch unsere <a href="%2$s">Datenschutzrichtlinie</a> für mehr Informationen.]]></string>
<string name="login_google_client_limited_use"><![CDATA[%1$s richtet sich nach der <a href="%2$s">Google API Services Nutzerdaten-Richtlinie</a>, inklusive der eingeschränkten Nutzungsbedingungen.]]></string>
<string name="login_oauth_couldnt_obtain_auth_code">Authentifizierungscode konnte nicht abgerufen werden</string>
<string name="login_type_nextcloud">Nextcloud</string>
<string name="login_nextcloud_login_with_nextcloud">Mit Nextcloud anmelden</string>
<string name="login_nextcloud_login_flow_text">Dadurch wird der Nextcloud-Anmeldevorgang in einem Webbrowser gestartet.</string>
<string name="login_nextcloud_login_flow_server_address">Nextcloud-Serveradresse</string>
<string name="login_nextcloud_login_flow_sign_in">Anmeldung</string>
<string name="login_nextcloud_login_flow_no_login_url">Login-URL konnte nicht abgerufen werden</string>
<string name="login_nextcloud_login_flow_no_login_data">Anmeldedaten konnten nicht abgerufen werden</string>
<string name="login_configuration_detection">Ressourcen-Erkennung</string>
<string name="login_querying_server">Server wird abgefragt. Bitte warten …</string>
<string name="login_no_service">Es konnte weder ein CalDAV- noch ein CardDAV-Dienst gefunden werden.</string>
<string name="login_no_service_info">Die Basis-URL scheint keine erreichbare CalDAV/CardDAV-URL zu sein und die Diensterkennung war nicht erfolgreich.</string>
<string name="login_see_tested_services"><![CDATA[Bitte beachten Sie das Handbuch Ihres Dienstanbieters und <a href="%s">unsere Liste der getesteten Dienste</a> und deren Basis-URLs.]]></string>
<string name="login_check_credentials">Bitte überprüfen Sie auch die Authentifizierung (normalerweise Benutzername und Passwort).</string>
<string name="login_logs_available">Weitere technische Informationen sind in den Protokollen verfügbar.</string>
<string name="login_view_logs">Protokoll anzeigen</string>
<!--AccountSettingsActivity-->
<string name="settings_sync">Synchronisierung</string>
<string name="settings_sync_interval_contacts">Häufigkeit der Kontakte-Synchronisierung</string>
<string name="settings_sync_summary_manually">Nur manuell</string>
<string name="settings_sync_summary_periodically" tools:ignore="PluralsCandidate">Alle %d Minuten + sofort bei lokalen Änderungen</string>
<string name="settings_sync_interval_calendars">Häufigkeit der Kalender-Synchronisierung</string>
<string name="settings_sync_interval_tasks">Häufigkeit der Aufgaben-Synchronisierung</string>
<string-array name="settings_sync_interval_names">
<item>Nur manuell</item>
<item>Alle 15 Minuten</item>
<item>Alle 30 Minuten</item>
<item>Jede Stunde</item>
<item>Alle 2 Stunden</item>
<item>Alle 4 Stunden</item>
<item>Einmal am Tag</item>
</string-array>
<string name="settings_sync_wifi_only">Nur über WLAN synchronisieren</string>
<string name="settings_sync_wifi_only_on">Synchronisierung nur bei aktiver WLAN-Verbindung</string>
<string name="settings_sync_wifi_only_off">Verbindungstyp wird nicht beachtet</string>
<string name="settings_sync_wifi_only_ssids">WLAN-SSID-Beschränkung</string>
<string name="settings_sync_wifi_only_ssids_on">Synchronisierung nur über %s</string>
<string name="settings_sync_wifi_only_ssids_off">Alle WLAN-Verbindungen werden verwendet</string>
<string name="settings_sync_wifi_only_ssids_message">Erlaubte WLAN-Namen (SSIDs), mit Komma getrennt (leer lassen für alle)</string>
<string name="settings_sync_wifi_only_ssids_permissions_required">WLAN-SSID-Einschränkung benötigt weitere Einstellungen</string>
<string name="settings_sync_wifi_only_ssids_permissions_action">Verwalten</string>
<string name="settings_ignore_vpns">VPN erfordert zugrundeliegendes Internet</string>
<string name="settings_ignore_vpns_on">VPN ohne zugrundeliegende überprüfte Internetverbindung reicht für Synchronisierung nicht aus (empfohlen)</string>
<string name="settings_ignore_vpns_off">VPN ohne zugrundeliegende überprüfte Internetverbindung reicht für Synchronisierung aus</string>
<string name="settings_authentication">Anmeldeinformationen</string>
<string name="settings_username">Benutzername</string>
<string name="settings_password">Passwort oder App-Passwort</string>
<string name="settings_app_password_hint"><![CDATA[Möglicherweise möchten Sie ein <a href="%1$s">App-Passwort</a> verwenden.]]></string>
<string name="settings_new_password">Neues Passwort</string>
<string name="settings_password_summary">Aktualisieren Sie Ihr Passwort gemäß den Server-Einstellungen.</string>
<string name="settings_reauthorize_oauth">Erneut authentifizieren (OAuth)</string>
<string name="settings_reauthorize_oauth_summary">Verwenden, wenn der Zugriff widerrufen wurde</string>
<string name="settings_reauthorize_oauth_success">Authentifizierung erfolgreich</string>
<string name="settings_certificate_alias">Client-Zertifikat</string>
<string name="settings_certificate_alias_empty">Kein Zertifikat verfügbar oder ausgewählt</string>
<string name="settings_certificate_install">Zertifikat installieren </string>
<string name="settings_caldav">CalDAV</string>
<string name="settings_sync_time_range_past">Abrufbeschränkung vergangener Termine</string>
<string name="settings_sync_time_range_past_none">Alle Termine werden synchronisiert</string>
<plurals name="settings_sync_time_range_past_days">
<item quantity="one">Termine, die mehr als einen Tag in der Vergangenheit liegen, werden ignoriert</item>
<item quantity="other">Termine, die mehr als %d Tage in der Vergangenheit liegen, werden ignoriert</item>
</plurals>
<string name="settings_sync_time_range_past_message">Termine, die mehr als diese Anzahl von Tagen in der Vergangenheit liegen, werden ignoriert (kann 0 sein). Feld leer lassen, um alle Termine zu synchronisieren.</string>
<string name="settings_default_alarm">Standard-Erinnerung</string>
<plurals name="settings_default_alarm_on">
<item quantity="one">Standard-Erinnerung eine Minute vor dem Ereignis</item>
<item quantity="other">Standard-Erinnerung %d Minuten vor dem Ereignis</item>
</plurals>
<string name="settings_default_alarm_off">Keine Standard-Erinnerungen</string>
<string name="settings_default_alarm_message">Wenn Standard-Erinnerungen für Termine ohne Erinnerung erzeugt werden sollen: gewünschte Anzahl der Minuten vor dem Ereignis. Leer lassen, um Standard-Erinnerungen zu deaktivieren.</string>
<string name="settings_manage_calendar_colors">Kalenderfarben verwalten</string>
<string name="settings_manage_calendar_colors_on">Kalenderfarben werden bei jeder Synchronisierung neu gesetzt</string>
<string name="settings_manage_calendar_colors_off">Kalenderfarben können von anderen Apps festgesetzt werden</string>
<string name="settings_event_colors">Unterstützung für Terminfarben</string>
<string name="settings_event_colors_on">Terminfarben werden synchronisiert</string>
<string name="settings_event_colors_off">Terminfarben werden nicht synchronisiert</string>
<string name="settings_carddav">CardDAV</string>
<string name="settings_contact_group_method">Kontaktgruppen-Methode</string>
<string-array name="settings_contact_group_method_entries">
<item>Gruppen sind eigene vCards</item>
<item>Gruppen sind Kategorien der Kontakte</item>
</string-array>
<!--CreateAddressBookScreen, CreateCalendarScreen-->
<string name="create_addressbook">Adressbuch erstellen</string>
<string name="create_addressbook_maybe_not_supported">Das Erstellen von Adressbüchern über CardDAV wird vom Server möglicherweise nicht unterstützt.</string>
<string name="create_calendar">Kalender anlegen</string>
<string name="create_calendar_time_zone_optional">Standard-Zeitzone (optional)</string>
<string name="create_calendar_time_zone_none"></string>
<string name="create_calendar_type">Mögliche Kalendereinträge</string>
<string name="create_calendar_type_vevent">Termine</string>
<string name="create_calendar_type_vtodo">Aufgaben</string>
<string name="create_calendar_type_vjournal">Notizen / Journal</string>
<string name="create_calendar_maybe_not_supported">Das Erstellen von Kalendern über CardDAV wird vom Server möglicherweise nicht unterstützt.</string>
<string name="create_collection_color">Farbe</string>
<string name="create_collection_display_name">Titel</string>
<string name="create_collection_home_set">Speicherort</string>
<string name="create_collection_description_optional">Beschreibung (optional)</string>
<string name="create_collection_create">Erstellen</string>
<!--CollectionScreen-->
<string name="collection_datatype_contacts">Kontakte</string>
<string name="collection_datatype_events">Termine</string>
<string name="collection_datatype_tasks">Aufgaben</string>
<string name="collection_delete">Ordner löschen</string>
<string name="collection_delete_warning">Dieser Ordner (%s) und alle enthaltenen Daten werden dauerhaft entfernt, sowohl lokal als auch auf dem Server.</string>
<string name="collection_synchronization">Synchronisierung</string>
<string name="collection_synchronization_on">Synchronisierung aktiviert</string>
<string name="collection_synchronization_off">Synchronisierung deaktiviert</string>
<string name="collection_read_only">Schreibgeschützt</string>
<string name="collection_read_only_by_server">Schreibgeschützt (durch Server)</string>
<string name="collection_read_only_by_setting">Schreibgeschützt (laut Richtlinie)</string>
<string name="collection_read_only_forced">Schreibgeschützt (nur lokal)</string>
<string name="collection_read_write">Lesen/Schreiben</string>
<string name="collection_title">Titel</string>
<string name="collection_description">Beschreibung</string>
<string name="collection_owner">Besitzende Entität</string>
<string name="collection_push_support">Push-Unterstützung</string>
<string name="collection_push_web_push">Server bietet Push-Unterstützung</string>
<string name="collection_push_subscribed_at">Um %1$s angemeldet, läuft ab %2$s</string>
<string name="collection_last_sync">Letzte Synchronisierung (%s)</string>
<string name="collection_url">Adresse (URL)</string>
<!--debugging and DebugInfoActivity-->
<string name="debug_info_title">Informationen zur Fehlersuche</string>
<string name="debug_info_archive_caption">ZIP-Archiv</string>
<string name="debug_info_archive_subtitle">Beinhaltet Debug-Info und Logs</string>
<string name="debug_info_archive_text">Das Archiv teilen, um es zu einem Rechner zu übertragen, per Email zu verschicken oder an ein Support-Ticket anzuhängen.</string>
<string name="debug_info_archive_share">Archiv teilen</string>
<string name="debug_info_attached">Debug-Informationen sind dieser Nachricht beigelegt (benötigt Unterstützung für Anhänge in der empfangenden App).</string>
<string name="debug_info_http_error">HTTP-Fehler</string>
<string name="debug_info_server_error">Serverfehler</string>
<string name="debug_info_webdav_error">WebDAV-Fehler</string>
<string name="debug_info_io_error">E/A-Fehler</string>
<string name="debug_info_http_403_description">Die Anfrage wurde vom Server abgelehnt.</string>
<string name="debug_info_http_404_description">Die angeforderte Ressource existiert nicht (mehr).</string>
<string name="debug_info_http_405_description">Der Server erlaubt die angeforderte Art der Operation nicht.</string>
<string name="debug_info_http_5xx_description">Es trat ein serverseitiges Problem auf. Wenden Sie sich bitte an den Server-Support.</string>
<string name="debug_info_unexpected_error">Es trat ein unerwarteter Fehler auf. Einzelheiten dazu finden Sie in der Debug-Info.</string>
<string name="debug_info_view_details">Details anzeigen</string>
<string name="debug_info_subtitle">Debug-Informationen wurden gesammelt</string>
<string name="debug_info_involved_caption">Beteiligte Ressourcen</string>
<string name="debug_info_involved_subtitle">Im Zusammenhang mit dem Problem</string>
<string name="debug_info_involved_remote">Entfernte Ressource:</string>
<string name="debug_info_involved_local">Lokale Ressource:</string>
<string name="debug_info_logs_caption">Protokoll</string>
<string name="debug_info_logs_subtitle">Ausführliches Protokoll verfügbar</string>
<string name="debug_info_logs_view">Logs anzeigen</string>
<string name="debug_info_copy_remote_url">URL kopieren</string>
<string name="debug_info_view_local_resource">Ressource überprüfen</string>
<string name="debug_info_privacy_warning_title">Datenschutzhinweis</string>
<string name="debug_info_privacy_warning_description">Protokolle und Debug-Informationen können private Daten enthalten. Seien Sie sich dessen bewusst, wenn Sie diese öffentlich weitergeben.</string>
<string name="debug_info_can_not_view_resource">Ressource kann nicht angezeigt werden</string>
<!--ExceptionInfoFragment-->
<string name="exception">Ein Fehler ist aufgetreten.</string>
<string name="exception_httpexception">Ein HTTP-Fehler ist aufgetreten.</string>
<string name="exception_ioexception">Ein E/A-Fehler ist aufgetreten.</string>
<string name="exception_show_details">Details anzeigen</string>
<!--WebDAV accounts-->
<string name="webdav_mounts_title">WebDAV-Zugänge</string>
<string name="webdav_mounts_quota_used_available">Speicher belegt: %1$s / verfügbar: %2$s</string>
<string name="webdav_mounts_share_content">Inhalt teilen</string>
<string name="webdav_mounts_unmount">Aushängen</string>
<string name="webdav_add_mount_title">WebDAV-Zugang hinzufügen</string>
<string name="webdav_mounts_empty">Greifen Sie mit einem WebDAV-Zugang direkt auf Ihre Cloud-Dateien zu!</string>
<string name="webdav_add_mount_empty_more_info"><![CDATA[In der Anleitung erfahren Sie mehr darüber, <a href="%1$s">wie WebDAV-Zugänge funktionieren</a>.]]></string>
<string name="webdav_add_mount_display_name">Anzeigename</string>
<string name="webdav_add_mount_url">WebDAV-Adresse</string>
<string name="webdav_add_mount_url_invalid">Ungültige Adresse</string>
<string name="webdav_add_mount_mountpoint_displayname">Einhängepunkt und Anzeigename</string>
<string name="webdav_add_mount_authentication">Anmeldeinformationen</string>
<string name="webdav_add_mount_username">Anmeldename</string>
<string name="webdav_add_mount_password">Passwort</string>
<string name="webdav_add_mount_username_optional">Benutzername (optional)</string>
<string name="webdav_add_mount_password_optional">Passwort (optional)</string>
<string name="webdav_add_mount_add">Einhängen</string>
<string name="webdav_add_mount_no_support">Kein WebDAV-Dienst unter dieser Adresse</string>
<string name="webdav_remove_mount_title">Einhängepunkt entfernen</string>
<string name="webdav_remove_mount_text">Verbindungsdetails werden verloren gehen, es werden aber keine Dateien gelöscht.</string>
<string name="webdav_notification_access">WebDAV-Dateizugriff</string>
<string name="webdav_notification_download">WebDAV-Download</string>
<string name="webdav_notification_upload">WebDAV-Upload</string>
<string name="webdav_provider_root_title">WebDAV-Zugang</string>
<!--sync-->
<string name="sync_error_permissions">DAVx⁵-Berechtigungen</string>
<string name="sync_error_permissions_text">Zusätzliche Berechtigungen benötigt</string>
<string name="sync_error_tasks_too_old">%s zu alt</string>
<string name="sync_error_tasks_required_version">Benötigte Mindestversion: %1$s</string>
<string name="sync_error_authentication_failed">Anmeldungsfehler (Login-Daten überprüfen)</string>
<string name="sync_error_io">Netzwerk- oder E/A-Fehler %s</string>
<string name="sync_error_http_dav">HTTP-Serverfehler %s</string>
<string name="sync_error_local_storage">Lokaler Speicherfehler %s</string>
<string name="sync_error_retry_limit_reached">Weicher Fehler (maximale Anzahl an Wiederholungen erreicht)</string>
<string name="sync_invalid_contact">Ungültigen Kontakt vom Server erhalten</string>
<string name="sync_invalid_event">Ungültigen Termin vom Server erhalten</string>
<string name="sync_invalid_task">Ungültige Aufgabe vom Server erhalten</string>
<string name="sync_invalid_resources_ignoring">Eine/mehrere ungültige Ressourcen ignoriert</string>
<string name="sync_notification_pending_push_title">Synchronisierung ausstehend</string>
<string name="sync_notification_pending_push_message">Daten auf dem Server haben sich geändert</string>
<!--widgets-->
<string name="widget_sync_all">Alles synchronisieren</string>
<string name="widget_sync_all_accounts">Alle Konten synchronisieren</string>
<string name="widget_labeled_sync_label">Beschriftete Sync-Taste</string>
<string name="widget_icon_sync_label">Sync-Taste-Symbol</string>
<string name="widget_sync_description">Antippen, um die Synchronisierung manuell durchzuführen.</string>
<!--cert4android-->
</resources>

View File

@@ -1,406 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--common strings-->
<string name="account_invalid">Account inesistente (o cancellato)</string>
<string name="account_title_address_book">Rubrica DAVx⁵</string>
<string name="dialog_delete">Cancella</string>
<string name="dialog_remove">Elimina</string>
<string name="dialog_deny">Annulla</string>
<string name="dialog_enable">Attiva</string>
<string name="field_required">Questo campo è necessario</string>
<string name="help">Aiuto</string>
<string name="options_menu">Menu opzioni</string>
<string name="share">Condividi</string>
<string name="sync_started">Sincronizzazione avviata</string>
<string name="database_destructive_migration_title">Database danneggiato</string>
<string name="database_destructive_migration_text">Tutti gli account sono stati rimossi localmente.</string>
<string name="notification_channel_debugging">Debugging</string>
<string name="notification_channel_general">Altri messaggi importanti</string>
<string name="notification_channel_status">Messaggi di stato a bassa priorità</string>
<string name="notification_channel_sync">Sincronizzazione</string>
<string name="notification_channel_sync_errors">Errori di sincronizzazione</string>
<string name="notification_channel_sync_errors_desc">Errori importanti che bloccano la sincronizzazione, come risposte inattese del server</string>
<string name="notification_channel_sync_warnings">Avvisi di sincronizzazione</string>
<string name="notification_channel_sync_warnings_desc">Problemi di sincronizzazione non gravi come alcuni file non validi</string>
<string name="notification_channel_sync_io_errors">Errori di Rete e di I/O</string>
<string name="notification_channel_sync_io_errors_desc">Timeouts, problemi di connessione, ecc. (spesso temporanei)</string>
<!--IntroActivity-->
<string name="intro_slogan1">Tuoi i dati. Tua la scelta.</string>
<string name="intro_slogan2">Riprendi il controllo.</string>
<string name="intro_battery_title">Intervalli di sincronizzazione regolari.</string>
<string name="intro_battery_text">Per sincronizzare i dati a intervalli regolari, %s deve essere autorizzato a girare in background. Altrimenti Android può mettere in pausa gli aggiornamenti in qualunque momento.</string>
<string name="intro_battery_dont_show">Non ho bisogno di sincronizzare a intervalli di tempo regolari.*</string>
<string name="intro_autostart_title">%s compatibilità</string>
<string name="intro_autostart_dont_show">Ho settato le impostazioni richieste. Non ricordarmelo più.</string>
<string name="intro_leave_unchecked">* Lascia smarcato per fartelo ricordare dopo. Può essere reimpostato nelle impostazione dell\'app %s.</string>
<string name="intro_more_info">Maggiori informazioni</string>
<string name="intro_tasks_jtx_info"><![CDATA[Supporta la sincronizzazione di Attività, Diari e Note.]]></string>
<string name="intro_tasks_title">Supporto per le attività</string>
<string name="intro_tasks_text1">Se le attività sono supportate dal tuo server, possono essere sincronizzate con una app per attività supportata:</string>
<string name="intro_tasks_opentasks">OpenTasks</string>
<string name="intro_tasks_opentasks_info">Non sembra essere più sviluppato - non raccomandato.</string>
<string name="intro_tasks_tasks_org">Tasks.org</string>
<string name="intro_tasks_no_app_store">Nessun app store disponibile</string>
<string name="intro_tasks_dont_show">Non ho bisogno del supporto alle attività.*</string>
<string name="intro_open_source_title">Software open-source</string>
<string name="intro_open_source_text">Siamo felici che tu usi %s, che è un software open source. Lo sviluppo, la manutenzione e il supporto sono compiti duri. Per piacere prendi in considerazione di dare una mano (puoi farlo in molti modi) o una donazione. Sarebbe davvero apprezzato!</string>
<string name="intro_open_source_details">Come aiutare/donare</string>
<!--PermissionsActivity-->
<string name="permissions_title">Autorizzazioni</string>
<string name="permissions_text">%s richiede autorizzazioni per funzionare correttamente.</string>
<string name="permissions_all_title">Tutti i seguenti</string>
<string name="permissions_all_status_off">Usare questo per abilitare tutte le funzioni (consigliato)</string>
<string name="permissions_all_status_on">Concedi tutte le autorizzazioni</string>
<string name="permissions_contacts_title">Autorizzazioni per i contatti</string>
<string name="permissions_contacts_status_off">Non sincronizzare i contatti (sconsigliato)</string>
<string name="permissions_contacts_status_on">Possibilità di sincronizzare i contatti</string>
<string name="permissions_calendar_title">Autorizzazioni per il calendario</string>
<string name="permissions_calendar_status_off">Non sincronizzare il calendario (sconsigliato)</string>
<string name="permissions_calendar_status_on">Permette di sincronizzare il calendario</string>
<string name="permissions_notification_title">Autorizza notifiche</string>
<string name="permissions_notification_status_off">Notifiche disabilitate (non consigliato)</string>
<string name="permissions_notification_status_on">Notifiche attive</string>
<string name="permissions_opentasks_title">Autorizzazioni di OpenTasks</string>
<string name="permissions_tasksorg_title">Autorizzazioni delle attività</string>
<string name="permissions_tasks_status_on">Permette di sincronizzare le attività</string>
<string name="permissions_autoreset_title">Mantieni autorizzazioni</string>
<string name="permissions_autoreset_status_off">Le autorizzazioni possono essere reimpostate automaticamente (sconsigliato)</string>
<string name="permissions_autoreset_status_on">Le autorizzazioni non si reimposteranno automaticamente</string>
<string name="permissions_autoreset_instruction">Fai click su Autorizzazioni &gt; deseleziona \"Rimuovi autorizzazioni se l\'app non è in uso\"</string>
<string name="permissions_app_settings_hint">Se uno slider non funziona, vai a impostazioni app/ autorizzazioni.</string>
<string name="permissions_app_settings">Impostazioni app</string>
<!--WifiPermissionsActivity-->
<string name="wifi_permissions_label">Autorizzazioni per WiFi SSID</string>
<string name="wifi_permissions_intro">Per poter accedere al nome dell\'attuale nome del WIFI (SSID), devono essere soddfsfatte queste condizioni:</string>
<string name="wifi_permissions_location_permission">Autorizzazione precisa della localizzazione</string>
<string name="wifi_permissions_location_permission_on">Garantire l\'autorizzazione della posizione</string>
<string name="wifi_permissions_location_permission_off">Negare l\'autorizzazione della posizione</string>
<string name="wifi_permissions_background_location_permission">Autorizzazione della posizione in background</string>
<string name="wifi_permissions_background_location_permission_label">Permettere sempre</string>
<string name="wifi_permissions_background_location_permission_on">Permessi di localizzazione impostati a: %s</string>
<string name="wifi_permissions_background_location_permission_off">Permessi di localizzazione non impostati a: %s</string>
<string name="wifi_permissions_location_enabled">Posizione sempre disabilitata</string>
<string name="wifi_permissions_location_enabled_on">Servizio di posizione abiltato</string>
<string name="wifi_permissions_location_enabled_off">Servizio di posizione disabilitato</string>
<!--AboutActivity-->
<string name="about_translations">Traduzioni</string>
<string name="about_libraries">Librerie</string>
<string name="about_version">Versione %1$s (%2$d)</string>
<string name="about_copyright">© Ricki Hirner, Bernhard Stockmann (bitfire web engineering GmbH) e contibutori</string>
<string name="about_license_info_no_warranty">Il programma è distribuito SENZA ALCUNA GARANZIA. È software libero e può essere redistribuito sotto alcune condizioni.</string>
<!--global settings-->
<string name="logging_couldnt_create_file">Impossibile creare il file di log</string>
<string name="logging_notification_text">Adesso l\'accesso all\' %s delle attività </string>
<string name="logging_notification_view_share">Visualizza/condividi</string>
<string name="logging_notification_disable">Disabilita</string>
<!--AccountsScreen-->
<string name="navigation_drawer_subtitle">CalDAV/CardDAV adattatore di sincronizzazione</string>
<string name="navigation_drawer_about">Informazioni / Licenza</string>
<string name="navigation_drawer_beta_feedback">Feedback sulla beta</string>
<string name="install_browser">Installare un browser Web</string>
<string name="navigation_drawer_settings">Impostazioni</string>
<string name="navigation_drawer_news_updates">Notizie &amp; aggiornamenti</string>
<string name="navigation_drawer_tools">Strumenti</string>
<string name="navigation_drawer_external_links">Link esterni</string>
<string name="navigation_drawer_website">Sito web</string>
<string name="navigation_drawer_manual">Manuale</string>
<string name="navigation_drawer_faq">Domande Frequenti</string>
<string name="navigation_drawer_community">Comunità</string>
<string name="navigation_drawer_support_project">Supporta il progetto</string>
<string name="navigation_drawer_contribute">Come contribuire</string>
<string name="navigation_drawer_privacy_policy">Politica sulla riservatezza</string>
<string name="accounts_sync_all">Sincronizzazione di tutti gli account</string>
<!--Sync warnings-->
<string name="sync_warning_no_notification_permission">Notifiche non attive. Non sarai avvisato di eventuali errori di sincronizzazione</string>
<string name="sync_warning_manage_connections">Gestione connessioni</string>
<string name="sync_warning_datasaver_enabled">Risparmio dati attivo. La sincronizzazione in background è limitata,</string>
<string name="sync_warning_battery_saver_enabled">Risparmio energetico attivo. La sincronizzazione in background è limitata,</string>
<string name="sync_warning_manage_battery_saver">Gestisci risparmio energetico</string>
<string name="sync_warning_low_storage">Spazio di memorizzazione scarso. Androin non salverà immediatamente i cambiamente, ma alla prossima sincronizzazione programmata.</string>
<string name="sync_warning_manage_storage">Gestisci spazio di memorizzazione</string>
<!--RefreshCollectionsWorker-->
<string name="refresh_collections_worker_refresh_failed">Impossibile trovare il servizio</string>
<string name="refresh_collections_worker_refresh_couldnt_refresh">Impossibile aggiornare la lista delle raccolte</string>
<!--Foreground service used by WorkManager on Android <12-->
<string name="foreground_service_notify_title">Esecuzione in primo piano</string>
<string name="foreground_service_notify_text">Su alcuni dispositivi, questo è necessario per la sincronizzazione automatica.</string>
<!--AppSettingsActivity-->
<string name="app_settings">Impostazioni</string>
<string name="app_settings_debug">Debug</string>
<string name="app_settings_show_debug_info">Mostra informazioni di debug</string>
<string name="app_settings_logging">Log completo</string>
<string name="app_settings_logging_off">Log disabilitato</string>
<string name="app_settings_battery_optimization">Ottimizzazione batteria</string>
<string name="app_settings_connection">Connessione</string>
<string name="app_settings_proxy">Tipo di proxy</string>
<string-array name="app_settings_proxy_types">
<item>Predefinito di sistema</item>
<item>Nessun proxy</item>
<item>HTTP</item>
<item>SOCKS (per Orbot)</item>
</string-array>
<string name="app_settings_proxy_host">Nome host proxy</string>
<string name="app_settings_proxy_port">Porta proxy</string>
<string name="app_settings_security">Sicurezza</string>
<string name="app_settings_security_app_permissions">Autorizzazioni app</string>
<string name="app_settings_security_app_permissions_summary">Controlla le autorizzazioni per la sincronizzazione</string>
<string name="app_settings_distrust_system_certs">Non ti fidare dei certificati di sistema</string>
<string name="app_settings_distrust_system_certs_on">Le CA di sistema e quelle aggiunte dall\'utente non sono affidabili</string>
<string name="app_settings_distrust_system_certs_off">Le CA di sistema e quelle aggiunte dall\'utente sono affidabili (raccomandato)</string>
<string name="app_settings_reset_certificates">Reimposta la fiducia in tutti i certificati</string>
<string name="app_settings_reset_certificates_summary">Reimposta la fiducia nei certificati aggiunti</string>
<string name="app_settings_reset_certificates_success">Sono stati cancellati tutti i certificati aggiunti</string>
<string name="app_settings_user_interface">Interfaccia utente</string>
<string name="app_settings_notification_settings">Impostazioni di notifica</string>
<string name="app_settings_notification_settings_summary">Gestisci i canali di notifica e le loro impostazioni</string>
<string name="app_settings_theme_title">Seleziona il tema</string>
<string-array name="app_settings_theme_names">
<item> Sistema predefinito </item>
<item> Luce </item>
<item> Buio </item>
</string-array>
<string name="app_settings_reset_hints">Reimposta i suggerimenti</string>
<string name="app_settings_reset_hints_summary">Riabilita i suggerimenti precedentemente disabilitati</string>
<string name="app_settings_reset_hints_success">I suggerimenti verranno mostrati</string>
<string name="app_settings_integration">Integrazione</string>
<string name="app_settings_tasks_provider">Funzioni dell\'applicazione</string>
<string name="app_settings_tasks_provider_none">Nessuna applicazione compatibile con e funzionalità trovata</string>
<!--AccountScreen-->
<string name="account_carddav">CardDAV</string>
<string name="account_caldav">CalDAV</string>
<string name="account_webcal">Webcal</string>
<string name="account_missing_permissions">Per sincronizzare questi dati sono richiesti permessi aggiuntivi.</string>
<string name="account_manage_permissions">Gestisci permessi</string>
<string name="account_synchronize_now">Sincronizza adesso</string>
<string name="account_settings">Impostazioni account</string>
<string name="account_rename">Rinomina account</string>
<string name="account_rename_new_name_description">Dati locali non salvati potrebbero venir persi. Dopo il cambio nome è necessaria la ri-sincronizzazione.</string>
<string name="account_rename_new_name">Nuovo nome account</string>
<string name="account_rename_rename">Rinomina</string>
<string name="account_rename_exists_already">Nome account già usato</string>
<string name="account_rename_couldnt_rename">Impossibile rinominare l\'account</string>
<string name="account_delete">Elimina account</string>
<string name="account_delete_confirmation_title">Cancellare l\'account?</string>
<string name="account_delete_confirmation_text">Tutte le copie locali delle rubriche, dei calendari e degli elenchi attività verranno eliminate.</string>
<string name="account_synchronize_this_collection">Sincronizza questa raccolta</string>
<string name="account_read_only">sola lettura</string>
<string name="account_calendar">calendario</string>
<string name="account_contacts">contatti</string>
<string name="account_journal">diario</string>
<string name="account_task_list">attività</string>
<string name="account_only_personal">Mostra solo personale</string>
<string name="account_refresh_collections">Aggiorna lista</string>
<string name="account_webcal_external_app">Sottoscrizioni al Webcal possono essere sincronizzate con applicazioni esterne.</string>
<string name="account_no_webcal_handler_found">Non ho trovato nessuna applicazione abilitata per Webcal</string>
<string name="account_install_icsx5">Installa ICSx⁵</string>
<!--AddAccountActivity-->
<string name="login_title">Aggiungi account</string>
<string name="login_generic_login">Login generico</string>
<string name="login_provider_login">Login del Provider</string>
<string name="login_continue">Continua</string>
<string name="login_login">Login</string>
<string name="login_type_email">Accedi con indirizzo email</string>
<string name="login_email_address">Indirizzo email</string>
<string name="login_email_address_error">È necessario un indirizzo email valido</string>
<string name="login_email_address_info"><![CDATA[Viene usato il dominio dell\'email come URL base. <a href="%s">I servizi sono individuati </a> usando record DNS e le URL well-known.]]></string>
<string name="login_password">Password</string>
<string name="login_password_hide">Nascondi password</string>
<string name="login_password_show">Mostra password</string>
<string name="login_type_url">Accedi con URL e nome utente</string>
<string name="login_user_name">Nome utente</string>
<string name="login_base_url">Base URL</string>
<string name="login_base_url_info"><![CDATA[La URL base viene controllata direttamente, ma <a href="%s">i servizi sono individuati anche </a> usando record DNS records e le URL well-known.]]></string>
<string name="login_select_certificate">Seleziona certificato</string>
<string name="login_add_account">Aggiungi account</string>
<string name="login_account_name">Nome account</string>
<string name="login_account_avoid_apostrophe">L\'uso degli apostrofi (\') potrebbe causare problemi su alcuni dispositivi.</string>
<string name="login_account_name_info">Inserisci il tuo indirizzo email come nome dell\'account in quanto Android userà il nome dell\'account nel campo ORGANIZER degli eventi creati. Non è possibile avere due account con nome uguale.</string>
<string name="login_account_contact_group_method">Metodo del contact group:</string>
<string name="login_account_name_required">Richiesto il nome dell\'account</string>
<string name="login_account_name_already_taken">Nome account già usato</string>
<string name="login_type_advanced">Login avanzato</string>
<string name="login_client_certificate_selected">Certificato client: %s</string>
<string name="login_no_certificate_found">Nessun certificato trovato</string>
<string name="login_install_certificate">Installa il certificato</string>
<string name="login_type_google">Contatti Google / Calendario</string>
<string name="login_google_account">Account Google</string>
<string name="login_google">Accedi con Google</string>
<string name="login_google_client_id">ID Client (facoltativo)</string>
<string name="login_google_client_limited_use"><![CDATA[%1$s è conforme alla <a href="%2$s">Google API Services User Data Policy</a>, incluso il Limited Use requirements.]]></string>
<string name="login_oauth_couldnt_obtain_auth_code">Non posso ottenere il codice di autorizzazione</string>
<string name="login_type_nextcloud">Nextcloud</string>
<string name="login_nextcloud_login_with_nextcloud">Accedi con Nextcloud</string>
<string name="login_nextcloud_login_flow_text">Questo aprirà la pagina di login di Nextcloud nel browser.</string>
<string name="login_nextcloud_login_flow_server_address">Indirizzo del server Nextcloud</string>
<string name="login_nextcloud_login_flow_sign_in">Iscriviti</string>
<string name="login_nextcloud_login_flow_no_login_url">Non posso ottenere l\'URL di login</string>
<string name="login_nextcloud_login_flow_no_login_data">Non posso ottenere i dati di login</string>
<string name="login_configuration_detection">Rilevazione configurazione</string>
<string name="login_querying_server">Attendere, invio richiesta al server…</string>
<string name="login_no_service">Impossibile trovare servizi CalDAV o CardDAV.</string>
<string name="login_no_service_info">L\'URL base non sembra essere un URL CalDAV/CardDAV accessibile e i servizi di individuazione hanno fallito.</string>
<string name="login_check_credentials">Controlla attentamente i dati di autenticazione (normalmente username e password).</string>
<string name="login_logs_available">Informazioni tecniche aggiuntive sono reperibili nei log.</string>
<string name="login_view_logs">Vedi i registri</string>
<!--AccountSettingsActivity-->
<string name="settings_sync">Sincronizzazione</string>
<string name="settings_sync_interval_contacts">Intervallo sincr. Contatti</string>
<string name="settings_sync_summary_manually">Solo manualmente</string>
<string name="settings_sync_summary_periodically" tools:ignore="PluralsCandidate">Ogni %d minuti e a seguito di ogni cambiamento locale</string>
<string name="settings_sync_interval_calendars">Intervallo sincr. calendari</string>
<string name="settings_sync_interval_tasks">Intervallo sincr. attività</string>
<string-array name="settings_sync_interval_names">
<item>Solo manualmente</item>
<item>Ogni 15 minuti</item>
<item>Ogni 30 minuti</item>
<item>Ogni ora</item>
<item>Ogni 2 ore</item>
<item>Ogni 4 ore</item>
<item>Una volta al giorno</item>
</string-array>
<string name="settings_sync_wifi_only">Sincr. solo tramite WiFi</string>
<string name="settings_sync_wifi_only_on">La sincronizzazione è limitata alle connessioni WiFi</string>
<string name="settings_sync_wifi_only_off">Il tipo di connessione non è preso in considerazione</string>
<string name="settings_sync_wifi_only_ssids">Restrizione SSID WiFi</string>
<string name="settings_sync_wifi_only_ssids_on">Sincronizzeremo solo oltre %s</string>
<string name="settings_sync_wifi_only_ssids_off">Verranno utilizzate tutte le connessioni WIFI </string>
<string name="settings_sync_wifi_only_ssids_message">Nomi (SSID) delle reti WiFi autorizzate separati da virgola (lascia vuoto per autorizzarle tutte)</string>
<string name="settings_sync_wifi_only_ssids_permissions_required">Le restrizioni del SSID WIFI richiedono ulteriori impostazioni</string>
<string name="settings_sync_wifi_only_ssids_permissions_action">Riuscire</string>
<string name="settings_ignore_vpns">La VPN richiede connessione internet</string>
<string name="settings_ignore_vpns_on">La VPN senza una connessione internet validata non è sufficiente per lanciare la sincronizzazione (raccomandato)</string>
<string name="settings_ignore_vpns_off">La VPN senza una connessione internet validata è sufficiente per lanciare la sincronizzazione</string>
<string name="settings_authentication">Autenticazione</string>
<string name="settings_username">Nome utente</string>
<string name="settings_new_password">Nuova password</string>
<string name="settings_password_summary">Aggiorna la password come sul tuo server.</string>
<string name="settings_certificate_alias">Certificato client</string>
<string name="settings_certificate_alias_empty">Nessun certificato disponibile o selezionato</string>
<string name="settings_certificate_install">Installa il certificato</string>
<string name="settings_caldav">CalDAV</string>
<string name="settings_sync_time_range_past">Limite di tempo per gli eventi trascorsi</string>
<string name="settings_sync_time_range_past_none">Verranno sincronizzati tutti gli eventi</string>
<plurals name="settings_sync_time_range_past_days">
<item quantity="one">Eventi più vecchi di un giorno saranno ignorati</item>
<item quantity="many">Eventi più vecchi di %d giorni saranno ignorati</item>
<item quantity="other">Eventi più vecchi di %d giorni saranno ignorati</item>
</plurals>
<string name="settings_sync_time_range_past_message">Eventi più vecchi di questo numero di giorni verranno ignorati(può anche essere 0). Lasciare in bianco per sincronizzare tutti gli eventi.</string>
<string name="settings_default_alarm">Promemoria predefinito</string>
<plurals name="settings_default_alarm_on">
<item quantity="one">Promemoria predefinito un minuto prima dell\'evento</item>
<item quantity="many">Promemoria predefinito %d minuti prima dell\'evento</item>
<item quantity="other">Promemoria predefinito %d minuti prima dell\'evento</item>
</plurals>
<string name="settings_default_alarm_off">Nessun promemoria di default creato</string>
<string name="settings_default_alarm_message">Indicare il numero di minuti che si desidera per il promemoria predefinito.
Lasciare vuoto per non creare un promemoria predefinito.</string>
<string name="settings_manage_calendar_colors">Cambia il colore del calendario</string>
<string name="settings_manage_calendar_colors_on">I colori del calendario sono resettati ad ogni sincronizzazione</string>
<string name="settings_manage_calendar_colors_off">I colori del calendario possono essere scelti da altre applicazioni</string>
<string name="settings_event_colors">Supporto colore dell\'evento</string>
<string name="settings_event_colors_on">I colori degli eventi sono sincronizzati</string>
<string name="settings_event_colors_off">I colori degli eventi non sono sicnronizzati</string>
<string name="settings_carddav">CardDAV</string>
<string name="settings_contact_group_method">Organizzazione dei gruppi di contatto</string>
<string-array name="settings_contact_group_method_entries">
<item>I gruppi sono vCards separate</item>
<item>I gruppi sono categorie per ogni contatto</item>
</string-array>
<!--CreateAddressBookScreen, CreateCalendarScreen-->
<string name="create_addressbook">Crea rubrica</string>
<string name="create_addressbook_maybe_not_supported">La creazione di rubriche tramitte CardDAV potrebbe non essere supportata dal server.</string>
<string name="create_calendar">Crea calendario</string>
<string name="create_calendar_time_zone_none"></string>
<string name="create_calendar_type">Possibili voci del calendario</string>
<string name="create_calendar_type_vevent">Eventi</string>
<string name="create_calendar_type_vtodo">Attività</string>
<string name="create_calendar_type_vjournal">Note / diario</string>
<string name="create_calendar_maybe_not_supported">La creazione do calendari tramite CalDAV potrebbe non essere supportata dal server.</string>
<string name="create_collection_color">Colore</string>
<string name="create_collection_display_name">Titolo</string>
<string name="create_collection_home_set">Percorso di archiviazione</string>
<string name="create_collection_create">Crea</string>
<!--CollectionScreen-->
<string name="collection_datatype_contacts">contatti</string>
<string name="collection_datatype_tasks">attività</string>
<string name="collection_delete">Elimina raccolta</string>
<string name="collection_delete_warning">Questa raccolta (%s) e tutti i suoi dati saranno rimossi definitivamente, sia localmente che sul server.</string>
<string name="collection_synchronization">Sincronizzazione</string>
<string name="collection_synchronization_on">Sincronizzazione attivata</string>
<string name="collection_synchronization_off">Sincronizzazione disattivata</string>
<string name="collection_read_only">Sola lettura</string>
<string name="collection_read_only_by_server">Sola lettura (dal server)</string>
<string name="collection_read_only_forced">Sola lettura (locale)</string>
<string name="collection_read_write">Lettura/scrittura</string>
<string name="collection_title">Titolo</string>
<string name="collection_description">Descrizione</string>
<string name="collection_owner">Proprietario</string>
<string name="collection_push_support">Supporto push</string>
<string name="collection_last_sync">Ultima sincronizzazione %s</string>
<string name="collection_url">Indirizzo (URL)</string>
<!--debugging and DebugInfoActivity-->
<string name="debug_info_title">Informazioni di debug</string>
<string name="debug_info_archive_caption">Archivio ZIP</string>
<string name="debug_info_archive_subtitle">Contiene informazioni sui debug e sugli accessi</string>
<string name="debug_info_archive_text">Condividi l\'archivio per trasferirlo ad un computer, per inviarlo tramite email o per fissarlo ad un ticket di supporto.</string>
<string name="debug_info_archive_share">Condividi l\'archivio</string>
<string name="debug_info_attached">Informazioni sul debug fissate a questo messaggio (richiede un supporto di fissaggio dell\'applicazione di supporto). </string>
<string name="debug_info_http_error">Errore HTTP</string>
<string name="debug_info_server_error">Errore del Server</string>
<string name="debug_info_webdav_error">Errore WebDAV</string>
<string name="debug_info_io_error">Errore I/O</string>
<string name="debug_info_view_details">Vedi dettagli</string>
<string name="debug_info_subtitle">Sono state raccolte informazioni di debug</string>
<string name="debug_info_involved_caption">Fonti coinvolte</string>
<string name="debug_info_involved_subtitle">Collegate con il problema</string>
<string name="debug_info_involved_remote">Fonti remote:</string>
<string name="debug_info_involved_local">Fonti locali:</string>
<string name="debug_info_logs_caption">Registri</string>
<string name="debug_info_logs_subtitle">Sono disponibili registri verbali</string>
<string name="debug_info_logs_view">Vedi i registri</string>
<string name="debug_info_copy_remote_url">Copia URL</string>
<!--ExceptionInfoFragment-->
<string name="exception">Si è verificato un errore.</string>
<string name="exception_httpexception">Si è verificato un errore HTTP.</string>
<string name="exception_ioexception">Si è verificato un errore di I/O.</string>
<string name="exception_show_details">Mostra dettagli</string>
<!--WebDAV accounts-->
<string name="webdav_mounts_title">Installazioni WebDAV</string>
<string name="webdav_mounts_quota_used_available">Quantità utilizzata: %1$s / disponibile: %2$s</string>
<string name="webdav_mounts_share_content">Condividi i contenuti</string>
<string name="webdav_mounts_unmount">Disinstallazioni</string>
<string name="webdav_add_mount_title">Aggiungi installazioni WedDAV</string>
<string name="webdav_mounts_empty">Accedi direttamente ai tuoi file nel cloud aggiungendo un supporto WebDAV!</string>
<string name="webdav_add_mount_display_name">Nome del display</string>
<string name="webdav_add_mount_url">URL WebDVA</string>
<string name="webdav_add_mount_url_invalid">URL non valido</string>
<string name="webdav_add_mount_authentication">Autenticazione</string>
<string name="webdav_add_mount_username">Nome utente</string>
<string name="webdav_add_mount_password">Password</string>
<string name="webdav_add_mount_add">Aggiungi installazioni</string>
<string name="webdav_add_mount_no_support">Nessun servizio WebDAV a questo URL</string>
<string name="webdav_remove_mount_title">Rimuovi punto di mont</string>
<string name="webdav_remove_mount_text">I dettagli della connessione saranno perduti, ma nessun file verrà cancellato.</string>
<string name="webdav_notification_access">File di accesso WebDAV</string>
<string name="webdav_notification_download">File di download WebDAV</string>
<string name="webdav_notification_upload">Caricare file WebDAV</string>
<string name="webdav_provider_root_title">Installazione WebDAV</string>
<!--sync-->
<string name="sync_error_permissions">Autorizzazioni DAVx⁵</string>
<string name="sync_error_permissions_text">Autorizzazioni addizionali richieste</string>
<string name="sync_error_tasks_too_old">%s troppo vecchio</string>
<string name="sync_error_tasks_required_version">Versione minima richiesta %1$s</string>
<string name="sync_error_authentication_failed">Autenticazione fallita (controlla credenziali login)</string>
<string name="sync_error_io">Errore di rete o di I/O %s</string>
<string name="sync_error_http_dav">Errore server HTTP %s</string>
<string name="sync_error_local_storage">Errore di archiviazione locale %s</string>
<string name="sync_invalid_contact">Contatto non valido ricevuto dal server</string>
<string name="sync_invalid_event">Evento non valido ricevuto dal server</string>
<string name="sync_invalid_task">Attività non valida ricevuta dal server</string>
<string name="sync_invalid_resources_ignoring">Una o più risorse non valide ignorate</string>
<!--widgets-->
<string name="widget_sync_all">Sincronizza tutto</string>
<string name="widget_sync_all_accounts">Sincronizzazione di tutti gli account</string>
<!--cert4android-->
</resources>

View File

@@ -1,486 +0,0 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources xmlns:tools="http://schemas.android.com/tools">
<!--common strings-->
<string name="account_invalid">Contul nu (mai) există</string>
<string name="account_title_address_book">Agenda DAVx⁵</string>
<string name="account_prefs_use_app">Nu schimba contul aici! Utilizează direct aplicația pentru a gestiona conturile în schimb.</string>
<string name="dialog_delete">Șterge</string>
<string name="dialog_remove">Elimină</string>
<string name="dialog_deny">Anulează</string>
<string name="dialog_enable">Activează</string>
<string name="field_required">Acest câmp este obligatoriu</string>
<string name="help">Ajutor</string>
<string name="navigate_up">Navigare în sus</string>
<string name="options_menu">Meniul Opțiuni</string>
<string name="share">Distribuie</string>
<string name="sync_started">Sincronizare începută/pusă în coadă</string>
<string name="database_destructive_migration_title">Bază de date deteriorată</string>
<string name="database_destructive_migration_text">Toate conturile au fost eliminate local.</string>
<string name="notification_channel_debugging">Depanare</string>
<string name="notification_channel_general">Alte mesaje importante</string>
<string name="notification_channel_status">Mesaje de stare cu prioritate redusă</string>
<string name="notification_channel_sync">Sincronizare</string>
<string name="notification_channel_sync_errors">Erori de sincronizare</string>
<string name="notification_channel_sync_errors_desc">Erori importante care opresc sincronizarea, cum ar fi răspunsurile neașteptate ale serverului</string>
<string name="notification_channel_sync_warnings">Avertismente de sincronizare</string>
<string name="notification_channel_sync_warnings_desc">Probleme de sincronizare non-fatale, cum ar fi anumite fișiere nevalide</string>
<string name="notification_channel_sync_io_errors">Erori de rețea și I/O</string>
<string name="notification_channel_sync_io_errors_desc">Expirare, probleme de conexiune etc. (adesea temporare)</string>
<!--IntroActivity-->
<string name="intro_slogan1">Datele tale. Alegerea ta.</string>
<string name="intro_slogan2">Preia controlul.</string>
<string name="intro_battery_title">Intervale regulate de sincronizare</string>
<string name="intro_battery_text">Pentru sincronizare la intervale regulate, %s trebuie să aibă voie să ruleze în fundal. În caz contrar, Android poate întrerupe sincronizarea în orice moment.</string>
<string name="intro_battery_dont_show">Nu am nevoie de intervale regulate de sincronizare.*</string>
<string name="intro_autostart_title">Compatibilitate %s </string>
<string name="intro_autostart_text">Firmware-ul specific vendorului poate bloca sincronizarea. Dacă ești afectat, poți rezolva acest lucru manual.</string>
<string name="intro_autostart_dont_show">Am făcut setările necesare. Nu-mi mai aminti.*</string>
<string name="intro_leave_unchecked">* Lasă nebifat pentru a fi reamintit mai târziu. Poate fi resetat în setările aplicației / %s.</string>
<string name="intro_more_info">Mai multe informații</string>
<string name="intro_tasks_jtx">Placă de bază jtx</string>
<string name="intro_tasks_jtx_info"><![CDATA[Acceptă sincronizarea sarcinilor, jurnalelor și notelor.]]></string>
<string name="intro_tasks_title">Suport pentru sarcini</string>
<string name="intro_tasks_text1">Dacă sarcinile sunt acceptate de server, acestea pot fi sincronizate cu o aplicație de sarcini acceptată:</string>
<string name="intro_tasks_opentasks">OpenTasks</string>
<string name="intro_tasks_opentasks_info">Nu pare a mai fi dezvoltat nu este recomandat.</string>
<string name="intro_tasks_tasks_org">Tasks.org</string>
<string name="intro_tasks_tasks_org_info"><![CDATA[Unele caracteristici <a href="https://www.davx5.com/faq/tasks/advanced-task-features">nu sunt acceptate</a>.]]></string>
<string name="intro_tasks_no_app_store">Nu există un magazin de aplicații disponibil</string>
<string name="intro_tasks_dont_show">Nu am nevoie de suport pentru sarcini.*</string>
<string name="intro_open_source_title">Software cu sursă deschisă</string>
<string name="intro_open_source_text">Ne bucurăm că utilizezi %s, care este un software open-source. Dezvoltarea, întreținerea și suportul sunt o muncă grea. Ia în considerare contribuția (există mai multe moduri) sau o donație. Ar fi foarte apreciat!</string>
<string name="intro_open_source_details">Cum să contribui/donezi</string>
<string name="intro_open_source_dont_show">Nu-mi aminti</string>
<plurals name="intro_open_source_dont_show_months">
<item quantity="one">%d lună</item>
<item quantity="few">%d luni</item>
<item quantity="other">%d luni</item>
</plurals>
<string name="intro_next">Înainte</string>
<!--PermissionsActivity-->
<string name="permissions_title">Permisiuni</string>
<string name="permissions_text">%s necesită permisiuni pentru a funcționa corect.</string>
<string name="permissions_all_title">Toate cele de mai jos</string>
<string name="permissions_all_status_off">Utilizează aceasta pentru a activa toate funcțiile (recomandat)</string>
<string name="permissions_all_status_on">Toate permisiunile sunt acordate</string>
<string name="permissions_contacts_title">Permisiuni Contacte</string>
<string name="permissions_contacts_status_off">Fără sincronizare de contacte (nu este recomandat)</string>
<string name="permissions_contacts_status_on">Este posibilă sincronizarea contactelor</string>
<string name="permissions_calendar_title">Permisiuni pentru calendar</string>
<string name="permissions_calendar_status_off">Fără sincronizare calendar (nu este recomandat)</string>
<string name="permissions_calendar_status_on">Sincronizarea calendarului este posibilă</string>
<string name="permissions_notification_title">Permisiune de notificare</string>
<string name="permissions_notification_status_off">Notificări dezactivate (nu este recomandat)</string>
<string name="permissions_notification_status_on">Notificări activate</string>
<string name="permissions_jtx_title">Permisiuni pentru jtx Board</string>
<string name="permissions_opentasks_title">Permisiuni OpenTasks</string>
<string name="permissions_tasksorg_title">Permisiuni pentru sarcini</string>
<string name="permissions_tasks_status_off">Nicio sincronizare a sarcinilor</string>
<string name="permissions_tasks_status_on">Este posibilă sincronizarea sarcinilor</string>
<string name="permissions_autoreset_title">Păstrează permisiunile</string>
<string name="permissions_autoreset_status_off">Permisiunile pot fi resetate automat (nu este recomandat)</string>
<string name="permissions_autoreset_status_on">Permisiunile nu vor fi resetate automat</string>
<string name="permissions_autoreset_instruction">Clic pe Permisiuni &gt; debifează „Elimină permisiunile dacă aplicația nu este utilizată”</string>
<string name="permissions_app_settings_hint">Dacă un comutator nu funcționează, utilizează setările/permisiunile aplicației.</string>
<string name="permissions_app_settings">Setările aplicației</string>
<!--WifiPermissionsActivity-->
<string name="wifi_permissions_label">Permisiuni SSID WiFi</string>
<string name="wifi_permissions_intro">Pentru a putea accesa numele actual WiFi (SSID), trebuie îndeplinite următoarele condiții:</string>
<string name="wifi_permissions_location_permission">Permisiune de locație precisă</string>
<string name="wifi_permissions_location_permission_on">Permisiunea de locație acordată</string>
<string name="wifi_permissions_location_permission_off">Permisiunea de locație refuzată</string>
<string name="wifi_permissions_background_location_permission">Permisiunea de locație în fundal</string>
<string name="wifi_permissions_background_location_permission_label">Permite tot timpul</string>
<string name="wifi_permissions_background_location_permission_on">Permisiunea locației setată la: %s</string>
<string name="wifi_permissions_background_location_permission_off">Permisiunea de locație nu este setată la: %s</string>
<string name="wifi_permissions_background_location_disclaimer">%s folosește datele locației (doar WiFi SSID) numai pentru a restricționa sincronizarea la un anumit SSID WiFi. Acest lucru se va întâmpla chiar și atunci când sincronizarea rulează în fundal.</string>
<string name="wifi_permissions_background_location_disclaimer2">Toate datele locației (doar WiFi SSID) sunt folosite doar local și nu sunt trimise nicăieri.</string>
<string name="wifi_permissions_location_enabled">Locația este întotdeauna activată</string>
<string name="wifi_permissions_location_enabled_on">Serviciul de localizare este activat</string>
<string name="wifi_permissions_location_enabled_off">Serviciul de localizare este dezactivat</string>
<!--AboutActivity-->
<string name="about_translations">Traduceri</string>
<string name="about_libraries">Biblioteci</string>
<string name="about_version">Versiune %1$s (%2$d)</string>
<string name="about_copyright">© Ricki Hirner, Bernhard Stockmann (inginerie web bitfire GmbH) și contribuitori</string>
<string name="about_license_info_no_warranty">Acest program vine cu ABSOLUT NICIO GARANȚIE. Este software gratuit și ești binevenit să îl redistribui în anumite condiții.</string>
<!--global settings-->
<string name="logging_couldnt_create_file">Nu s-a putut crea fișierul jurnal</string>
<string name="logging_notification_text">Acum se înregistrează toate activitățile %s</string>
<string name="logging_notification_view_share">Vizualizare/distribuire</string>
<string name="logging_notification_disable">Dezactivează</string>
<!--AccountsScreen-->
<string name="navigation_drawer_subtitle">Adaptor de sincronizare CalDAV/CardDAV</string>
<string name="navigation_drawer_about">Despre / Licență</string>
<string name="navigation_drawer_beta_feedback">Feedback beta</string>
<string name="install_browser">Instalează un browser web</string>
<string name="navigation_drawer_settings">Setări</string>
<string name="navigation_drawer_news_updates">Știri și actualizări</string>
<string name="navigation_drawer_tools">Instrumente</string>
<string name="navigation_drawer_external_links">Link-uri externe</string>
<string name="navigation_drawer_website">Pagină web</string>
<string name="navigation_drawer_manual">Manual</string>
<string name="navigation_drawer_faq">Întrebări frecvente</string>
<string name="navigation_drawer_managed">Pentru organizații</string>
<string name="navigation_drawer_community">Comunitate</string>
<string name="navigation_drawer_support_project">Susține proiectul</string>
<string name="navigation_drawer_contribute">Cum să contribui</string>
<string name="navigation_drawer_privacy_policy">Politica de confidențialitate</string>
<string name="account_list_welcome">Bun venit la DAVx⁵!</string>
<string name="account_list_empty">Conectează-te la server și păstrează calendarele și contactele sincronizate.</string>
<string name="accounts_sync_all">Sincronizează toate conturile</string>
<!--Sync warnings-->
<string name="sync_warning_no_notification_permission">Notificări dezactivate. Nu vei fi notificat despre erorile de sincronizare.</string>
<string name="sync_warning_no_internet">Sincronizarea automată nu este activă (fără conexiune la internet verificată).</string>
<string name="sync_warning_manage_connections">Gestionează conexiunile</string>
<string name="sync_warning_datasaver_enabled">Economizorul de date este activat. Sincronizarea în fundal este restricționată.</string>
<string name="sync_warning_manage_datasaver">Gestionează economizorul de date</string>
<string name="sync_warning_battery_saver_enabled">Economisirea bateriei este activată. Sincronizarea poate fi restricționată.</string>
<string name="sync_warning_manage_battery_saver">Gestionează economisirea bateriei</string>
<string name="sync_warning_low_storage">Spațiu de depozitare redus. Android nu va sincroniza modificările locale imediat, ci în timpul următoarei sincronizări obișnuite.</string>
<string name="sync_warning_manage_storage">Gestionează stocarea</string>
<string name="sync_warning_calendar_storage_disabled_title">Furnizorul de calendar lipsește</string>
<string name="sync_warning_calendar_storage_disabled_description">Ai dezactivat aplicația de sistem „Stocare Calendar”?</string>
<string name="sync_warning_contacts_storage_disabled_title">Furnizorul de contacte lipsește</string>
<string name="sync_warning_contacts_storage_disabled_description">Ai dezactivat aplicația de sistem „Stocare Contacte”?</string>
<string name="sync_warning_manage_apps">Gestionează aplicațiile</string>
<!--RefreshCollectionsWorker-->
<string name="refresh_collections_worker_refresh_failed">Detectarea serviciului a eșuat</string>
<string name="refresh_collections_worker_refresh_couldnt_refresh">Lista de colecții nu a putut fi actualizată</string>
<!--Foreground service used by WorkManager on Android <12-->
<string name="foreground_service_notify_title">Rulează în prim-plan</string>
<string name="foreground_service_notify_text">Pe unele dispozitive, acest lucru este necesar pentru sincronizarea automată.</string>
<!--AppSettingsActivity-->
<string name="app_settings">Setări</string>
<string name="app_settings_debug">Depanare</string>
<string name="app_settings_show_debug_info">Afișează informațiile de depanare</string>
<string name="app_settings_show_debug_info_details">Vizualizează/partajează detaliile de configurare și jurnalele</string>
<string name="app_settings_logging">Jurnalizare detaliată</string>
<string name="app_settings_logging_on">Înregistrarea este activă. Poți vizualiza jurnalele ca parte a informațiilor de depanare.</string>
<string name="app_settings_logging_off">Înregistrarea este dezactivată</string>
<string name="app_settings_battery_optimization">Optimizarea bateriei</string>
<string name="app_settings_battery_optimization_exempted">Aplicația este exclusă (recomandat)</string>
<string name="app_settings_battery_optimization_optimized">Se aplică restricții pentru baterie (nu este recomandat)</string>
<string name="app_settings_connection">Conexiune</string>
<string name="app_settings_proxy">Tip proxy</string>
<string-array name="app_settings_proxy_types">
<item>Implicit</item>
<item>Fără proxy</item>
<item>HTTP</item>
<item>SOCKS (pentru Orbot)</item>
</string-array>
<string name="app_settings_proxy_host">Nume gazdă proxy</string>
<string name="app_settings_proxy_port">Port proxy</string>
<string name="app_settings_security">Securitate</string>
<string name="app_settings_security_app_permissions">Permisiunile aplicației</string>
<string name="app_settings_security_app_permissions_summary">Examinează permisiunile necesare pentru sincronizare</string>
<string name="app_settings_distrust_system_certs">Nu avea încredere în certificatele de sistem</string>
<string name="app_settings_distrust_system_certs_on">CA de sistem și de utilizator nu vor fi de încredere</string>
<string name="app_settings_distrust_system_certs_off">CA de sistem și de utilizator vor fi de încredere (recomandat)</string>
<string name="app_settings_distrust_system_certs_dialog_message">Dacă această setare este activă, certificatele de sistem nu sunt considerate ca fiind de încredere. Aceasta înseamnă că va trebui să accepți manual fiecare certificat (de asemenea, atunci când serverul își reînnoiește certificatul) sau configurarea contului și sincronizarea nu va funcționa.</string>
<string name="app_settings_reset_certificates">Resetează certificatele de (ne)încredere</string>
<string name="app_settings_reset_certificates_summary">Resetează încrederea tuturor certificatelor personalizate</string>
<string name="app_settings_reset_certificates_success">Toate certificatele personalizate au fost șterse</string>
<string name="app_settings_user_interface">Interfață de utilizator</string>
<string name="app_settings_notification_settings">Setări de notificare</string>
<string name="app_settings_notification_settings_summary">Gestionează canalele de notificare și setările acestora</string>
<string name="app_settings_theme_title">Selectează tema</string>
<string-array name="app_settings_theme_names">
<item>Ca în sistem</item>
<item>Luminoasă</item>
<item>Întunecată</item>
</string-array>
<string name="app_settings_reset_hints">Resetează sugestiile</string>
<string name="app_settings_reset_hints_summary">Reactivează sugestiile care au fost respinse anterior</string>
<string name="app_settings_reset_hints_success">Toate sugestiile vor fi afișate din nou</string>
<string name="app_settings_integration">Integrare</string>
<string name="app_settings_tasks_provider">Aplicația de sarcini</string>
<string name="app_settings_tasks_provider_none">Nu a fost găsită nicio aplicație de sarcini compatibilă</string>
<string name="app_settings_unifiedpush">UnifiedPush (experimental)</string>
<string name="app_settings_unifiedpush_disable">Nimic (dezactivare Push)</string>
<string name="app_settings_unifiedpush_choose_distributor">Alege un distribuitor</string>
<string name="app_settings_unifiedpush_no_distributor">Nu este instalat un distribuitor push</string>
<string name="app_settings_unifiedpush_no_endpoint">Niciun punct final configurat</string>
<string name="app_settings_unifiedpush_ready">Gata să primească mesaje push peste %s</string>
<string name="app_settings_unifiedpush_distributor_fcm">FCM (Google Play)</string>
<string name="app_settings_unifiedpush_encrypted">Mesajele push sunt întotdeauna criptate.</string>
<!--AccountScreen-->
<string name="account_invalid_account">Contul a fost eliminat</string>
<string name="account_carddav">CardDAV</string>
<string name="account_caldav">CalDAV</string>
<string name="account_webcal">Webcal</string>
<string name="account_missing_permissions">Sunt necesare permisiuni suplimentare pentru a sincroniza aceste colecții.</string>
<string name="account_manage_permissions">Gestionează permisiunile</string>
<string name="account_synchronize_now">Sincronizează acum</string>
<string name="account_settings">Setările contului</string>
<string name="account_rename">Redenumește contul</string>
<string name="account_rename_new_name_description">Datele locale nesalvate pot fi respinse. Resincronizarea este necesară după redenumire.</string>
<string name="account_rename_new_name">Nume cont nou</string>
<string name="account_rename_rename">Redenumește</string>
<string name="account_rename_exists_already">Numele contului este deja luat</string>
<string name="account_rename_couldnt_rename">Nu s-a putut redenumi contul</string>
<string name="account_delete">Șterge contul</string>
<string name="account_delete_confirmation_title">Chiar ștergi contul?</string>
<string name="account_delete_confirmation_text">Toate copiile locale ale agendelor, calendarelor și listelor de sarcini vor fi șterse.</string>
<string name="account_synchronize_this_collection">sincronizează această colecție</string>
<string name="account_read_only">numai pentru citire</string>
<string name="account_calendar">calendar</string>
<string name="account_contacts">contacte</string>
<string name="account_journal">jurnal</string>
<string name="account_task_list">sarcini</string>
<string name="account_only_personal">Afișează numai personal</string>
<string name="account_refresh_collections">Actualizează lista</string>
<string name="account_webcal_external_app">Abonamentele Webcal pot fi sincronizate cu aplicații externe.</string>
<string name="account_no_webcal_handler_found">Nu a fost găsită nicio aplicație compatibilă cu Webcal</string>
<string name="account_install_icsx5">Instalează ICSx⁵</string>
<!--AddAccountActivity-->
<string name="login_title">Adaugă contul</string>
<string name="login_privacy_hint"><![CDATA[Toate datele vor fi transferate numai între server și dispozitiv. %1$s nu le voi trimite altundeva. Vezi <a href="%2$s">Politica de confidențialitate</a>.]]></string>
<string name="login_generic_login">Autentificare generică</string>
<string name="login_provider_login">Autentificare specifică furnizorului</string>
<string name="login_continue">Continuă</string>
<string name="login_login">Autentificare</string>
<string name="login_type_email">Conectează-te cu adresa de e-mail</string>
<string name="login_email_address">Adresa de e-mail</string>
<string name="login_email_address_error">Este necesară o adresă de e-mail validă</string>
<string name="login_email_address_info"><![CDATA[Domeniul de e-mail este folosit ca URL de bază. <a href="%s">Serviciile sunt descoperite</a> folosind înregistrări DNS și adrese URL bine-cunoscute.]]></string>
<string name="login_password">Parolă</string>
<string name="login_password_hide">Ascunde parola</string>
<string name="login_password_show">Afișează parola</string>
<string name="login_password_optional">Parolă (opțional)</string>
<string name="login_type_url">Conecteează-te cu adresa URL și numele de utilizator</string>
<string name="login_user_name">Nume de utilizator</string>
<string name="login_user_name_optional">Nume de utilizator (opțional)</string>
<string name="login_base_url">Adresa URL de bază</string>
<string name="login_base_url_info"><![CDATA[Adresa URL de bază va fi verificată direct, dar <a href="%s">serviciile sunt de asemenea descoperite</a> folosind înregistrări DNS și adrese URL bine-cunoscute.]]></string>
<string name="login_select_certificate">Selectează certificatul</string>
<string name="login_add_account">Adaugă contul</string>
<string name="login_account_name">Nume de cont</string>
<string name="login_account_avoid_apostrophe">Utilizarea apostrofelor (\') pare să cauzeze probleme pe unele dispozitive.</string>
<string name="login_account_name_info">Utilizează adresa de e-mail ca nume de cont, deoarece Android va folosi numele contului ca câmp ORGANIZATOR pentru evenimentele pe care le creezi. Nu poți avea două conturi cu același nume.</string>
<string name="login_account_contact_group_method">Metoda de grupare a contactelor:</string>
<string name="login_account_name_required">Numele contului este necesar</string>
<string name="login_account_name_already_taken">Numele contului este deja luat</string>
<string name="login_account_not_added">Contul nu a putut fi adăugat</string>
<string name="login_finish">Finalizează</string>
<string name="login_type_advanced">Autentificare avansată</string>
<string name="login_no_client_certificate_optional">Fără certificat de client (opțional)</string>
<string name="login_client_certificate_selected">Certificat de client: %s</string>
<string name="login_no_certificate_found">Nu a fost găsit niciun certificat</string>
<string name="login_install_certificate">Instalare certificat</string>
<string name="login_fastmail">Fastmail</string>
<string name="login_fastmail_account">Cont Fastmail</string>
<string name="login_fastmail_sign_in">Conectează-te cu Fastmail</string>
<string name="login_type_google">Contacte Google / Calendar</string>
<string name="login_google_account">Cont Google</string>
<string name="login_google">Conectează-te cu Google</string>
<string name="login_google_client_id">ID client (opțional)</string>
<string name="login_google_client_privacy_policy"><![CDATA[%1$s transferă datele din Agendă Google și din Calendar numai pentru sincronizare cu acest dispozitiv. Vezi <a href="%2$s">Politica de confidențialitate</a> pentru detalii.]]></string>
<string name="login_google_client_limited_use"><![CDATA[%1$s respectă <a href="%2$s">Politica privind datele utilizatorilor serviciilor API Google</a>, inclusiv cerințele de utilizare limitată.]]></string>
<string name="login_oauth_couldnt_obtain_auth_code">Nu s-a putut obține codul de autorizare</string>
<string name="login_type_nextcloud">Nextcloud</string>
<string name="login_nextcloud_login_with_nextcloud">Conectare cu Nextcloud</string>
<string name="login_nextcloud_login_flow_text">Aceasta va porni fluxul de conectare Nextcloud într-un browser web.</string>
<string name="login_nextcloud_login_flow_server_address">Adresa serverului Nextcloud</string>
<string name="login_nextcloud_login_flow_sign_in">Conectare</string>
<string name="login_nextcloud_login_flow_no_login_url">Nu s-a putut obține adresa URL de conectare</string>
<string name="login_nextcloud_login_flow_no_login_data">Nu s-au putut obține datele de conectare</string>
<string name="login_configuration_detection">Detectarea configurației</string>
<string name="login_querying_server">Se interoghează serverul…</string>
<string name="login_no_service">Nu s-a putut găsi serviciul CalDAV sau CardDAV.</string>
<string name="login_no_service_info">Adresa URL de bază nu pare să fie o adresă URL CalDAV/CardDAV accesibilă, iar detectarea serviciului nu a avut succes.</string>
<string name="login_see_tested_services"><![CDATA[Consultă manualul furnizorului de servicii, <a href="%s">lista de servicii testate</a> și adresele lor URL de bază.]]></string>
<string name="login_check_credentials">Verifică, de asemenea, și autentificarea (de obicei, numele de utilizator și parola).</string>
<string name="login_logs_available">Informații tehnice suplimentare sunt disponibile în jurnale.</string>
<string name="login_view_logs">Vezi jurnalele</string>
<!--AccountSettingsActivity-->
<string name="settings_sync">Sincronizare</string>
<string name="settings_sync_interval_contacts">Interval de sincronizare a contactelor</string>
<string name="settings_sync_summary_manually">Doar manual</string>
<string name="settings_sync_summary_periodically" tools:ignore="PluralsCandidate">La fiecare %d minute + imediat la modificări locale</string>
<string name="settings_sync_interval_calendars">Interval de sincronizare a calendarelor</string>
<string name="settings_sync_interval_tasks">Interval de sincronizare a sarcinilor</string>
<string-array name="settings_sync_interval_names">
<item>Doar manual</item>
<item>La fiecare 15 minute</item>
<item>La fiecare 30 de minute</item>
<item>La fiecare oră</item>
<item>La fiecare 2 ore</item>
<item>La fiecare 4 ore</item>
<item>O dată pe zi</item>
</string-array>
<string name="settings_sync_wifi_only">Sincronizare numai prin WiFi</string>
<string name="settings_sync_wifi_only_on">Sincronizarea este limitată la conexiunile WiFi</string>
<string name="settings_sync_wifi_only_off">Tipul de conexiune nu este luat în considerare</string>
<string name="settings_sync_wifi_only_ssids">Restricție SSID WiFi</string>
<string name="settings_sync_wifi_only_ssids_on">Se va sincroniza numai prin %s</string>
<string name="settings_sync_wifi_only_ssids_off">Toate conexiunile WiFi vor fi utilizate</string>
<string name="settings_sync_wifi_only_ssids_message">Nume separate prin virgulă (SSID) ale rețelelor WiFi permise (lasă necompletat pentru toate)</string>
<string name="settings_sync_wifi_only_ssids_permissions_required">Restricția SSID WiFi necesită setări suplimentare</string>
<string name="settings_sync_wifi_only_ssids_permissions_action">Gestionează</string>
<string name="settings_ignore_vpns">VPN necesită internetul de bază</string>
<string name="settings_ignore_vpns_on">VPN fără conexiune validată la Internet nu este suficient pentru a rula sincronizarea (recomandat)</string>
<string name="settings_ignore_vpns_off">VPN fără conexiune validată la Internet este suficient pentru a rula sincronizarea</string>
<string name="settings_authentication">Autentificare</string>
<string name="settings_username">Nume de utilizator</string>
<string name="settings_password">Parolă sau parola aplicației</string>
<string name="settings_app_password_hint"><![CDATA[Poate preferi să utilizezi <a href="%1$s">parola aplicației</a>.]]></string>
<string name="settings_new_password">Parolă nouă</string>
<string name="settings_password_summary">Actualizează parola în funcție de server.</string>
<string name="settings_reauthorize_oauth">Autorizează din nou (OAuth)</string>
<string name="settings_reauthorize_oauth_summary">Utilizează atunci când accesul a fost revocat</string>
<string name="settings_reauthorize_oauth_success">Autorizare cu succes</string>
<string name="settings_certificate_alias">Certificat de client</string>
<string name="settings_certificate_alias_empty">Niciun certificat disponibil sau selectat</string>
<string name="settings_certificate_install">Instalare certificat</string>
<string name="settings_caldav">CalDAV</string>
<string name="settings_sync_time_range_past">Limită de timp pentru evenimentele din trecut</string>
<string name="settings_sync_time_range_past_none">Toate evenimentele vor fi sincronizate</string>
<plurals name="settings_sync_time_range_past_days">
<item quantity="one">Evenimentele cu mai mult de o zi în trecut vor fi ignorate</item>
<item quantity="few">Evenimentele cu peste %d zile în trecut vor fi ignorate</item>
<item quantity="other">Evenimentele cu peste %d zile în trecut vor fi ignorate</item>
</plurals>
<string name="settings_sync_time_range_past_message">Evenimentele care depășesc acest număr de zile în trecut vor fi ignorate (poate fi 0). Lasă necompletat pentru a sincroniza toate evenimentele.</string>
<string name="settings_default_alarm">Memento implicit</string>
<plurals name="settings_default_alarm_on">
<item quantity="one">Memento implicit cu un minut înainte de eveniment</item>
<item quantity="few">Memento implicit cu %d minute înainte de eveniment</item>
<item quantity="other">Memento implicit cu %d minute înainte de eveniment</item>
</plurals>
<string name="settings_default_alarm_off">Nu sunt create mementouri implicite</string>
<string name="settings_default_alarm_message">Dacă vor fi create memento-uri implicite pentru evenimente fără memento: numărul dorit de minute înainte de eveniment. Lasă necompletat pentru a dezactiva memento-urile implicite.</string>
<string name="settings_manage_calendar_colors">Gestionează culorile calendarului</string>
<string name="settings_manage_calendar_colors_on">Culorile calendarului sunt resetate la fiecare sincronizare</string>
<string name="settings_manage_calendar_colors_off">Culorile calendarului pot fi setate de alte aplicații</string>
<string name="settings_event_colors">Suport pentru culoarea evenimentului</string>
<string name="settings_event_colors_on">Culorile evenimentelor sunt sincronizate</string>
<string name="settings_event_colors_off">Culorile evenimentelor nu sunt sincronizate</string>
<string name="settings_carddav">CardDAV</string>
<string name="settings_contact_group_method">Metoda de grupare a contactelor</string>
<string-array name="settings_contact_group_method_entries">
<item>Grupurile sunt vCard-uri separate</item>
<item>Grupurile sunt categorii per-contact</item>
</string-array>
<!--CreateAddressBookScreen, CreateCalendarScreen-->
<string name="create_addressbook">Creează agendă de adrese</string>
<string name="create_addressbook_maybe_not_supported">Crearea agendei prin CardDAV poate să nu fie acceptată de server.</string>
<string name="create_calendar">Creează un calendar</string>
<string name="create_calendar_time_zone_optional">Fus orar implicit (opțional)</string>
<string name="create_calendar_time_zone_none"></string>
<string name="create_calendar_type">Posibile intrări din calendar</string>
<string name="create_calendar_type_vevent">Evenimente</string>
<string name="create_calendar_type_vtodo">Sarcini</string>
<string name="create_calendar_type_vjournal">Note/jurnal</string>
<string name="create_calendar_maybe_not_supported">Crearea calendarului prin CalDAV poate să nu fie acceptată de server.</string>
<string name="create_collection_color">Culoare</string>
<string name="create_collection_display_name">Titlu</string>
<string name="create_collection_home_set">Locația de stocare</string>
<string name="create_collection_description_optional">Descriere (opțional)</string>
<string name="create_collection_create">Crează</string>
<!--CollectionScreen-->
<string name="collection_datatype_contacts">contacte</string>
<string name="collection_datatype_events">evenimente</string>
<string name="collection_datatype_tasks">sarcini</string>
<string name="collection_delete">Șterge colecția</string>
<string name="collection_delete_warning">Această colecție (%s) și toate datele sale vor fi șterse definitiv, atât local, cât și de pe server.</string>
<string name="collection_synchronization">Sincronizare</string>
<string name="collection_synchronization_on">Sincronizarea este activată</string>
<string name="collection_synchronization_off">Sincronizarea este dezactivată</string>
<string name="collection_read_only">Numai citire</string>
<string name="collection_read_only_by_server">Numai citire (de pe server)</string>
<string name="collection_read_only_by_setting">Numai citire (după politică)</string>
<string name="collection_read_only_forced">Numai citire (doar local)</string>
<string name="collection_read_write">Citire/scriere</string>
<string name="collection_title">Titlu</string>
<string name="collection_description">Descriere</string>
<string name="collection_owner">Proprietar</string>
<string name="collection_push_support">Suport Push</string>
<string name="collection_push_web_push">Serverul informează despre suportul Push</string>
<string name="collection_push_subscribed_at">Abonat la %1$s, expiră la %2$s</string>
<string name="collection_last_sync">Ultima sincronizare (%s)</string>
<string name="collection_url">Adresă (URL)</string>
<!--debugging and DebugInfoActivity-->
<string name="debug_info_title">Informații de depanare</string>
<string name="debug_info_archive_caption">Arhivă ZIP</string>
<string name="debug_info_archive_subtitle">Conține informații de depanare și jurnale</string>
<string name="debug_info_archive_text">Partajează arhiva pentru a o transfera pe un computer, pentru a o trimite prin e-mail sau pentru a o atașa la un bilet de asistență.</string>
<string name="debug_info_archive_share">Partajează arhiva</string>
<string name="debug_info_attached">Informații de depanare atașate la acest mesaj (necesită suport pentru atașamentele aplicației care primește).</string>
<string name="debug_info_http_error">Eroare HTTP</string>
<string name="debug_info_server_error">Eroare de server</string>
<string name="debug_info_webdav_error">Eroare WebDAV</string>
<string name="debug_info_io_error">Eroare I/O</string>
<string name="debug_info_http_403_description">Solicitarea a fost respinsă de server.</string>
<string name="debug_info_http_404_description">Resursa solicitată nu (mai) există.</string>
<string name="debug_info_http_405_description">Serverul nu permite tipul de operare solicitat.</string>
<string name="debug_info_http_5xx_description">A apărut o problemă la nivelul serverului. Contactează asistența serverului.</string>
<string name="debug_info_unexpected_error">A apărut o eroare neașteptată. Vezi informațiile de depanare pentru detalii.</string>
<string name="debug_info_view_details">Vezi detaliile</string>
<string name="debug_info_subtitle">Au fost colectate informații de depanare</string>
<string name="debug_info_involved_caption">Resurse implicate</string>
<string name="debug_info_involved_subtitle">Legat de problema</string>
<string name="debug_info_involved_remote">Resursa de la distanță:</string>
<string name="debug_info_involved_local">Resursa locală:</string>
<string name="debug_info_logs_caption">Jurnale</string>
<string name="debug_info_logs_subtitle">Jurnalele detaliate sunt disponibile</string>
<string name="debug_info_logs_view">Vezi jurnalele</string>
<string name="debug_info_copy_remote_url">Copiază adresa URL</string>
<string name="debug_info_view_local_resource">Inspectează resursa</string>
<string name="debug_info_privacy_warning_title">Notificare de confidențialitate</string>
<string name="debug_info_privacy_warning_description">Jurnalele și informațiile de depanare pot conține informații private. Fii conștient de acest lucru atunci când îl publici.</string>
<string name="debug_info_can_not_view_resource">Nu se poate vizualiza resursa</string>
<!--ExceptionInfoFragment-->
<string name="exception">A avut loc o eroare.</string>
<string name="exception_httpexception">A apărut o eroare HTTP.</string>
<string name="exception_ioexception">A apărut o eroare I/O.</string>
<string name="exception_show_details">Afișează detaliile</string>
<!--WebDAV accounts-->
<string name="webdav_mounts_title">Montări WebDAV</string>
<string name="webdav_mounts_quota_used_available">Cotă utilizată: %1$s / disponibilă: %2$s</string>
<string name="webdav_mounts_share_content">Partajează conținutul</string>
<string name="webdav_mounts_unmount">Demontează</string>
<string name="webdav_add_mount_title">Adaugă o montare WebDAV</string>
<string name="webdav_mounts_empty">Accesează direct fișierele din cloud adăugând o montare WebDAV!</string>
<string name="webdav_add_mount_empty_more_info"><![CDATA[Vezi manualul pentru a afla <a href="%1$s">cum funcționează montările WebDAV</a>.]]></string>
<string name="webdav_add_mount_display_name">Numele afișat</string>
<string name="webdav_add_mount_url">URL WebDAV</string>
<string name="webdav_add_mount_url_invalid">URL greșit</string>
<string name="webdav_add_mount_mountpoint_displayname">Punctul de montare și numele de afișare</string>
<string name="webdav_add_mount_authentication">Autentificare</string>
<string name="webdav_add_mount_username">Nume de utilizator</string>
<string name="webdav_add_mount_password">Parolă</string>
<string name="webdav_add_mount_username_optional">Nume de utilizator (opțional)</string>
<string name="webdav_add_mount_password_optional">Parolă (opțional)</string>
<string name="webdav_add_mount_add">Adaugă montare</string>
<string name="webdav_add_mount_no_support">Niciun serviciu WebDAV la această adresă URL</string>
<string name="webdav_remove_mount_title">Elimină punctul de montare</string>
<string name="webdav_remove_mount_text">Detaliile conexiunii se vor pierde, dar niciun fișier nu va fi șters.</string>
<string name="webdav_notification_access">Se accesează fișierul WebDAV</string>
<string name="webdav_notification_download">Se descarcă fișierul WebDAV</string>
<string name="webdav_notification_upload">Se actualizează fișierul WebDAV</string>
<string name="webdav_provider_root_title">Montare WebDAV</string>
<!--sync-->
<string name="sync_error_permissions">Permisiuni DAVx⁵</string>
<string name="sync_error_permissions_text">Sunt necesare permisiuni suplimentare</string>
<string name="sync_error_tasks_too_old">%s prea vechi</string>
<string name="sync_error_tasks_required_version">Versiunea minimă necesară: %1$s</string>
<string name="sync_error_authentication_failed">Autentificare eșuată (verifică datele de conectare)</string>
<string name="sync_error_io">Eroare de rețea sau I/O %s</string>
<string name="sync_error_http_dav">Eroare de server HTTP %s</string>
<string name="sync_error_local_storage">Eroare de stocare locală %s</string>
<string name="sync_error_retry_limit_reached">Eroare soft (încercări maxime atinse)</string>
<string name="sync_invalid_contact">S-a primit contact nevalid de la server</string>
<string name="sync_invalid_event">S-a primit eveniment nevalid de la server</string>
<string name="sync_invalid_task">S-a primit sarcină nevalidă de la server</string>
<string name="sync_invalid_resources_ignoring">Ignorarea uneia sau mai multor resurse nevalide</string>
<string name="sync_notification_pending_push_title">Sincronizare în așteptare</string>
<string name="sync_notification_pending_push_message">Datele de la distanță s-au schimbat</string>
<!--widgets-->
<string name="widget_sync_all">Sincronizează tot</string>
<string name="widget_sync_all_accounts">Sincronizează toate conturile</string>
<string name="widget_labeled_sync_label">Eticheta butonului de sincronizare</string>
<string name="widget_icon_sync_label">Pictograma butonului de sincronizare</string>
<string name="widget_sync_description">Atinge pentru a rula sincronizarea manual.</string>
<!--cert4android-->
</resources>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primaryColor">#7cb342</color>
<color name="primaryLightColor">#aee571</color>
<color name="primaryDarkColor">#4b830d</color>
</resources>

View File

@@ -2,12 +2,13 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
plugins {
// These lines make sure that the plugins are applied in the same version to all subprojects.
alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.hilt) apply false
alias(libs.plugins.kotlin.android) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.mikepenz.aboutLibraries.android) apply false
}

View File

View File

@@ -3,10 +3,9 @@
*/
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.android.library)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.mikepenz.aboutLibraries.android)
@@ -17,20 +16,12 @@ android {
compileSdk = 36
defaultConfig {
applicationId = "at.bitfire.davdroid"
versionCode = 405080003
versionName = "4.5.8"
base.archivesName = "davx5-ose-$versionName"
minSdk = 24 // Android 7.0
targetSdk = 36 // Android 16
// whether the build supports and allows to use custom certificates
buildConfigField("boolean", "allowCustomCerts", "true")
testInstrumentationRunner = "at.bitfire.davdroid.HiltTestRunner"
// include these rules in the app that uses the core library
consumerProguardFile("core-proguard-rules.pro")
}
java {
@@ -54,37 +45,9 @@ android {
// Java namespace for our classes (not to be confused with Android package ID)
namespace = "at.bitfire.davdroid"
flavorDimensions += "distribution"
productFlavors {
create("ose") {
dimension = "distribution"
versionNameSuffix = "-ose"
}
}
sourceSets {
getByName("androidTest") {
assets.srcDir("$projectDir/schemas")
}
}
signingConfigs {
create("bitfire") {
storeFile = file(System.getenv("ANDROID_KEYSTORE") ?: "/dev/null")
storePassword = System.getenv("ANDROID_KEYSTORE_PASSWORD")
keyAlias = System.getenv("ANDROID_KEY_ALIAS")
keyPassword = System.getenv("ANDROID_KEY_PASSWORD")
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules-release.pro")
isShrinkResources = true
signingConfig = signingConfigs.findByName("bitfire")
isMinifyEnabled = false
}
}
@@ -92,10 +55,6 @@ android {
disable += arrayOf("GoogleAppIndexingWarning", "ImpliedQuantity", "MissingQuantity", "MissingTranslation", "ExtraTranslation", "RtlEnabled", "RtlHardcoded", "Typos")
}
androidResources {
generateLocaleConfig = true
}
packaging {
resources {
// multiple (test) dependencies have LICENSE files at same location
@@ -103,6 +62,12 @@ android {
}
}
sourceSets {
getByName("androidTest") {
assets.srcDir("$projectDir/schemas")
}
}
@Suppress("UnstableApiUsage")
testOptions {
managedDevices {
@@ -131,7 +96,7 @@ aboutLibraries {
}
dependencies {
// core
// Kotlin / Android
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines)
coreLibraryDesugaring(libs.android.desugaring)
@@ -161,13 +126,14 @@ dependencies {
implementation(libs.compose.accompanist.permissions)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material3.adaptive)
implementation(libs.androidx.compose.materialIconsExtended)
debugImplementation(libs.androidx.compose.ui.tooling)
implementation(libs.androidx.compose.ui.toolingPreview)
// Glance Widgets
implementation(libs.androidx.glance.base)
implementation(libs.androidx.glance.material)
implementation(libs.androidx.glance.material3)
// Jetpack Room
implementation(libs.androidx.room.runtime)

View File

@@ -1,13 +1,4 @@
# R8 usage for DAVx⁵:
# shrinking yes (only in release builds)
# optimization yes (on by R8 defaults)
# full-mode no (see gradle.properties)
# obfuscation no (open-source)
-dontobfuscate
-printusage build/reports/r8-usage.txt
# keep rules
-keep class at.bitfire.** { *; } # all DAVx5 code is required
-keep class org.xmlpull.** { *; }

View File

View File

@@ -10,7 +10,6 @@ import android.os.Build
import android.os.Bundle
import androidx.test.runner.AndroidJUnitRunner
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule
import at.bitfire.davdroid.test.BuildConfig
import at.bitfire.synctools.log.LogcatHandler
import dagger.hilt.android.testing.HiltTestApplication
import java.util.logging.Level
@@ -29,7 +28,7 @@ class HiltTestRunner : AndroidJUnitRunner() {
val rootLogger = Logger.getLogger("")
rootLogger.level = Level.ALL
rootLogger.handlers.forEach { rootLogger.removeHandler(it) }
rootLogger.addHandler(LogcatHandler(BuildConfig.APPLICATION_ID))
rootLogger.addHandler(LogcatHandler(javaClass.name))
// MockK requirements
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)

View File

@@ -28,11 +28,11 @@ class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) {
""".trimIndent()
db.execSQL(
"INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)",
arrayOf(1, "test", Service.Companion.TYPE_CALDAV)
arrayOf<Any>(1, "test", Service.Companion.TYPE_CALDAV)
)
db.execSQL(
"INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, minimalVTimezone)
arrayOf<Any>(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, minimalVTimezone)
)
}
) { db ->
@@ -47,11 +47,11 @@ class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) {
prepare = { db ->
db.execSQL(
"INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)",
arrayOf(1, "test", Service.Companion.TYPE_CALDAV)
arrayOf<Any>(1, "test", Service.Companion.TYPE_CALDAV)
)
db.execSQL(
"INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync, timezone) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, "Some Garbage Content")
arrayOf<Any>(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false, "Some Garbage Content")
)
}
) { db ->
@@ -66,11 +66,11 @@ class AutoMigration16Test: DatabaseMigrationTest(toVersion = 16) {
prepare = { db ->
db.execSQL(
"INSERT INTO service (id, accountName, type) VALUES (?, ?, ?)",
arrayOf(1, "test", Service.Companion.TYPE_CALDAV)
arrayOf<Any>(1, "test", Service.Companion.TYPE_CALDAV)
)
db.execSQL(
"INSERT INTO collection (id, serviceId, type, url, privWriteContent, privUnbind, forceReadOnly, sync) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
arrayOf(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false)
arrayOf<Any>(1, 1, TYPE_CALENDAR, "https://example.com", true, true, false, false)
)
}
) { db ->

View File

@@ -0,0 +1,28 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.di
import at.bitfire.cert4android.CustomCertManager
import at.bitfire.cert4android.CustomCertStore
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import java.util.Optional
@Module
@InstallIn(SingletonComponent::class)
class Cert4AndroidModule {
@Provides
fun customCertManager(): Optional<CustomCertManager> = Optional.empty()
@Provides
fun customHostnameVerifier(): Optional<CustomCertManager.HostnameVerifier> = Optional.empty()
@Provides
fun customCertStore(): Optional<CustomCertStore> = Optional.empty()
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.di
import androidx.compose.material3.ColorScheme
import at.bitfire.davdroid.di.qualifier.DarkColorScheme
import at.bitfire.davdroid.di.qualifier.LightColorScheme
import at.bitfire.davdroid.ui.OseTheme
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
class ColorSchemesModule {
@Provides
@LightColorScheme
fun lightColorScheme(): ColorScheme = OseTheme.lightScheme
@Provides
@DarkColorScheme
fun darkColorScheme(): ColorScheme = OseTheme.darkScheme
}

View File

@@ -5,6 +5,10 @@
package at.bitfire.davdroid.di
import at.bitfire.davdroid.di.TestCoroutineDispatchersModule.standardTestDispatcher
import at.bitfire.davdroid.di.qualifier.DefaultDispatcher
import at.bitfire.davdroid.di.qualifier.IoDispatcher
import at.bitfire.davdroid.di.qualifier.MainDispatcher
import at.bitfire.davdroid.di.qualifier.SyncDispatcher
import dagger.Module
import dagger.Provides
import dagger.hilt.components.SingletonComponent

View File

@@ -4,12 +4,11 @@
package at.bitfire.davdroid.di
import at.bitfire.davdroid.ui.intro.OseIntroPageFactory
import at.bitfire.davdroid.ui.AboutActivity
import at.bitfire.davdroid.ui.AccountsDrawerHandler
import at.bitfire.davdroid.ui.OpenSourceLicenseInfoProvider
import at.bitfire.davdroid.ui.OseAccountsDrawerHandler
import at.bitfire.davdroid.ui.about.AboutActivity
import at.bitfire.davdroid.ui.about.FakeAppLicenseInfoProvider
import at.bitfire.davdroid.ui.intro.FakeIntroPageFactory
import at.bitfire.davdroid.ui.intro.IntroPageFactory
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
import at.bitfire.davdroid.ui.setup.StandardLoginTypesProvider
@@ -36,7 +35,7 @@ interface OseModules {
@InstallIn(ViewModelComponent::class)
interface ForViewModels {
@Binds
fun appLicenseInfoProvider(impl: OpenSourceLicenseInfoProvider): AboutActivity.AppLicenseInfoProvider
fun appLicenseInfoProvider(impl: FakeAppLicenseInfoProvider): AboutActivity.AppLicenseInfoProvider
@Binds
fun loginTypesProvider(impl: StandardLoginTypesProvider): LoginTypesProvider
@@ -46,7 +45,7 @@ interface OseModules {
@InstallIn(SingletonComponent::class)
interface Global {
@Binds
fun introPageFactory(impl: OseIntroPageFactory): IntroPageFactory
fun introPageFactory(impl: FakeIntroPageFactory): IntroPageFactory
}
}

View File

@@ -5,20 +5,20 @@
package at.bitfire.davdroid.di
import at.bitfire.davdroid.startup.StartupPlugin
import at.bitfire.davdroid.startup.TasksAppWatcher
import dagger.Module
import dagger.hilt.components.SingletonComponent
import dagger.hilt.testing.TestInstallIn
import dagger.multibindings.Multibinds
// remove TasksAppWatcherModule from Android tests
@Module
@TestInstallIn(
components = [SingletonComponent::class],
replaces = [TasksAppWatcher.TasksAppWatcherModule::class]
replaces = [StartupPluginsModule::class]
)
abstract class TestTasksAppWatcherModule {
// provides empty set of plugins
abstract class TestStartupPluginsModule {
// provides empty set of startup plugins so that nothing interferes with tests
@Multibinds
abstract fun empty(): Set<StartupPlugin>
}

View File

@@ -22,6 +22,7 @@ import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assume
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TestRule
@@ -62,6 +63,7 @@ class LocalCalendarStoreTest {
}
@Ignore("Flaky in CI")
@Test
fun testUpdateAccount_updatesOwnerAccount() {
// Verify initial state (assume to skip and prevent flaky test failures)
@@ -76,7 +78,6 @@ class LocalCalendarStoreTest {
// Verify [Calendar.OWNER_ACCOUNT] of local calendar was updated
assertEquals("ChangedAccountName", getOwnerAccount())
}

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