Compare commits

...

35 Commits

Author SHA1 Message Date
Ricki Hirner
38bad81c55 [WIP] Split into packages 2026-02-05 14:36:39 +01:00
Ricki Hirner
31a7ad0939 Move OSE code to separate package
- 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 14:10:14 +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
540 changed files with 3536 additions and 2217 deletions

8
.github/CODEOWNERS vendored
View File

@@ -1,4 +1,8 @@
# 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
# everything else
* @rfc2822

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

View File

@@ -6,7 +6,6 @@ plugins {
alias(libs.plugins.android.application)
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)
@@ -19,17 +18,14 @@ android {
defaultConfig {
applicationId = "at.bitfire.davdroid"
versionCode = 405080003
versionName = "4.5.8"
versionCode = 405090005
versionName = "4.5.9"
base.archivesName = "davx5-ose-$versionName"
base.archivesName = "davx5-$versionCode-$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"
}
@@ -52,7 +48,7 @@ android {
}
// Java namespace for our classes (not to be confused with Android package ID)
namespace = "at.bitfire.davdroid"
namespace = "com.davx5.ose"
flavorDimensions += "distribution"
productFlavors {
@@ -131,7 +127,10 @@ aboutLibraries {
}
dependencies {
// core
// app core
implementation(project(":core"))
// Kotlin / Android
implementation(libs.kotlin.stdlib)
implementation(libs.kotlinx.coroutines)
coreLibraryDesugaring(libs.android.desugaring)
@@ -161,13 +160,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)

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

@@ -4,350 +4,15 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="internalOnly">
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="internalOnly">
<!-- normal permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.READ_SYNC_STATS"/>
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
<!-- other permissions -->
<!-- android.permission-group.CONTACTS -->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<!-- android.permission-group.CALENDAR -->
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<!-- android.permission-group.LOCATION -->
<!-- getting the WiFi name (for "sync in Wifi only") requires
- coarse location (Android 8.1)
- fine location (Android 10) -->
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- required since Android 10 to get the WiFi name while in background (= while syncing) -->
<uses-permission-sdk-23 android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!-- ical4android declares task access permissions -->
<!-- Disable GPS capability requirement, which is implicitly derived from ACCESS_FINE_LOCATION
permission and makes app unusable on some devices without GPS. We need location permissions only
to get the current WiFi SSID, and we don't need GPS for that. -->
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<application
android:name=".App"
android:allowBackup="false"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
android:resizeableActivity="true"
tools:ignore="UnusedAttribute"
android:supportsRtl="true">
<!-- 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 android:name=".App">
<!-- Remove the node added by AppAuth (remove only from net.openid.appauth library, not from our flavor manifest files) -->
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity"
tools:node="remove" tools:selector="net.openid.appauth"/>
<activity android:name=".ui.intro.IntroActivity" />
<activity
android:name=".ui.AccountsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name=".ui.AboutActivity"
android:label="@string/navigation_drawer_about"
android:parentActivityName=".ui.AccountsActivity"/>
<activity
android:name=".ui.AppSettingsActivity"
android:label="@string/app_settings"
android:parentActivityName=".ui.AccountsActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.APPLICATION_PREFERENCES"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".ui.DebugInfoActivity"
android:parentActivityName=".ui.AppSettingsActivity"
android:exported="false"
android:label="@string/debug_info_title">
<intent-filter>
<action android:name="android.intent.action.BUG_REPORT"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".ui.PermissionsActivity"
android:label="@string/app_settings_security_app_permissions"
android:parentActivityName=".ui.AppSettingsActivity" />
<activity
android:name=".ui.TasksActivity"
android:label="@string/intro_tasks_title"
android:parentActivityName=".ui.AppSettingsActivity" />
<activity
android:name=".ui.setup.LoginActivity"
android:parentActivityName=".ui.AccountsActivity"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="caldav"/>
<data android:scheme="caldavs"/>
<data android:scheme="carddav"/>
<data android:scheme="carddavs"/>
<data android:scheme="davx5"/>
</intent-filter>
<intent-filter>
<action android:name="loginFlow" /> <!-- Ensures this filter matches, even if the sending app is not defining an action -->
<category android:name="android.intent.category.DEFAULT" />
<data
tools:ignore="AppLinkUrlError"
android:scheme="http" />
<data android:scheme="https" />
</intent-filter>
</activity>
<activity
android:name=".ui.account.AccountActivity"
android:parentActivityName=".ui.AccountsActivity"
android:exported="true">
</activity>
<activity
android:name=".ui.account.CollectionActivity"
android:parentActivityName=".ui.account.AccountActivity" />
<activity
android:name=".ui.account.CreateAddressBookActivity"
android:parentActivityName=".ui.account.AccountActivity" />
<activity
android:name=".ui.account.CreateCalendarActivity"
android:parentActivityName=".ui.account.AccountActivity" />
<activity
android:name=".ui.account.AccountSettingsActivity"
android:parentActivityName=".ui.account.AccountActivity" />
<activity
android:name=".ui.account.WifiPermissionsActivity"
android:parentActivityName=".ui.account.AccountSettingsActivity" />
<activity
android:name=".ui.webdav.WebdavMountsActivity"
android:exported="true"
android:parentActivityName=".ui.AccountsActivity" />
<activity
android:name=".ui.webdav.AddWebdavMountActivity"
android:parentActivityName=".ui.webdav.WebdavMountsActivity"
android:windowSoftInputMode="adjustResize" />
<!-- account type "DAVx⁵" -->
<service
android:name=".sync.account.AccountAuthenticatorService"
android:exported="false">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/account_authenticator"/>
</service>
<service
android:name=".sync.adapter.CalendarsSyncAdapterService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_calendars"/>
</service>
<service
android:name=".sync.adapter.JtxSyncAdapterService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_notes"/>
</service>
<service
android:name=".sync.adapter.OpenTasksSyncAdapterService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_opentasks"/>
</service>
<service
android:name=".sync.adapter.TasksOrgSyncAdapterService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_tasks_org"/>
</service>
<provider
android:authorities="@string/webdav_authority"
android:name=".webdav.DavDocumentsProvider"
android:exported="true"
android:grantUriPermissions="true"
android:permission="android.permission.MANAGE_DOCUMENTS">
<intent-filter>
<action android:name="android.content.action.DOCUMENTS_PROVIDER" />
</intent-filter>
</provider>
<!-- account type "DAVx⁵ Address book" -->
<service
android:name=".sync.account.AddressBookAuthenticatorService"
android:exported="true"
tools:ignore="ExportedService"> <!-- Since Android 11, this must be true so that Google Contacts shows the address book accounts -->
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator"/>
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="@xml/account_authenticator_address_book"/>
</service>
<service
android:name=".sync.adapter.ContactsSyncAdapterService"
android:exported="true"
tools:ignore="ExportedService">
<intent-filter>
<action android:name="android.content.SyncAdapter"/>
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="@xml/sync_contacts"/>
<meta-data
android:name="android.provider.CONTACTS_STRUCTURE"
android:resource="@xml/contacts"/>
</service>
<!-- provider to share debug info/logs -->
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="@string/authority_debug_provider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/debug_paths" />
</provider>
<!-- UnifiedPush -->
<service android:exported="false" android:name=".push.UnifiedPushService">
<intent-filter>
<action android:name="org.unifiedpush.android.connector.PUSH_EVENT"/>
</intent-filter>
</service>
<!-- Widgets -->
<receiver android:name=".ui.widget.LabeledSyncButtonWidgetReceiver"
android:label="@string/widget_labeled_sync_label"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info_labeled_sync_button" />
</receiver>
<receiver android:name=".ui.widget.IconSyncButtonWidgetReceiver"
android:label="@string/widget_icon_sync_label"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info_icon_sync_button" />
</receiver>
tools:node="remove" tools:selector="net.openid.appauth"/>
</application>
<!-- package visiblity which apps do we need to see? -->
<queries>
<!-- system providers (listing them is technically not required, but some apps like the
Huawei calendar take this as indication of whether these providers are accessed) -->
<provider android:authorities="com.android.calendar"/>
<provider android:authorities="com.android.contacts"/>
<!-- task providers -->
<package android:name="at.techbee.jtx" />
<package android:name="org.dmfs.tasks" />
<package android:name="org.tasks" />
<!-- ICSx5 for Webcal feeds -->
<package android:name="at.bitfire.icsdroid"/>
<!-- apps that interact with contact, calendar, task data (for debug info) -->
<intent>
<action android:name="*" />
<data android:scheme="content" android:host="com.android.contacts" />
</intent>
<intent>
<action android:name="*" />
<data android:scheme="content" android:host="com.android.calendar" />
</intent>
<!-- Open URLs in a browser or other app [https://developer.android.com/training/package-visibility/use-cases#open-urls-browser-or-other-app] -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<!-- Custom Tabs support (e.g. Nextcloud Login Flow) -->
<intent>
<action android:name="android.support.customtabs.action.CustomTabsService" />
</intent>
</queries>
</manifest>

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,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,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

@@ -2,12 +2,12 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid
package com.davx5.ose
import android.app.Application
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import at.bitfire.davdroid.di.DefaultDispatcher
import at.bitfire.davdroid.di.scope.DefaultDispatcher
import at.bitfire.davdroid.log.LogManager
import at.bitfire.davdroid.startup.StartupPlugin
import at.bitfire.davdroid.sync.account.AccountsCleanupWorker

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,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 CustomCertManagerModule {
@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.scope.DarkColorScheme
import at.bitfire.davdroid.di.scope.LightColorScheme
import com.davx5.ose.ui.OseTheme
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
@Module
@InstallIn(SingletonComponent::class)
class OseColorSchemesModule {
@Provides
@LightColorScheme
fun lightColorScheme(): ColorScheme = OseTheme.lightScheme
@Provides
@DarkColorScheme
fun darkColorScheme(): ColorScheme = OseTheme.darkScheme
}

View File

@@ -2,17 +2,16 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.di
package com.davx5.ose.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.intro.IntroPageFactory
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
import at.bitfire.davdroid.ui.setup.StandardLoginTypesProvider
import com.davx5.ose.ui.about.OpenSourceLicenseInfoProvider
import com.davx5.ose.ui.intro.OseIntroPageFactory
import com.davx5.ose.ui.setup.StandardLoginTypesProvider
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn

View File

@@ -2,14 +2,13 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui
package com.davx5.ose.ui
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.ui.graphics.Color
@Suppress("MemberVisibilityCanBePrivate")
object M3ColorScheme {
object OseTheme {
// All colors hand-crafted because Material Theme Builder generates unbelievably ugly colors

View File

@@ -2,7 +2,7 @@
* 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.text.Spanned
@@ -18,11 +18,12 @@ import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
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 kotlinx.coroutines.launch
import javax.inject.Inject
class OpenSourceLicenseInfoProvider @Inject constructor(): AboutActivity.AppLicenseInfoProvider {

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
)

View File

@@ -2,7 +2,7 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui.setup
package com.davx5.ose.ui.setup
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
@@ -15,6 +15,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@@ -24,6 +25,8 @@ import at.bitfire.davdroid.ui.ExternalUris
import at.bitfire.davdroid.ui.ExternalUris.withStatParams
import at.bitfire.davdroid.ui.UiUtils.toAnnotatedString
import at.bitfire.davdroid.ui.composable.Assistant
import at.bitfire.davdroid.ui.setup.LoginInfo
import at.bitfire.davdroid.ui.setup.LoginType
@Composable
fun StandardLoginTypePage(
@@ -67,9 +70,10 @@ fun StandardLoginTypePage(
HorizontalDivider(Modifier.padding(vertical = 12.dp))
val context = LocalContext.current
val privacyPolicy = ExternalUris.Homepage.baseUrl.buildUpon()
.appendPath(ExternalUris.Homepage.PATH_PRIVACY)
.withStatParams("StandardLoginTypePage")
.withStatParams(context, "StandardLoginTypePage")
.build().toString()
val privacy = HtmlCompat.fromHtml(
stringResource(R.string.login_privacy_hint, stringResource(R.string.app_name), privacyPolicy),

View File

@@ -2,12 +2,22 @@
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
package at.bitfire.davdroid.ui.setup
package com.davx5.ose.ui.setup
import android.content.Intent
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import at.bitfire.davdroid.ui.setup.AdvancedLogin
import at.bitfire.davdroid.ui.setup.EmailLogin
import at.bitfire.davdroid.ui.setup.FastmailLogin
import at.bitfire.davdroid.ui.setup.GoogleLogin
import at.bitfire.davdroid.ui.setup.LoginActivity
import at.bitfire.davdroid.ui.setup.LoginInfo
import at.bitfire.davdroid.ui.setup.LoginType
import at.bitfire.davdroid.ui.setup.LoginTypesProvider
import at.bitfire.davdroid.ui.setup.LoginTypesProvider.LoginAction
import at.bitfire.davdroid.ui.setup.NextcloudLogin
import at.bitfire.davdroid.ui.setup.UrlLogin
import java.util.logging.Logger
import javax.inject.Inject

View File

@@ -4,9 +4,9 @@
plugins {
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

196
core/build.gradle.kts Normal file
View File

@@ -0,0 +1,196 @@
/*
* Copyright © All Contributors. See LICENSE and AUTHORS in the root directory for details.
*/
plugins {
alias(libs.plugins.android.library)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.hilt)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.ksp)
alias(libs.plugins.mikepenz.aboutLibraries.android)
}
// Android configuration
android {
compileSdk = 36
defaultConfig {
minSdk = 24 // Android 7.0
testInstrumentationRunner = "at.bitfire.davdroid.HiltTestRunner"
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
compileOptions {
// required for
// - dnsjava 3.x: java.nio.file.Path
// - ical4android: time API
isCoreLibraryDesugaringEnabled = true
}
buildFeatures {
buildConfig = true
compose = true
}
// Java namespace for our classes (not to be confused with Android package ID)
namespace = "at.bitfire.davdroid"
sourceSets {
getByName("androidTest") {
assets.srcDir("$projectDir/schemas")
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
lint {
disable += arrayOf("GoogleAppIndexingWarning", "ImpliedQuantity", "MissingQuantity", "MissingTranslation", "ExtraTranslation", "RtlEnabled", "RtlHardcoded", "Typos")
}
packaging {
resources {
// multiple (test) dependencies have LICENSE files at same location
merges += arrayOf("META-INF/LICENSE*")
}
}
@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"
}
}
}
}
}
ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
aboutLibraries {
export {
// exclude timestamps for reproducible builds [https://github.com/bitfireAT/davx5-ose/issues/994]
excludeFields.add("generated")
}
}
dependencies {
// 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.activityCompose)
implementation(libs.androidx.appcompat)
implementation(libs.androidx.browser)
implementation(libs.androidx.core)
implementation(libs.androidx.hilt.navigation.compose)
implementation(libs.androidx.hilt.work)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.androidx.lifecycle.viewmodel.base)
implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.paging)
implementation(libs.androidx.paging.compose)
implementation(libs.androidx.preference)
implementation(libs.androidx.security)
implementation(libs.androidx.work.base)
// Jetpack Compose
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.material3)
// Jetpack Room
implementation(libs.androidx.room.runtime)
implementation(libs.androidx.room.base)
implementation(libs.androidx.room.paging)
ksp(libs.androidx.room.compiler)
// own libraries
implementation(libs.bitfire.cert4android)
implementation(libs.bitfire.dav4jvm) {
exclude(group="junit")
exclude(group="org.ogce", module="xpp3") // Android has its own XmlPullParser implementation
}
implementation(libs.bitfire.synctools) {
exclude(group="androidx.test") // synctools declares test rules, but we don't want them in non-test code
exclude(group = "junit")
}
// third-party libs
implementation(libs.conscrypt)
implementation(libs.dnsjava)
implementation(libs.guava)
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.okhttp)
implementation(libs.ktor.serialization.kotlinx.json)
implementation(libs.mikepenz.aboutLibraries.m3)
implementation(libs.okhttp.base)
implementation(libs.okhttp.brotli)
implementation(libs.okhttp.logging)
implementation(libs.openid.appauth)
implementation(libs.unifiedpush) {
// UnifiedPush connector seems to be using a workaround by importing this library.
// Will be removed after https://github.com/tink-crypto/tink-java-apps/pull/5 is merged.
// See: https://codeberg.org/UnifiedPush/android-connector/src/commit/28cb0d622ed0a972996041ab9cc85b701abc48c6/connector/build.gradle#L56-L59
exclude(group = "com.google.crypto.tink", module = "tink")
}
implementation(libs.unifiedpush.fcm)
// force some versions for compatibility with our minSdk level (see version catalog for details)
implementation(libs.commons.codec)
implementation(libs.commons.lang)
// for tests
androidTestImplementation(libs.androidx.arch.core.testing)
androidTestImplementation(libs.androidx.room.testing)
androidTestImplementation(libs.androidx.test.core)
androidTestImplementation(libs.androidx.test.junit)
androidTestImplementation(libs.androidx.test.rules)
androidTestImplementation(libs.androidx.test.runner)
androidTestImplementation(libs.androidx.work.testing)
androidTestImplementation(libs.hilt.android.testing)
androidTestImplementation(libs.junit)
androidTestImplementation(libs.kotlinx.coroutines.test)
androidTestImplementation(libs.mockk.android)
androidTestImplementation(libs.okhttp.mockwebserver)
testImplementation(libs.bitfire.dav4jvm)
testImplementation(libs.junit)
testImplementation(libs.mockk)
testImplementation(libs.okhttp.mockwebserver)
testImplementation(libs.robolectric)
}

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

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

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())
}

View File

@@ -25,6 +25,7 @@ import org.junit.Assert.assertFalse
import org.junit.Assume
import org.junit.Before
import org.junit.BeforeClass
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import java.util.logging.Logger
@@ -72,6 +73,7 @@ class AccountSettingsMigration21Test {
}
@Ignore("Flaky in CI")
@SdkSuppress(minSdkVersion = 34)
@Test
fun testCancelsSyncAndClearsPendingState() = runBlocking {

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