diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5290041b7..352bde60c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -221,7 +221,6 @@ dependencies { implementation("com.google.auth:google-auth-library-oauth2-http:0.26.0") implementation("androidx.work:work-runtime:${Versions.work}") implementation("androidx.work:work-runtime-ktx:${Versions.work}") - implementation("com.etesync:journalmanager:1.1.1") implementation("com.etebase:client:2.3.2") implementation("com.github.QuadFlask:colorpicker:0.0.15") implementation("net.openid:appauth:0.8.1") diff --git a/app/licenses.yml b/app/licenses.yml index 83c9b4261..f06dc10cc 100644 --- a/app/licenses.yml +++ b/app/licenses.yml @@ -497,24 +497,6 @@ copyrightHolder: Android Open Source Project license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt -- artifact: com.madgag.spongycastle:core:+ - name: Spongy Castle Core - copyrightHolder: The Legion of the Bouncy Castle Inc. - license: Bouncy Castle Licence - licenseUrl: http://www.bouncycastle.org/licence.html - url: http://rtyley.github.io/spongycastle/ -- artifact: com.etesync:journalmanager:+ - name: EteSync JVM - copyrightHolder: Tom Hacohen - license: LGPL-3.0-only - licenseUrl: https://spdx.org/licenses/LGPL-3.0-only.html - url: https://www.etesync.com -- artifact: com.madgag.spongycastle:prov:+ - name: Spongy Castle - copyrightHolder: The Legion of the Bouncy Castle Inc. - license: Bouncy Castle Licence - licenseUrl: http://www.bouncycastle.org/licence.html - url: http://rtyley.github.io/spongycastle/ - artifact: androidx.preference:preference:+ name: AndroidX Preference copyrightHolder: Android Open Source Project diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 428b8773a..796ea40be 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -638,10 +638,6 @@ - - diff --git a/app/src/main/assets/licenses.json b/app/src/main/assets/licenses.json index a7edbfbcd..98cb2bed8 100644 --- a/app/src/main/assets/licenses.json +++ b/app/src/main/assets/licenses.json @@ -1186,48 +1186,6 @@ "normalizedLicense": "apache2", "libraryName": "viewbinding" }, - { - "artifactId": { - "name": "core", - "group": "com.madgag.spongycastle", - "version": "+" - }, - "copyrightHolder": "The Legion of the Bouncy Castle Inc.", - "copyrightStatement": "Copyright © The Legion of the Bouncy Castle Inc. All rights reserved.", - "license": "Bouncy Castle Licence", - "licenseUrl": "http://www.bouncycastle.org/licence.html", - "normalizedLicense": "Bouncy Castle Licence", - "url": "http://rtyley.github.io/spongycastle/", - "libraryName": "Spongy Castle Core" - }, - { - "artifactId": { - "name": "journalmanager", - "group": "com.etesync", - "version": "+" - }, - "copyrightHolder": "Tom Hacohen", - "copyrightStatement": "Copyright © Tom Hacohen. All rights reserved.", - "license": "LGPL-3.0-only", - "licenseUrl": "https://spdx.org/licenses/LGPL-3.0-only.html", - "normalizedLicense": "lgpl3", - "url": "https://www.etesync.com", - "libraryName": "EteSync JVM" - }, - { - "artifactId": { - "name": "prov", - "group": "com.madgag.spongycastle", - "version": "+" - }, - "copyrightHolder": "The Legion of the Bouncy Castle Inc.", - "copyrightStatement": "Copyright © The Legion of the Bouncy Castle Inc. All rights reserved.", - "license": "Bouncy Castle Licence", - "licenseUrl": "http://www.bouncycastle.org/licence.html", - "normalizedLicense": "Bouncy Castle Licence", - "url": "http://rtyley.github.io/spongycastle/", - "libraryName": "Spongy Castle" - }, { "artifactId": { "name": "preference", diff --git a/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt b/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt index 3c2a91daf..16902fe8c 100644 --- a/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt +++ b/app/src/main/java/com/todoroo/astrid/adapter/SubheaderViewHolder.kt @@ -51,11 +51,8 @@ internal class SubheaderViewHolder( this.subheader = subheader text.text = subheader.listingTitle when { - subheader.error -> with(errorIcon) { - setColorFilter(ContextCompat.getColor(activity, R.color.overdue)) - visibility = View.VISIBLE - } - subheader.subheaderType == SubheaderType.ETESYNC -> with(errorIcon) { + subheader.error || subheader.subheaderType == SubheaderType.ETESYNC -> + with(errorIcon) { setColorFilter(ContextCompat.getColor(activity, R.color.overdue)) visibility = View.VISIBLE } diff --git a/app/src/main/java/org/tasks/analytics/Constants.kt b/app/src/main/java/org/tasks/analytics/Constants.kt index 0be975e31..cc3979f57 100644 --- a/app/src/main/java/org/tasks/analytics/Constants.kt +++ b/app/src/main/java/org/tasks/analytics/Constants.kt @@ -2,7 +2,6 @@ package org.tasks.analytics object Constants { const val SYNC_TYPE_CALDAV = "caldav" - const val SYNC_TYPE_ETESYNC = "etesync" const val SYNC_TYPE_DAVX5 = "davx5" const val SYNC_TYPE_GOOGLE_TASKS = "google_tasks" const val SYNC_TYPE_ETESYNC_OT = "etesync_ot" diff --git a/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.kt b/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.kt deleted file mode 100644 index ba8519f4c..000000000 --- a/app/src/main/java/org/tasks/etesync/AddEteSyncAccountViewModel.kt +++ /dev/null @@ -1,20 +0,0 @@ -package org.tasks.etesync - -import androidx.core.util.Pair -import com.etesync.journalmanager.UserInfoManager.UserInfo -import dagger.hilt.android.lifecycle.HiltViewModel -import org.tasks.ui.CompletableViewModel -import javax.inject.Inject - -@Deprecated("use etebase") -@HiltViewModel -class AddEteSyncAccountViewModel @Inject constructor( - private val client: EteSyncClient): CompletableViewModel>() { - suspend fun addAccount(url: String, username: String, password: String) { - run { - client.setForeground() - val token = client.forUrl(url, username, null, null).getToken(password) - Pair.create(client.forUrl(url, username, null, token!!).userInfo(), token) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/CreateUserInfoViewModel.kt b/app/src/main/java/org/tasks/etesync/CreateUserInfoViewModel.kt deleted file mode 100644 index fc8b73b10..000000000 --- a/app/src/main/java/org/tasks/etesync/CreateUserInfoViewModel.kt +++ /dev/null @@ -1,18 +0,0 @@ -package org.tasks.etesync - -import dagger.hilt.android.lifecycle.HiltViewModel -import org.tasks.data.CaldavAccount -import org.tasks.ui.CompletableViewModel -import javax.inject.Inject - -@Deprecated("use etebase") -@HiltViewModel -class CreateUserInfoViewModel @Inject constructor( - private val client: EteSyncClient): CompletableViewModel() { - suspend fun createUserInfo(caldavAccount: CaldavAccount, derivedKey: String) { - run { - client.forAccount(caldavAccount).createUserInfo(derivedKey) - derivedKey - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt b/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt deleted file mode 100644 index a85defcc1..000000000 --- a/app/src/main/java/org/tasks/etesync/EncryptionSettingsActivity.kt +++ /dev/null @@ -1,191 +0,0 @@ -package org.tasks.etesync - -import android.app.Activity -import android.content.Intent -import android.os.Bundle -import android.view.MenuItem -import android.view.View -import androidx.activity.viewModels -import androidx.appcompat.widget.Toolbar -import androidx.core.widget.addTextChangedListener -import androidx.lifecycle.lifecycleScope -import at.bitfire.dav4jvm.exception.HttpException -import com.etesync.journalmanager.Constants.Companion.CURRENT_VERSION -import com.etesync.journalmanager.Crypto.CryptoManager -import com.etesync.journalmanager.Crypto.deriveKey -import com.etesync.journalmanager.Exceptions.IntegrityException -import com.etesync.journalmanager.Exceptions.VersionTooNewException -import com.etesync.journalmanager.UserInfoManager -import com.google.android.material.snackbar.Snackbar -import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch -import org.tasks.R -import org.tasks.Strings.isNullOrEmpty -import org.tasks.data.CaldavAccount -import org.tasks.databinding.ActivityEtesyncEncryptionSettingsBinding -import org.tasks.extensions.Context.openUri -import org.tasks.injection.ThemedInjectingAppCompatActivity -import org.tasks.security.KeyStoreEncryption -import org.tasks.ui.DisplayableException -import java.net.ConnectException -import javax.inject.Inject - -@Deprecated("use etebase") -@AndroidEntryPoint -class EncryptionSettingsActivity : ThemedInjectingAppCompatActivity(), Toolbar.OnMenuItemClickListener { - @Inject lateinit var encryption: KeyStoreEncryption - - private lateinit var binding: ActivityEtesyncEncryptionSettingsBinding - private var userInfo: UserInfoManager.UserInfo? = null - private var caldavAccount: CaldavAccount? = null - private val createUserInfoViewModel: CreateUserInfoViewModel by viewModels() - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivityEtesyncEncryptionSettingsBinding.inflate(layoutInflater) - setContentView(binding.root) - val intent = intent - caldavAccount = intent.getParcelableExtra(EXTRA_ACCOUNT) - userInfo = intent.getSerializableExtra(EXTRA_USER_INFO) as UserInfoManager.UserInfo - if (userInfo == null) { - binding.description.visibility = View.VISIBLE - binding.repeatEncryptionPasswordLayout.visibility = View.VISIBLE - } - val toolbar = binding.toolbar.toolbar - toolbar.title = if (caldavAccount == null) getString(R.string.add_account) else caldavAccount!!.name - toolbar.navigationIcon = getDrawable(R.drawable.ic_outline_save_24px) - toolbar.setNavigationOnClickListener { save() } - toolbar.inflateMenu(R.menu.menu_help) - toolbar.setOnMenuItemClickListener(this) - themeColor.apply(toolbar) - createUserInfoViewModel.observe(this, { returnDerivedKey(it) }, this::requestFailed) - if (createUserInfoViewModel.inProgress) { - showProgressIndicator() - } - binding.repeatEncryptionPassword.addTextChangedListener( - onTextChanged = { _, _, _, _ -> onRepeatEncryptionPasswordChanged() } - ) - binding.encryptionPassword.addTextChangedListener( - onTextChanged = { _, _, _, _ -> onEncryptionPasswordChanged() } - ) - } - - private fun showProgressIndicator() { - binding.progressBar.progressBar.visibility = View.VISIBLE - } - - private fun hideProgressIndicator() { - binding.progressBar.progressBar.visibility = View.GONE - } - - private fun requestInProgress() = binding.progressBar.progressBar.visibility == View.VISIBLE - - private fun returnDerivedKey(derivedKey: String) { - hideProgressIndicator() - val result = Intent() - result.putExtra(EXTRA_DERIVED_KEY, derivedKey) - setResult(Activity.RESULT_OK, result) - finish() - return - } - - private fun save() = lifecycleScope.launch { - if (requestInProgress()) { - return@launch - } - val encryptionPassword = newEncryptionPassword - val derivedKey = caldavAccount!!.getEncryptionPassword(encryption) - if (isNullOrEmpty(encryptionPassword) && isNullOrEmpty(derivedKey)) { - binding.encryptionPasswordLayout.error = getString(R.string.encryption_password_required) - return@launch - } - if (userInfo == null) { - val repeatEncryptionPassword = binding.repeatEncryptionPassword.text.toString().trim { it <= ' ' } - if (encryptionPassword != repeatEncryptionPassword) { - binding.repeatEncryptionPasswordLayout.error = getString(R.string.passwords_do_not_match) - return@launch - } - } - val key = if (isNullOrEmpty(encryptionPassword)) derivedKey else deriveKey(caldavAccount!!.username!!, encryptionPassword) - val cryptoManager: CryptoManager - cryptoManager = try { - val version = if (userInfo == null) CURRENT_VERSION else userInfo!!.version!!.toInt() - CryptoManager(version, key, "userInfo") - } catch (e: VersionTooNewException) { - requestFailed(e) - return@launch - } catch (e: IntegrityException) { - requestFailed(e) - return@launch - } - if (userInfo == null) { - showProgressIndicator() - createUserInfoViewModel.createUserInfo(caldavAccount!!, key) - } else { - try { - userInfo!!.verify(cryptoManager) - returnDerivedKey(key) - } catch (e: IntegrityException) { - binding.encryptionPasswordLayout.error = getString(R.string.encryption_password_wrong) - } - } - } - - private fun requestFailed(t: Throwable) { - hideProgressIndicator() - when (t) { - is HttpException -> showSnackbar(t.message) - is DisplayableException -> showSnackbar(t.resId) - is ConnectException -> showSnackbar(R.string.network_error) - else -> showSnackbar(R.string.error_adding_account, t.message!!) - } - } - - private fun showSnackbar(resId: Int, vararg formatArgs: Any) = - showSnackbar(getString(resId, *formatArgs)) - - private fun showSnackbar(message: String?) = - newSnackbar(message).show() - - private fun newSnackbar(message: String?): Snackbar { - val snackbar = Snackbar.make(binding.rootLayout, message!!, 8000) - .setTextColor(getColor(R.color.snackbar_text_color)) - .setActionTextColor(getColor(R.color.snackbar_action_color)) - snackbar - .view - .setBackgroundColor(getColor(R.color.snackbar_background)) - return snackbar - } - - private fun onRepeatEncryptionPasswordChanged() { - binding.repeatEncryptionPasswordLayout.error = null - } - - private fun onEncryptionPasswordChanged() { - binding.encryptionPasswordLayout.error = null - } - - private val newEncryptionPassword: String - get() = binding.encryptionPassword.text.toString().trim { it <= ' ' } - - override fun finish() { - if (!requestInProgress()) { - super.finish() - } - } - - override fun onMenuItemClick(item: MenuItem): Boolean { - return if (item.itemId == R.id.menu_help) { - openUri(R.string.url_etesync) - true - } else { - onOptionsItemSelected(item) - } - } - - companion object { - const val EXTRA_USER_INFO = "extra_user_info" - const val EXTRA_ACCOUNT = "extra_account" - const val EXTRA_DERIVED_KEY = "extra_derived_key" - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt b/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt index 02141f35b..0e8b5bed8 100644 --- a/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt +++ b/app/src/main/java/org/tasks/etesync/EteSyncAccountSettingsActivity.kt @@ -1,42 +1,21 @@ package org.tasks.etesync -import android.app.Activity -import android.content.Intent import android.os.Bundle import android.view.View -import androidx.activity.viewModels import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat -import androidx.core.util.Pair -import androidx.lifecycle.lifecycleScope -import com.etesync.journalmanager.Crypto.CryptoManager -import com.etesync.journalmanager.Exceptions.IntegrityException -import com.etesync.journalmanager.Exceptions.VersionTooNewException -import com.etesync.journalmanager.UserInfoManager -import com.todoroo.astrid.data.Task -import com.todoroo.astrid.helper.UUIDHelper import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch import org.tasks.R import org.tasks.Strings.isNullOrEmpty -import org.tasks.analytics.Constants import org.tasks.caldav.BaseCaldavAccountSettingsActivity -import org.tasks.data.CaldavAccount -import timber.log.Timber -import javax.inject.Inject @Deprecated("use etebase") @AndroidEntryPoint class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Toolbar.OnMenuItemClickListener { - @Inject lateinit var eteSyncClient: EteSyncClient - - private val addAccountViewModel: AddEteSyncAccountViewModel by viewModels() - private val updateAccountViewModel: UpdateEteSyncAccountViewModel by viewModels() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding.repeat.visibility = View.GONE - binding.showAdvanced.visibility = View.VISIBLE + binding.showAdvanced.visibility = View.GONE binding.description.visibility = View.VISIBLE binding.description.setTextColor(ContextCompat.getColor(this, R.color.overdue)) binding.description.setText(description) @@ -46,90 +25,19 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool override val description = R.string.etesync_deprecated - override fun onResume() { - super.onResume() - if (!isFinishing) { - addAccountViewModel.observe(this, this::addAccount, this::requestFailed) - updateAccountViewModel.observe(this, this::updateAccount, this::requestFailed) - } - } - - override fun onPause() { - super.onPause() - addAccountViewModel.removeObserver(this) - updateAccountViewModel.removeObserver(this) - } - - private suspend fun addAccount(userInfoAndToken: Pair) { - caldavAccount = CaldavAccount() - caldavAccount!!.accountType = CaldavAccount.TYPE_ETESYNC - caldavAccount!!.uuid = UUIDHelper.newUUID() - applyTo(caldavAccount!!, userInfoAndToken) - } - - private suspend fun updateAccount(userInfoAndToken: Pair) { - caldavAccount!!.error = "" - applyTo(caldavAccount!!, userInfoAndToken) - } - - private suspend fun applyTo(account: CaldavAccount, userInfoAndToken: Pair) { - hideProgressIndicator() - account.name = newName - account.url = newURL - account.username = newUsername - val token = userInfoAndToken.second - if (token != account.getPassword(encryption)) { - account.password = encryption.encrypt(token!!) - } - val userInfo = userInfoAndToken.first - if (testUserInfo(userInfo)) { - saveAccountAndFinish() - } else { - val intent = Intent(this, EncryptionSettingsActivity::class.java) - intent.putExtra(EncryptionSettingsActivity.EXTRA_USER_INFO, userInfo) - intent.putExtra(EncryptionSettingsActivity.EXTRA_ACCOUNT, account) - startActivityForResult(intent, REQUEST_ENCRYPTION_PASSWORD) - } - } - - private fun testUserInfo(userInfo: UserInfoManager.UserInfo?): Boolean { - val encryptionKey = caldavAccount!!.getEncryptionPassword(encryption) - if (userInfo != null && !isNullOrEmpty(encryptionKey)) { - try { - val cryptoManager = CryptoManager(userInfo.version!!.toInt(), encryptionKey, "userInfo") - userInfo.verify(cryptoManager) - return true - } catch (e: IntegrityException) { - Timber.e(e) - } catch (e: VersionTooNewException) { - Timber.e(e) - } - } - return false - } - private fun updateUrlVisibility() { - binding.urlLayout.visibility = if (binding.showAdvanced.isChecked) View.VISIBLE else View.GONE + binding.urlLayout.visibility = View.GONE } - override fun needsValidation(): Boolean { - return super.needsValidation() || isNullOrEmpty(caldavAccount!!.encryptionKey) - } + override fun needsValidation() = false - override suspend fun addAccount(url: String, username: String, password: String) = - addAccountViewModel.addAccount(url, username, password) + override fun hasChanges() = false - override suspend fun updateAccount(url: String, username: String, password: String) = - updateAccountViewModel.updateAccount( - url, - username, - if (PASSWORD_MASK == password) null else password, - caldavAccount!!.getPassword(encryption)) + override suspend fun addAccount(url: String, username: String, password: String) {} - override suspend fun updateAccount() { - caldavAccount!!.name = newName - saveAccountAndFinish() - } + override suspend fun updateAccount(url: String, username: String, password: String) {} + + override suspend fun updateAccount() {} override val newURL: String get() { @@ -141,41 +49,4 @@ class EteSyncAccountSettingsActivity : BaseCaldavAccountSettingsActivity(), Tool get() = binding.password.text.toString().trim { it <= ' ' } override val helpUrl = R.string.url_etesync - - override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { - if (requestCode == REQUEST_ENCRYPTION_PASSWORD) { - if (resultCode == Activity.RESULT_OK) { - lifecycleScope.launch { - val key = data!!.getStringExtra(EncryptionSettingsActivity.EXTRA_DERIVED_KEY)!! - caldavAccount!!.encryptionKey = encryption.encrypt(key) - saveAccountAndFinish() - } - } - } else { - super.onActivityResult(requestCode, resultCode, data) - } - } - - private suspend fun saveAccountAndFinish() { - if (caldavAccount!!.id == Task.NO_ID) { - caldavDao.insert(caldavAccount!!) - firebase.logEvent( - R.string.event_sync_add_account, - R.string.param_type to Constants.SYNC_TYPE_ETESYNC - ) - } else { - caldavDao.update(caldavAccount!!) - } - setResult(Activity.RESULT_OK) - finish() - } - - override suspend fun removeAccount() { - caldavAccount?.let { eteSyncClient.forAccount(it).invalidateToken() } - super.removeAccount() - } - - companion object { - private const val REQUEST_ENCRYPTION_PASSWORD = 10101 - } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/EteSyncClient.kt b/app/src/main/java/org/tasks/etesync/EteSyncClient.kt deleted file mode 100644 index 8fb3a273a..000000000 --- a/app/src/main/java/org/tasks/etesync/EteSyncClient.kt +++ /dev/null @@ -1,277 +0,0 @@ -package org.tasks.etesync - -import android.content.Context -import androidx.core.util.Pair -import at.bitfire.cert4android.CustomCertManager -import com.etesync.journalmanager.* -import com.etesync.journalmanager.Constants.Companion.CURRENT_VERSION -import com.etesync.journalmanager.Crypto.AsymmetricKeyPair -import com.etesync.journalmanager.Crypto.CryptoManager -import com.etesync.journalmanager.Exceptions.IntegrityException -import com.etesync.journalmanager.Exceptions.VersionTooNewException -import com.etesync.journalmanager.JournalManager.Journal -import com.etesync.journalmanager.UserInfoManager.UserInfo.Companion.generate -import com.etesync.journalmanager.model.CollectionInfo -import com.etesync.journalmanager.model.CollectionInfo.Companion.fromJson -import com.etesync.journalmanager.model.SyncEntry -import com.etesync.journalmanager.util.TokenAuthenticator -import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import okhttp3.HttpUrl -import okhttp3.HttpUrl.Companion.toHttpUrlOrNull -import okhttp3.OkHttpClient -import okhttp3.internal.tls.OkHostnameVerifier -import org.tasks.DebugNetworkInterceptor -import org.tasks.caldav.MemoryCookieStore -import org.tasks.data.CaldavAccount -import org.tasks.data.CaldavCalendar -import org.tasks.preferences.Preferences -import org.tasks.security.KeyStoreEncryption -import timber.log.Timber -import java.io.IOException -import java.security.KeyManagementException -import java.security.NoSuchAlgorithmException -import java.util.* -import java.util.concurrent.TimeUnit -import javax.inject.Inject -import javax.net.ssl.SSLContext - -@Deprecated("use etebase") -class EteSyncClient { - private val encryption: KeyStoreEncryption - private val preferences: Preferences - private val interceptor: DebugNetworkInterceptor - private val username: String? - private val token: String? - private val encryptionPassword: String? - private val httpClient: OkHttpClient? - private val httpUrl: HttpUrl? - private val context: Context - private val journalManager: JournalManager? - private var foreground = false - - @Inject - constructor( - @ApplicationContext context: Context, - encryption: KeyStoreEncryption, - preferences: Preferences, - interceptor: DebugNetworkInterceptor) { - this.context = context - this.encryption = encryption - this.preferences = preferences - this.interceptor = interceptor - username = null - token = null - encryptionPassword = null - httpClient = null - httpUrl = null - journalManager = null - } - - private constructor( - context: Context, - encryption: KeyStoreEncryption, - preferences: Preferences, - interceptor: DebugNetworkInterceptor, - url: String?, - username: String?, - encryptionPassword: String?, - token: String?, - foreground: Boolean) { - this.context = context - this.encryption = encryption - this.preferences = preferences - this.interceptor = interceptor - this.username = username - this.encryptionPassword = encryptionPassword - this.token = token - this.foreground = foreground - val customCertManager = CustomCertManager(context) - customCertManager.appInForeground = foreground - val hostnameVerifier = customCertManager.hostnameVerifier(OkHostnameVerifier) - val sslContext = SSLContext.getInstance("TLS") - sslContext.init(null, arrayOf(customCertManager), null) - val builder = OkHttpClient() - .newBuilder() - .addNetworkInterceptor(TokenAuthenticator(null, token)) - .cookieJar(MemoryCookieStore()) - .followRedirects(false) - .followSslRedirects(true) - .sslSocketFactory(sslContext.socketFactory, customCertManager) - .hostnameVerifier(hostnameVerifier) - .connectTimeout(15, TimeUnit.SECONDS) - .writeTimeout(30, TimeUnit.SECONDS) - .readTimeout(120, TimeUnit.SECONDS) - if (preferences.isFlipperEnabled) { - interceptor.apply(builder) - } - httpClient = builder.build() - httpUrl = url?.toHttpUrlOrNull() - journalManager = JournalManager(httpClient, httpUrl!!) - } - - @Throws(NoSuchAlgorithmException::class, KeyManagementException::class) - suspend fun forAccount(account: CaldavAccount): EteSyncClient { - return forUrl( - account.url, - account.username, - account.getEncryptionPassword(encryption), - account.getPassword(encryption)) - } - - @Throws(KeyManagementException::class, NoSuchAlgorithmException::class) - suspend fun forUrl(url: String?, username: String?, encryptionPassword: String?, token: String?): EteSyncClient = withContext(Dispatchers.IO) { - EteSyncClient( - context, - encryption, - preferences, - interceptor, - url, - username, - encryptionPassword, - token, - foreground) - } - - @Throws(IOException::class, Exceptions.HttpException::class) - suspend fun getToken(password: String?): String? = withContext(Dispatchers.IO) { - JournalAuthenticator(httpClient!!, httpUrl!!).getAuthToken(username!!, password!!) - } - - @Throws(Exceptions.HttpException::class) - suspend fun userInfo(): UserInfoManager.UserInfo? = withContext(Dispatchers.IO) { - val userInfoManager = UserInfoManager(httpClient!!, httpUrl!!) - userInfoManager.fetch(username!!) - } - - @Throws(VersionTooNewException::class, IntegrityException::class) - fun getCrypto(userInfo: UserInfoManager.UserInfo?, journal: Journal): CryptoManager { - if (journal.key == null) { - return CryptoManager(journal.version, encryptionPassword!!, journal.uid!!) - } - if (userInfo == null) { - throw RuntimeException("Missing userInfo") - } - val cryptoManager = CryptoManager(userInfo.version!!.toInt(), encryptionPassword!!, "userInfo") - val keyPair = AsymmetricKeyPair(userInfo.getContent(cryptoManager)!!, userInfo.pubkey!!) - return CryptoManager(journal.version, keyPair, journal.key!!) - } - - private fun convertJournalToCollection(userInfo: UserInfoManager.UserInfo?, journal: Journal): CollectionInfo? { - return try { - val cryptoManager = getCrypto(userInfo, journal) - journal.verify(cryptoManager) - val collection = fromJson(journal.getContent(cryptoManager)) - collection.updateFromJournal(journal) - collection - } catch (e: IntegrityException) { - Timber.e(e) - null - } catch (e: VersionTooNewException) { - Timber.e(e) - null - } - } - - @Throws(Exceptions.HttpException::class) - suspend fun getCalendars(userInfo: UserInfoManager.UserInfo?): Map = withContext(Dispatchers.IO) { - val result: MutableMap = HashMap() - for (journal in journalManager!!.list()) { - val collection = convertJournalToCollection(userInfo, journal) - if (collection != null) { - if (TYPE_TASKS == collection.type) { - Timber.v("Found %s", collection) - result[journal] = collection - } else { - Timber.v("Ignoring %s", collection) - } - } - } - result - } - - @Throws(IntegrityException::class, Exceptions.HttpException::class, VersionTooNewException::class) - suspend fun getSyncEntries( - userInfo: UserInfoManager.UserInfo?, - journal: Journal, - calendar: CaldavCalendar, - callback: suspend (List>) -> Unit) = withContext(Dispatchers.IO) { - val journalEntryManager = JournalEntryManager(httpClient!!, httpUrl!!, journal.uid!!) - val crypto = getCrypto(userInfo, journal) - var journalEntries: List - do { - journalEntries = journalEntryManager.list(crypto, calendar.ctag, MAX_FETCH) - callback(journalEntries.map { - Pair.create(it, SyncEntry.fromJournalEntry(crypto, it)) - }) - } while (journalEntries.size >= MAX_FETCH) - } - - @Throws(Exceptions.HttpException::class) - suspend fun pushEntries(journal: Journal, entries: List?, remoteCtag: String?) = withContext(Dispatchers.IO) { - var remoteCtag = remoteCtag - val journalEntryManager = JournalEntryManager(httpClient!!, httpUrl!!, journal.uid!!) - for (partition in entries!!.chunked(MAX_PUSH)) { - journalEntryManager.create(partition, remoteCtag) - remoteCtag = partition[partition.size - 1].uid - } - } - - fun setForeground() { - foreground = true - } - - suspend fun invalidateToken() = withContext(Dispatchers.IO) { - try { - JournalAuthenticator(httpClient!!, httpUrl!!).invalidateAuthToken(token!!) - } catch (e: Exception) { - Timber.e(e) - } - } - - @Throws(VersionTooNewException::class, IntegrityException::class, Exceptions.HttpException::class) - suspend fun makeCollection(name: String?, color: Int): String = withContext(Dispatchers.IO) { - val uid = Journal.genUid() - val collectionInfo = CollectionInfo() - collectionInfo.displayName = name - collectionInfo.type = TYPE_TASKS - collectionInfo.uid = uid - collectionInfo.selected = true - collectionInfo.color = if (color == 0) null else color - val crypto = CryptoManager(collectionInfo.version, encryptionPassword!!, uid) - journalManager!!.create(Journal(crypto, collectionInfo.toJson(), uid)) - uid - } - - @Throws(VersionTooNewException::class, IntegrityException::class, Exceptions.HttpException::class) - suspend fun updateCollection(calendar: CaldavCalendar, name: String?, color: Int): String? = withContext(Dispatchers.IO) { - val uid = calendar.url - val journal = journalManager!!.fetch(uid!!) - val userInfo = userInfo() - val crypto = getCrypto(userInfo, journal) - val collectionInfo = convertJournalToCollection(userInfo, journal) - collectionInfo!!.displayName = name - collectionInfo.color = if (color == 0) null else color - journalManager.update(Journal(crypto, collectionInfo.toJson(), uid)) - uid - } - - @Throws(Exceptions.HttpException::class) - suspend fun deleteCollection(calendar: CaldavCalendar) = withContext(Dispatchers.IO) { - journalManager!!.delete(Journal.fakeWithUid(calendar.url!!)) - } - - @Throws(Exceptions.HttpException::class, VersionTooNewException::class, IntegrityException::class, IOException::class) - suspend fun createUserInfo(derivedKey: String?) = withContext(Dispatchers.IO) { - val cryptoManager = CryptoManager(CURRENT_VERSION, derivedKey!!, "userInfo") - val userInfo: UserInfoManager.UserInfo = generate(cryptoManager, username!!) - UserInfoManager(httpClient!!, httpUrl!!).create(userInfo) - } - - companion object { - private const val TYPE_TASKS = "TASKS" - private const val MAX_FETCH = 50 - private const val MAX_PUSH = 30 - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/EteSynchronizer.kt b/app/src/main/java/org/tasks/etesync/EteSynchronizer.kt deleted file mode 100644 index bea6523ef..000000000 --- a/app/src/main/java/org/tasks/etesync/EteSynchronizer.kt +++ /dev/null @@ -1,225 +0,0 @@ -package org.tasks.etesync - -import android.content.Context -import androidx.core.util.Pair -import at.bitfire.ical4android.ICalendar.Companion.prodId -import com.etesync.journalmanager.Exceptions -import com.etesync.journalmanager.Exceptions.IntegrityException -import com.etesync.journalmanager.Exceptions.VersionTooNewException -import com.etesync.journalmanager.JournalEntryManager -import com.etesync.journalmanager.JournalEntryManager.Entry.Companion.getFakeWithUid -import com.etesync.journalmanager.JournalManager.Journal -import com.etesync.journalmanager.UserInfoManager -import com.etesync.journalmanager.model.SyncEntry -import com.todoroo.astrid.helper.UUIDHelper -import com.todoroo.astrid.service.TaskDeleter -import dagger.hilt.android.qualifiers.ApplicationContext -import net.fortuna.ical4j.model.property.ProdId -import org.tasks.BuildConfig -import org.tasks.LocalBroadcastManager -import org.tasks.R -import org.tasks.Strings.isNullOrEmpty -import org.tasks.billing.Inventory -import org.tasks.caldav.iCalendar -import org.tasks.caldav.iCalendar.Companion.fromVtodo -import org.tasks.data.CaldavAccount -import org.tasks.data.CaldavCalendar -import org.tasks.data.CaldavDao -import org.tasks.data.CaldavTaskContainer -import timber.log.Timber -import java.security.KeyManagementException -import java.security.NoSuchAlgorithmException -import java.util.* -import javax.inject.Inject -import kotlin.collections.HashSet - -@Deprecated("use etebase") -class EteSynchronizer @Inject constructor( - @param:ApplicationContext private val context: Context, - private val caldavDao: CaldavDao, - private val localBroadcastManager: LocalBroadcastManager, - private val taskDeleter: TaskDeleter, - private val inventory: Inventory, - private val client: EteSyncClient, - private val iCal: iCalendar) { - companion object { - init { - prodId = ProdId("+//IDN tasks.org//android-" + BuildConfig.VERSION_CODE + "//EN") - } - } - - suspend fun sync(account: CaldavAccount) { - Thread.currentThread().contextClassLoader = context.classLoader - - if (!inventory.hasPro) { - setError(account, context.getString(R.string.requires_pro_subscription)) - return - } - if (isNullOrEmpty(account.password)) { - setError(account, context.getString(R.string.password_required)) - return - } - if (isNullOrEmpty(account.encryptionKey)) { - setError(account, context.getString(R.string.encryption_password_required)) - return - } - try { - synchronize(account) - } catch (e: KeyManagementException) { - setError(account, e.message) - } catch (e: NoSuchAlgorithmException) { - setError(account, e.message) - } catch (e: Exceptions.HttpException) { - setError(account, e.message) - } catch (e: IntegrityException) { - setError(account, e.message) - } catch (e: VersionTooNewException) { - setError(account, e.message) - } - } - - @Throws(KeyManagementException::class, NoSuchAlgorithmException::class, Exceptions.HttpException::class, IntegrityException::class, VersionTooNewException::class) - private suspend fun synchronize(account: CaldavAccount) { - val client = client.forAccount(account) - val userInfo = client.userInfo() - val resources = client.getCalendars(userInfo) - val uids: Set = resources.values.mapNotNull { it.uid }.toHashSet() - Timber.d("Found uids: %s", uids) - for (calendar in caldavDao.findDeletedCalendars(account.uuid!!, uids.toList())) { - taskDeleter.delete(calendar) - } - for ((key, collection) in resources) { - val uid = collection.uid - var calendar = caldavDao.getCalendarByUrl(account.uuid!!, uid!!) - val colorInt = collection.color - val color = colorInt ?: 0 - if (calendar == null) { - calendar = CaldavCalendar() - calendar.name = collection.displayName - calendar.account = account.uuid - calendar.url = collection.uid - calendar.uuid = UUIDHelper.newUUID() - calendar.color = color - caldavDao.insert(calendar) - } else { - if (calendar.name != collection.displayName - || calendar.color != color) { - calendar.name = collection.displayName - calendar.color = color - caldavDao.update(calendar) - localBroadcastManager.broadcastRefreshList() - } - } - sync(client, userInfo!!, calendar, key) - } - setError(account, "") - } - - private suspend fun setError(account: CaldavAccount, message: String?) { - account.error = message - caldavDao.update(account) - localBroadcastManager.broadcastRefreshList() - if (!isNullOrEmpty(message)) { - Timber.e(message) - } - } - - @Throws(IntegrityException::class, Exceptions.HttpException::class, VersionTooNewException::class) - private suspend fun sync( - client: EteSyncClient, - userInfo: UserInfoManager.UserInfo, - caldavCalendar: CaldavCalendar, - journal: Journal) { - Timber.d("sync(%s)", caldavCalendar) - val localChanges = HashMap() - for (task in caldavDao.getCaldavTasksToPush(caldavCalendar.uuid!!)) { - localChanges[task.remoteId] = task - } - var remoteCtag = journal.lastUid - if (isNullOrEmpty(remoteCtag) || remoteCtag != caldavCalendar.ctag) { - Timber.v("Applying remote changes") - client.getSyncEntries(userInfo, journal, caldavCalendar) { - applyEntries(caldavCalendar, it, localChanges.keys) - } - } else { - Timber.d("%s up to date", caldavCalendar.name) - } - val changes: MutableList = ArrayList() - for (task in caldavDao.getMoved(caldavCalendar.uuid!!)) { - val vtodo = task.vtodo - if (!isNullOrEmpty(vtodo)) { - changes.add(SyncEntry(vtodo!!, SyncEntry.Actions.DELETE)) - } - } - for (task in localChanges.values) { - val vtodo = task.vtodo - val existingTask = !isNullOrEmpty(vtodo) - if (task.isDeleted) { - if (existingTask) { - changes.add(SyncEntry(vtodo!!, SyncEntry.Actions.DELETE)) - } - } else { - changes.add( - SyncEntry( - String(iCal.toVtodo(task.caldavTask, task.task)), - if (existingTask) SyncEntry.Actions.CHANGE else SyncEntry.Actions.ADD)) - } - } - remoteCtag = caldavCalendar.ctag - val crypto = client.getCrypto(userInfo, journal) - val updates: MutableList> = ArrayList() - var previous: JournalEntryManager.Entry? = if (isNullOrEmpty(remoteCtag)) null else getFakeWithUid(remoteCtag!!) - for (syncEntry in changes) { - val entry = JournalEntryManager.Entry() - entry.update(crypto, syncEntry.toJson(), previous) - updates.add(Pair.create(entry, syncEntry)) - previous = entry - } - if (updates.size > 0) { - Timber.v("Pushing local changes") - client.pushEntries(journal, updates.mapNotNull { it.first }, remoteCtag) - Timber.v("Applying local changes") - applyEntries(caldavCalendar, updates, HashSet()) - } - Timber.d("UPDATE %s", caldavCalendar) - caldavDao.update(caldavCalendar) - caldavDao.updateParents(caldavCalendar.uuid!!) - localBroadcastManager.broadcastRefresh() - } - - private suspend fun applyEntries( - caldavCalendar: CaldavCalendar, - syncEntries: List>, - dirty: MutableSet) { - for (entry in syncEntries) { - val journalEntry = entry.first - val syncEntry = entry.second - val action = syncEntry!!.action - val vtodo = syncEntry.content - Timber.v("%s: %s", action, vtodo) - val task = fromVtodo(vtodo) ?: continue - val remoteId = task.uid - val caldavTask = caldavDao.getTaskByRemoteId(caldavCalendar.uuid!!, remoteId!!) - when (action) { - SyncEntry.Actions.ADD, SyncEntry.Actions.CHANGE -> if (dirty.contains(remoteId)) { - caldavTask!!.vtodo = vtodo - caldavDao.update(caldavTask) - } else { - iCal.fromVtodo(caldavCalendar, caldavTask, task, vtodo, null, null) - } - SyncEntry.Actions.DELETE -> { - dirty.remove(remoteId) - if (caldavTask != null) { - if (caldavTask.isDeleted()) { - caldavDao.delete(caldavTask) - } else { - taskDeleter.delete(caldavTask.task) - } - } - } - } - caldavCalendar.ctag = journalEntry!!.uid - caldavDao.update(caldavCalendar) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.kt b/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.kt deleted file mode 100644 index 137b71fd4..000000000 --- a/app/src/main/java/org/tasks/etesync/UpdateEteSyncAccountViewModel.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.tasks.etesync - -import androidx.core.util.Pair -import com.etesync.journalmanager.UserInfoManager.UserInfo -import dagger.hilt.android.lifecycle.HiltViewModel -import org.tasks.Strings.isNullOrEmpty -import org.tasks.ui.CompletableViewModel -import javax.inject.Inject - -@Deprecated("use etebase") -@HiltViewModel -class UpdateEteSyncAccountViewModel @Inject constructor( - private val client: EteSyncClient) : CompletableViewModel>() { - suspend fun updateAccount(url: String, user: String, pass: String?, token: String) { - run { - client.setForeground() - if (isNullOrEmpty(pass)) { - Pair.create(client.forUrl(url, user, null, token).userInfo(), token) - } else { - val newToken = client.forUrl(url, user, null, null).getToken(pass) - Pair.create(client.forUrl(url, user, null, newToken).userInfo(), newToken) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/jobs/SyncEteSyncWork.kt b/app/src/main/java/org/tasks/jobs/SyncEteSyncWork.kt deleted file mode 100644 index 632e50dbe..000000000 --- a/app/src/main/java/org/tasks/jobs/SyncEteSyncWork.kt +++ /dev/null @@ -1,46 +0,0 @@ -package org.tasks.jobs - -import android.content.Context -import androidx.hilt.work.HiltWorker -import androidx.work.WorkerParameters -import dagger.assisted.Assisted -import dagger.assisted.AssistedInject -import kotlinx.coroutines.* -import org.tasks.LocalBroadcastManager -import org.tasks.R -import org.tasks.analytics.Firebase -import org.tasks.data.CaldavAccount.Companion.TYPE_ETESYNC -import org.tasks.data.CaldavDao -import org.tasks.etesync.EteSynchronizer -import org.tasks.preferences.Preferences - -@Deprecated("use etebase") -@HiltWorker -class SyncEteSyncWork @AssistedInject constructor( - @Assisted context: Context, - @Assisted workerParams: WorkerParameters, - firebase: Firebase, - localBroadcastManager: LocalBroadcastManager, - preferences: Preferences, - private val caldavDao: CaldavDao, - private val eteSynchronizer: EteSynchronizer -) : SyncWork(context, workerParams, firebase, localBroadcastManager, preferences) { - - override suspend fun enabled() = caldavDao.getAccounts(TYPE_ETESYNC).isNotEmpty() - - override val syncStatus = R.string.p_sync_ongoing_etesync - - override suspend fun doSync() { - firebase.logEvent(R.string.legacy_etesync) - etesyncJobs().awaitAll() - } - - private suspend fun etesyncJobs(): List> = coroutineScope { - caldavDao.getAccounts(TYPE_ETESYNC) - .map { - async(Dispatchers.IO) { - eteSynchronizer.sync(it) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/tasks/jobs/WorkManager.kt b/app/src/main/java/org/tasks/jobs/WorkManager.kt index ae2e1f946..4dee4dd79 100644 --- a/app/src/main/java/org/tasks/jobs/WorkManager.kt +++ b/app/src/main/java/org/tasks/jobs/WorkManager.kt @@ -20,9 +20,6 @@ interface WorkManager { suspend fun caldavSync(immediate: Boolean) - @Deprecated("use etebase") - suspend fun eteSync(immediate: Boolean) - suspend fun eteBaseSync(immediate: Boolean) suspend fun openTaskSync(immediate: Boolean) @@ -55,7 +52,6 @@ interface WorkManager { const val TAG_MIDNIGHT_REFRESH = "tag_midnight_refresh" const val TAG_SYNC_GOOGLE_TASKS = "tag_sync_google_tasks" const val TAG_SYNC_CALDAV = "tag_sync_caldav" - @Deprecated("use etebase") const val TAG_SYNC_ETESYNC = "tag_sync_etesync" const val TAG_SYNC_ETEBASE = "tag_sync_etebase" const val TAG_SYNC_OPENTASK = "tag_sync_opentask" const val TAG_BACKGROUND_SYNC_GOOGLE_TASKS = "tag_background_sync_google_tasks" diff --git a/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt b/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt index bd3ab4ff8..b214b6826 100644 --- a/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt +++ b/app/src/main/java/org/tasks/jobs/WorkManagerImpl.kt @@ -39,7 +39,6 @@ import org.tasks.jobs.WorkManager.Companion.TAG_REFRESH import org.tasks.jobs.WorkManager.Companion.TAG_REMOTE_CONFIG import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_CALDAV import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_ETEBASE -import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_ETESYNC import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_GOOGLE_TASKS import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_OPENTASK import org.tasks.jobs.WorkManager.Companion.TAG_UPDATE_PURCHASES @@ -103,9 +102,6 @@ class WorkManagerImpl constructor( override suspend fun caldavSync(immediate: Boolean) = sync(immediate, TAG_SYNC_CALDAV, SyncCaldavWork::class.java) - override suspend fun eteSync(immediate: Boolean) = - sync(immediate, TAG_SYNC_ETESYNC, SyncEteSyncWork::class.java) - override suspend fun eteBaseSync(immediate: Boolean) = sync(immediate, TAG_SYNC_ETEBASE, SyncEtebaseWork::class.java) diff --git a/app/src/main/java/org/tasks/preferences/Preferences.kt b/app/src/main/java/org/tasks/preferences/Preferences.kt index f13e6391b..6b7d86b54 100644 --- a/app/src/main/java/org/tasks/preferences/Preferences.kt +++ b/app/src/main/java/org/tasks/preferences/Preferences.kt @@ -514,7 +514,6 @@ class Preferences @JvmOverloads constructor( private val syncFlags = listOf( R.string.p_sync_ongoing_google_tasks, R.string.p_sync_ongoing_caldav, - R.string.p_sync_ongoing_etesync, R.string.p_sync_ongoing_android) } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/sync/SyncAdapters.kt b/app/src/main/java/org/tasks/sync/SyncAdapters.kt index f62b0ce53..bf90a224f 100644 --- a/app/src/main/java/org/tasks/sync/SyncAdapters.kt +++ b/app/src/main/java/org/tasks/sync/SyncAdapters.kt @@ -7,7 +7,6 @@ import org.tasks.LocalBroadcastManager import org.tasks.R import org.tasks.data.CaldavAccount.Companion.TYPE_CALDAV import org.tasks.data.CaldavAccount.Companion.TYPE_ETEBASE -import org.tasks.data.CaldavAccount.Companion.TYPE_ETESYNC import org.tasks.data.CaldavAccount.Companion.TYPE_OPENTASKS import org.tasks.data.CaldavAccount.Companion.TYPE_TASKS import org.tasks.data.CaldavDao @@ -17,7 +16,6 @@ import org.tasks.data.OpenTaskDao import org.tasks.jobs.WorkManager import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_CALDAV import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_ETEBASE -import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_ETESYNC import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_GOOGLE_TASKS import org.tasks.jobs.WorkManager.Companion.TAG_SYNC_OPENTASK import org.tasks.preferences.Preferences @@ -38,7 +36,6 @@ class SyncAdapters @Inject constructor( private val scope = CoroutineScope(newSingleThreadExecutor().asCoroutineDispatcher() + SupervisorJob()) private val googleTasks = Debouncer(TAG_SYNC_GOOGLE_TASKS) { workManager.googleTaskSync(it) } private val caldav = Debouncer(TAG_SYNC_CALDAV) { workManager.caldavSync(it) } - @Deprecated("use etebase") private val eteSync = Debouncer(TAG_SYNC_ETESYNC) { workManager.eteSync(it) } private val eteBaseSync = Debouncer(TAG_SYNC_ETEBASE) { workManager.eteBaseSync(it) } private val opentasks = Debouncer(TAG_SYNC_OPENTASK) { workManager.openTaskSync(it) } private val syncStatus = Debouncer("sync_status") { @@ -62,9 +59,6 @@ class SyncAdapters @Inject constructor( || caldavDao.isAccountType(task.id, TYPE_TASKS)) { caldav.sync(false) } - if (caldavDao.isAccountType(task.id, TYPE_ETESYNC)) { - eteSync.sync(false) - } if (caldavDao.isAccountType(task.id, TYPE_ETEBASE)) { eteBaseSync.sync(false) } @@ -89,7 +83,6 @@ class SyncAdapters @Inject constructor( fun sync(immediate: Boolean) = scope.launch { val googleTasksEnabled = async { isGoogleTaskSyncEnabled() } val caldavEnabled = async { isCaldavSyncEnabled() } - val eteSyncEnabled = async { isEteSyncEnabled() } val eteBaseEnabled = async { isEtebaseEnabled() } val opentasksEnabled = async { isOpenTaskSyncEnabled() } @@ -101,10 +94,6 @@ class SyncAdapters @Inject constructor( caldav.sync(immediate) } - if (eteSyncEnabled.await()) { - eteSync.sync(immediate) - } - if (eteBaseEnabled.await()) { eteBaseSync.sync(immediate) } @@ -119,9 +108,6 @@ class SyncAdapters @Inject constructor( private suspend fun isCaldavSyncEnabled() = caldavDao.getAccounts(TYPE_CALDAV, TYPE_TASKS).isNotEmpty() - @Deprecated("use etebase") - private suspend fun isEteSyncEnabled() = caldavDao.getAccounts(TYPE_ETESYNC).isNotEmpty() - private suspend fun isEtebaseEnabled() = caldavDao.getAccounts(TYPE_ETEBASE).isNotEmpty() private suspend fun isOpenTaskSyncEnabled() = diff --git a/app/src/main/res/layout/activity_etesync_encryption_settings.xml b/app/src/main/res/layout/activity_etesync_encryption_settings.xml deleted file mode 100644 index 4cfe899c1..000000000 --- a/app/src/main/res/layout/activity_etesync_encryption_settings.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 62c48d44d..ca1160075 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -310,13 +310,11 @@ %s (تم) الأولوية… قائمة - كلمة سرّ التشفير تحت العنوان بعد العنوان التكرار الافتراضي العلامات الافتراضيّة (لا عنوان) - كلمة سرّ التشفير مطلوبة كلمة السرّ مطلوبة اسم المستعمل مطلوب انتقِ من التخزين @@ -376,13 +374,10 @@ استكشاف الأخطاء وإصلاحها التوثيق متقدم - تذكّر كلمة سرّ التشفير التي تختارها، لا يمكن استرجاعها! اختر منصّة أنشأ \"%s\" لم يوجد أيّ تقويم تصفية - كلمات السرّ لا تتّفق - كلمة سر تشفير خاطئة انقل مهام فرعيّة @@ -453,7 +448,6 @@ الشارات خطأ: %s رابط - أكّد كلمة سرّ التشفير مخفي تذييل عكس diff --git a/app/src/main/res/values-bg-rBG/strings.xml b/app/src/main/res/values-bg-rBG/strings.xml index 7daf36666..12f612a41 100644 --- a/app/src/main/res/values-bg-rBG/strings.xml +++ b/app/src/main/res/values-bg-rBG/strings.xml @@ -544,12 +544,10 @@ Прекарах хиляди часове в работа по Tasks и публикувам целия изходен код безплатно. За да поддържам работата си, някои възможности изискват абонамент Скрито Икона - Потвърждаване на паролата за криптиране Добре Избор на всички Посочете своя цена Синхронизация чрез файлове - Парола за криптиране Списъци Нисък приоритет След днес @@ -576,16 +574,13 @@ При щракване Какво е новото Няма приложение, което да обработи тази заявка - Грешна парола за криптиране Синхронизация, шифрована от край до край - Запомнете паролата за шифроване, защото не може да бъде възстановена! Външен вид и усещане Отстраняване на неизправности Ползи за абонамент Назад Сега Незапочнати - Изисква се парола за криптиране Непрозрачност на реда Долен колонтитул Под заглавието @@ -596,7 +591,6 @@ Непрозрачност на заглавието Пренасрочване на задачата След заглавието - Паролите не съвпадат Отваряне на списък Адрес Тапети и теми за ден/нощ diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index a75f37b69..5d7c48fa3 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -421,11 +421,6 @@ Ikona Zvýšit předplatné Zrušit předplatné - Zadejte heslo pro šifrování - Heslo pro šifrování - Zadání hesla se neshodují - Zopakujte heslo pro šifrování - Nesprávné heslo pro šifrování Nápověda a zpětná vazba Dashclock rozšíření Vyžaduje PRO předplatné @@ -472,7 +467,6 @@ Zobrazit pokročilé možnosti Vyžaduje účet u poskytovatele s CalDAV službou nebo vlastní server. Vhodné poskytovatele najdete na tasks.org/caldav Vyžaduje účet na EteSync.com nebo vlastní server - Dobře si zapamatujte své šifrovací heslo, protože jej není možné obnovit! Vzhled a chování Dokumentace Pokročilé možnosti diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index bf225f8f1..5cd2864ea 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -174,7 +174,6 @@ Dokumentation Avanceret Udseende - Husk det krypteringskodeord, du vælger. Det kan ikke gendannes! Det kræver en konto hos EteSync.com eller en selv-hostet server Det kræver en konto hos en CalDAV-tjenesteudbyder eller en selv-hostet server. Find en tjenesteudbyder ved at gå til tasks.org/caldav Vis avancerede indstillinger @@ -264,8 +263,6 @@ Strømsparetilstand kan forsinke notifikationer Fejl: %s URL - Bekræft krypteringskodeord - Krypteringskodeord Kodeord Bruger Tilføj konto @@ -316,11 +313,8 @@ Skal begynde med http(s):// Hostname er nødvendigt URL er nødvendig - Kodeordene er ikke ens - Forkert krypteringskodeord Brugernavn er nødvendigt Kodeord er nødvendigt - Krypteringskodeord er nødvendigt Navnet må ikke være tomt Tagget findes allerede Send anonymiseret brugerstatistik og fejlrapporter for at hjælpe med at forbedre Tasks. Ingen personlig data bliver indsamlet. diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a6e766f75..a4602fb3f 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -458,13 +458,8 @@ Teilaufgaben Mehrstufige Teilaufgaben werden von Google Tasks nicht unterstützt Titel eingeben - Passwort zur Verschlüsselung erforderlich - Verschlüsselungspasswort Anzeigename Diese Funktion benötigt ein Abonnement - Passwörter stimmen nicht überein - Verschlüsselungspasswort bestätigen - Falsches Passwort zur Verschlüsselung Hilfe und Rückmeldung Systemstandard Schlagwort eingeben @@ -476,7 +471,6 @@ Erweiterte Einstellungen anzeigen Erfordert ein Konto bei einem CalDAV-Dienstanbieter oder einem selbst gehosteten Server. Finden Sie einen Dienstanbieter, indem Sie tasks.org/caldav besuchen Erfordert ein Konto bei EteSync.com oder einen selbst gehosteten Server - Merken Sie sich das von Ihnen gewählte Passwort! Es kann nicht wiederhergestellt werden. Erscheinungsbild Erweitert Dokumentation diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index dd017058f..3a5ae820d 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -260,7 +260,6 @@ Defaŭlta listo (Sen titolo) Ligilo bezonata - Pasvortoj ne samas Pasvorto bezonata Uzantnomo bezonata Nomo ne povas malpleni diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index c79d82474..95f6bebd5 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -459,21 +459,15 @@ Introducir título Introduzca el nombre de la etiqueta Crear «%s» - Se necesita una contraseña de cifrado - Contraseña de cifrado Mostrar el nombre Esta característica requiere una suscripción Seleccione una plataforma Servicio básico que se sincroniza con tu cuenta de Google Sincronización basada en estándares abiertos de Internet Sincronización cifrada de extremo a extremo - Las contraseñas no coinciden - Confirmar la contraseña de cifrado Mostrar la configuración avanzada Requiere una cuenta con un proveedor de servicios CalDAV o un servidor autoalojado. Encuentre un proveedor de servicios visitando tasks.org/caldav Requiere una cuenta en EteSync.com o un servidor autoalojado - Recuerde la contraseña de cifrado que elija. ¡No puede ser recuperada! - Contraseña de cifrado errónea Ayuda y retroalimentación Documentación Apariencia diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index 5e5c9f46e..17159f2e2 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -459,21 +459,15 @@ Sartu izenburua Idatzi etiketaren izena Sortu \"%s\" - Zifratze pasahitza behar da - Zifratze pasahitza Erakutsi izena Ezaugarri honek harpidetza eskatzen du Hautatu plataforma Zure Google kontuarekin sinkronizatzen den oinarrizko zerbitzua Internet estandar irekietan oinarritutako sinkronizazioa Muturretik-muturrera zifratutako sinkronizazioa - Pasahitzak ez datoz bat - Baieztatu zifratze pasahitza Erakutsi ezarpen aurreratuak CalDAV zerbitzu hornitzaile bateko edo zuk zeuk ostatatutako zerbitzu bateko kontua behar du. Aurkitu zerbitzu hornitzaile bat tasks.org/caldav helbidean EteSync.com zerbitzuko edo zuk zeuk ostatatutako zerbitzari bateko kontua behar du - Gogoratu aukeratutako zifratze-pasahitza, ezin baita berreskuratu! - Zifratze-pasahitz okerra Feedback eta laguntza Dokumentazioa Itxura diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 914738b3b..20acca3be 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -403,7 +403,6 @@ Paina tästä jos ilmoitusten kanssa on ongelmia Dokumentaatio Ulkonäkö ja tunnelma - Painathan salaukselle asettamasti salasanan muistiin, sillä sitä ei voi palauttaa tai nollata! End-to-end-salattu synkronointi Avoimiin verkkostandardeihin pohjautuva synkronointi Valitse alusta @@ -449,8 +448,6 @@ ", " Virhe: %s URL - Vahvista salauksen salasana - Salauksen salasana Salasana Käyttäjä Lisää tili @@ -459,9 +456,6 @@ Kuvake On alettava http(s):// URL vaaditaan - Salasanat eivät täsmää - Väärä salauksen salasana - Salauksen salasana vaaditaan Salasana vaaditaan Käyttäjänimi vaaditaan Siirrä diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 87c93931f..aded13819 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -454,21 +454,15 @@ Entrer le titre Entrez le nom de l\'étiquette Créer « %s » - Mot de passe de chiffrement requis - Mot de passe de chiffrement Afficher le nom Cette fonctionnalité nécessite un abonnement Sélectionnez une plate-forme Service de base qui se synchronise avec votre compte Google Synchronisation basée sur des normes d\'Internet ouvertes Synchronisation du chiffrement de bout en bout - Les mots de passe ne correspondent pas - Confirmer le mot de passe de chiffrement Afficher les paramètres avancés Nécessite un compte auprès d\'un fournisseur de services CalDAV ou un serveur auto-hébergé. Trouvez un fournisseur de services en visitant tasks.org/caldav Nécessite un compte sur EteSync.com ou un serveur auto-hébergé - N\'oubliez pas le mot de passe de chiffrement que vous choisissez, il ne peut pas être récupéré ! - Mot de passe de chiffrement erroné Aide et remarques Documentation Apparence diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index fbfd66717..ff83062fe 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -364,8 +364,6 @@ Optimiranje baterije može odgoditi obavijesti Greška: %s URL - Potvrdi lozinku za šifriranje - Lozinka za šifriranje Lozinka Korisnik Dodaj račun @@ -417,9 +415,6 @@ Mora početi s http(s):// Naziv računala je obavezno URL-adresa je obavezna - Lozinke se ne poklapaju - Kriva lozinka za šifriranje - Lozinka za šifriranje je obavezna Lozinka je obavezna Korisničko ime je obavezno Ime ne smije biti prazno @@ -634,7 +629,6 @@ Rješavanje problema Prikaži obavijesti na nosivim uređajima Obavijesti nosivih uređaja - Zapamti odabranu lozinku za šifriranje, ne može se obnoviti! Zahtijeva račun na EteSync.com ili vlastiti poslužitelj Pokaži zaglavlje Pokaži potvrdne okvire diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 2fe2757e1..9391968ee 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -457,21 +457,15 @@ Cím megadása Címke neve \"%s\" létrehozása - A titkosításhoz jelszó szükséges - Jelszó titkosításhoz Megjelenített név Ez a funkció csak előfizetéssel vehető igénybe Platform választása Alapvető szolgáltatás, ami a Google accounttal szinkronizál Nyílt Internetes szabványon alapuló szinkronizáció Végponttól végpontig titkosított szinkronizáció - A jelszavak nem egyeznek - Titkosítás jelszavának megerősítése Haladó beállítások mutatása CalDAV szolgáltatással rendelkező accountot, vagy saját szervert igényel. A szolgáltatók listája a tasks.org/caldav oldalon található EteSync.com accountot, vagy saját szervert igényel - Jól jegyezd meg a titkosítás jelszavát! A jelszó elfelejtés esetén nem visszaállítható! - Hibás titkosító jelszó Segítség és visszajelzés Dokumentáció Kinézet diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml index 7a33fb0ff..ea1c5bbea 100644 --- a/app/src/main/res/values-id/strings.xml +++ b/app/src/main/res/values-id/strings.xml @@ -299,8 +299,6 @@ ", " Jangan tambahkan ke kalender Bawaan kalender - Kata sandi enkripsi diperlukan - Kata sandi enkripsi Berkas %1$s berisi %2$s. \n \n %3$s diimpor, @@ -375,13 +373,9 @@ Sinkronisasi yang berdasarkan pada standar internet terbuka Enkripsi klien-ke-klien bersumber terbuka Latar - Sandi tidak sama - Konfirmasi sandi enkripsi Tampilkan pengaturan lanjutan Membutuhkan akun penyedia layanan CalDAV atau server host-mandiri. Temukan penyedia layanan dengan mengunjungi tasks.org/caldav Membutuhkan akun EteSync.com atau server hosting-mandiri - Ingat kata sandi enkripsi yang Anda pilih, sandi tidak akan dapat dipulihkan! - Sandi enkripsi salah Bantuan & umpanbalik Dokumentasi Tampilan dan gaya diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 87a0dcbe3..285744a50 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -434,12 +434,7 @@ Personalizzato Le attività spariranno immediatamente dalla lista dopo il completamento Riduci saturazione colori - Ricorda la password di cifratura che hai scelto, non può essere recuperata! Passa alla versione premium - Conferma password di cifratura - Password di cifratura - Password di cifratura sbagliata - È richiesta la password di cifratura Condividi Seleziona tutto Creato evento nel calendario per %s @@ -495,7 +490,6 @@ Password Predefinito del sistema Icona - Le password non corrispondono Ignora le modifiche %d attività secondaria diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 80b00549f..b5407b9c6 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -493,8 +493,6 @@ תכונה זו דורשת מנוי עזרה ומשוב שגיאה: %s - אשר את סיסמת ההצפנה - סיסמת הצפנה מוסתר מתחת לכותרת לאחר הכותרת @@ -525,8 +523,6 @@ יישומון בחירת זמן טקסט וסמל - סיסמת הצפנה שגויה - דרושה סיסמת הצפנה בטל שינויים תתי משימות הצג חוצצים @@ -557,7 +553,6 @@ אטימות הכותרת התחתונה אטימות כותרת אטימות שורה - הססמאות אינן תואמות מחר בלילה מחר בערב אתמול @@ -580,7 +575,6 @@ הצגת התראות על המחשוב הלביש שלך התראות על מחשוב לביש תיעוד - עליך לזכור את ססמת ההצפנה שבחרת, אי אפשר לשחזר אותה! דורש חשבון אצל EteSync.com או שרת באירוח עצמי דורש חשבון עם ספק שירות CalDAV או שרת באירוח עצמי. ניתן למצוא ספק שירות תחת tasks.org/caldav נשמח לשמוע איך החוויה שלך diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 159835456..41d5759ab 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -466,7 +466,6 @@ ヘッダーの透明度 地図のテーマ デフォルトのタグ - 暗号化パスワードが必要です 変更を破棄 明日の夜 明日の夕方 @@ -514,8 +513,6 @@ ドロワーメニューをカスタマイズ 表示名 エラー:%s - 暗号化パスワードを確認 - 暗号化パスワード Tasks.org アカウント %sをクリップボードにコピーしました 場所を追加 diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 6346ae772..140baee08 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -454,20 +454,14 @@ 제목 입력 태그 이름 입력 \"%s\" 생성 - 암호화 비밀번호 필수 - 암호화 비밀번호 이 기능을 사용하려면 구독해야 합니다 플랫폼 선택 기본 서비스는 구글 계정과 동기화합니다 개방형 인터넷 표준을 바탕으로 한 동기화 종단간 암호화된 동기화 - 비밀번호가 일치하지 않습니다 - 암호화 비밀번호 확인 고급 설정 표시 CalDAV 서비스 제공업체나 자체호스팅 서버의 계정이 필요합니다. tasks.org/caldav에 방문하여 서비스 제공업체를 찾아보세요 EteSync.com이나 자체호스팅 서버의 계정 필요 - 선택하신 암호화 비밀번호를 기억하세요. 복구가 불가능합니다! - 잘못된 암호화 비밀번호 공유 모두 선택 마감시간 없음 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index ef7a0b218..d1183aefd 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -487,7 +487,6 @@ Papildomi nustatymai Išjungti baterijos optimizaciją Išvaizda - Slaptažodžiai nesutampa Šiai funkcijai reikalinga prenumerata Piktograma Tik piktograma @@ -620,13 +619,9 @@ Atnaujinti prenumeratą Pagalba ir atsiliepimai Klaida: %s - Patvirtinkite šifravimo slaptažodį - Šifravimo slaptažodis Perplanuoti užduotį Paspaudus Numatytosios etiketės - Neteisingas šifravimo slaptažodis - Reikalingas šifravimo slaptažodis %s m. Antrinės užduotys Rodyti skirtukus @@ -724,7 +719,6 @@ Dėvimo įrenginio pranešimai Paprasta paslauga, kuri atlieka sinchronizaciją su jūsų Google paskyra Bakstelėkite čia, jei kyla problemų dėl pranešimų - Prisiminkite pasirinktą šifravimo slaptažodį, jo negalima bus atkurti! Reikia paskyros EteSync.com arba asmeninis serveris Reikia paskyros pas CalDAV paslaugų teikėją arba turėti asmeninį serverį. Paslaugų teikėją raskite apsilankę tasks.org/caldav Failais paremta sinchronizacija diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 93dc2c7e1..1f8f82a9f 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -459,18 +459,12 @@ Gjøremålssteg med flere nivåer støttes ikke av Google Tasks Skriv inn etikettnavn Opprett «%s» - Krypteringspassord kreves - Krypteringspassord Visningsnavn Denne funksjonen krever abonnement Velg en plattform Enkel tjeneste som synkroniserer med Google-kontoen din - Passordene samsvarer ikke - Bekreft krypteringspassord Vis avanserte innstillinger Krever en konto hos EteSync.com eller selvdrevet tjener - Husk krypteringspassordet du velger, det kan ikke gjenopprettes! - Feil krypteringspassord Hjelp og tilbakemelding Dokumentasjon Avansert diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index ecb1816ce..5fbcad98d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -454,21 +454,15 @@ Voer titel in Voer label naam in Maak \"%s\" aan - Coderingswachtwoord vereist - Coderingswachtwoord Weergavenaam Deze functionaliteit vereist een abonnement Selecteer een platform Basisservice die synchroniseert met uw Google-account Synchronisatie gebaseerd op open internetstandaarden End-to-end versleutelde synchronisatie - Wachtwoorden komen niet overeen - Bevestig coderingswachtwoord Toon geavanceerde instellingen Vereist een account bij een CalDAV dienstverlener of een eigen server. Vind een dienstverlener door tasks.org/caldav te bezoeken Vereist een account op EteSync.com of een eigen server - Onthoud het coderingswachtwoord dat je kiest, want het kan niet worden hersteld! - Fout coderingswachtwoord Hulp & feedback Documentatie Uiterlijk diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 60d77acf6..a50ca6443 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -470,21 +470,15 @@ Wprowadź tytuł Wprowadź nazwę tagu Stwórz \"%s\" - Wymagane hasło szyfrowania - Hasło szyfrowania Imię Ta funkcja wymaga subskrypcji Wybierz platformę Podstawowy serwis, synchronizujący dane z Twoim kontem Google Synchronizacja oparta na otwartych standardach Szyfrowana synchronizacja end-to-end - Hasła nie zgadzają się - Potwierdź hasło szyfrowania Pokaż ustawienia zaawansowane Wymaga konta u dostawcy usług CalDAV lub własnego serwera. Znajdź dostawcę usług na tasks.org/caldav Wymaga konta na EteSync.com lub własnego serwera - Zapamiętaj wybrane hasło szyfrowania, nie da się go odzyskać! - Nieprawidłowe hasło szyfrowania Pomoc i opinie Dokumentacja Wygląd diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 711d6c43a..b4ae5f951 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -471,7 +471,6 @@ Documentação Avançado Interface e experiência do usuário - Lembre-se da senha de encriptação que você escolheu, ela não pode ser recuperada! Precisa de uma conta com EteSync.com ou uma instância desse serviço auto-hospedada Precisa de uma conta com um provedor CalDAV. Encontre um provedor visitando tasks.org/caldav Mostrar configurações avançadas @@ -503,8 +502,6 @@ ", " Erro: %s URL - Confirme a senha de criptografia - Senha de criptografia Escondido Abaixo do título Depois do título @@ -520,9 +517,6 @@ Opacidade do rodapé Opacidade da Linha Opacidade do Cabeçalho - Senhas não conferem - Senha de encriptação errada - Senha de encriptação necessária Amanhã à noite Amanhã à tardinha %s m diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index d0f9f67e9..d6cd6edca 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -531,20 +531,14 @@ Aparência Documentação Ajuda e comentários - A palavra-passe de encriptação está errada - Lembre-se da palavra-passe de encriptação que escolheu, ela não pode ser recuperada! Precisa de uma conta no EteSync.com ou de um servidor auto-alojado Precisa de uma conta com um fornecedor CalDAV ou de um servidor auto-alojado. Encontre um fornecedor visitando tasks.org/caldav Mostrar configurações avançadas - Confirme a palavra-passe de encriptação - As palavras-passe não coincidem Sincronização com encriptação ponta-a-ponta Serviço básico que sincroniza com a sua conta Google Selecione uma plataforma Este recurso necessita de uma subscrição Mostrar nome - Palavra-passe de encriptação - É necessária uma palavra-passe de encriptação Criar \"%s\" Digite o nome da etiqueta Digite um título diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 62d8a43da..130b6e66b 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -155,8 +155,6 @@ Optimizările bateriei pot întârzia notificările Eroare: %s URL - Confirmați parola de criptare - Parola de criptare Parola Utilizator Adăugați un cont @@ -211,8 +209,6 @@ Trebuie să înceapă cu http(s):// Numele de gazdă necesar URL necesar - Parolă de criptare greșită - Parolă de criptare necesară Parolă necesară Nume de utilizator necesar Numele nu poate fi gol @@ -644,7 +640,6 @@ Documentație Avansat Aspect și senzație - Țineți minte parola de criptare pe care o alegeți, aceasta nu poate fi recuperată! Necesită un cont cu EteSync.com sau un server auto-găzduit Necesită un cont la un furnizor de servicii CalDAV sau un server găzduit de sine stătător. Găsiți un furnizor de servicii vizitând tasks.org/caldav Afișați setările avansate @@ -700,7 +695,6 @@ Necesită un abonament pro Extinderea ceasului de bord Tasks este un software libre open-source, licențiat sub licența GNU General Public License v3.0 - Parolele nu se potrivesc Cronometre active pentru %s! Ștergeți %s\? Creați o nouă listă diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index ea893367e..6995dd624 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -475,21 +475,15 @@ Введите название Введите имя тега Создать \"%s\" - Требуется пароль шифрования - Пароль шифрования Отображаемое название Эта функция требует подписки Выберите платформу Простой сервис, который синхронизируется с Вашим аккаунтом Google Синхронизация, основанная на открытых стандартах Сквозная зашифрованная синхронизация - Пароли не совпадают - Подтвердите пароль шифрования Показать расширенные настройки Требует аккаунта у провайдера CalDAV или собственного сервера. Список провайдеров можно найти на tasks.org/caldav Требует аккаунта на EteSync.com или собственного сервера - Запомните выбранный пароль шифрования, его нельзя будет восстановить! - Неверный пароль шифрования Помощь и обратная связь Документация Внешний вид diff --git a/app/src/main/res/values-si/strings.xml b/app/src/main/res/values-si/strings.xml index 491a6f9ae..3c3c52e66 100644 --- a/app/src/main/res/values-si/strings.xml +++ b/app/src/main/res/values-si/strings.xml @@ -186,8 +186,6 @@ ලාංඡන බැටරි ප්‍රශස්තිකරණය මඟින් දැනුම්දීම් ප්‍රමාද විය හැක URL - සංකේතන මුරපදය තහවුරු කරන්න - සංකේතන මුරපදය මුරපදය පරිශීලක ගිණුම එක් කරන්න @@ -241,7 +239,6 @@ ප්‍රලේඛනය උසස් පෙනුම හා පහසුව - ඔබ තෝරාගත් සංකේතාත්මක මුරපදය මතක තබා ගන්න, එය නැවත ලබා ගත නොහැක! EteSync.com හෝ ස්වයං සත්කාරක සේවාදායකයක් සමඟ ගිණුමක් අවශ්‍ය වේ CalDAV සේවා සැපයුම්කරුවෙකු හෝ ස්වයං සත්කාරක සේවාදායකයක් සමඟ ගිණුමක් අවශ්‍ය වේ. tasks.org/caldav වෙත පිවිසීමෙන් සේවා සපයන්නෙකු සොයා ගන්න උසස් සැකසුම් පෙන්වන්න @@ -629,9 +626,6 @@ http(s):// වලින් ආරම්භවිය යුතුය ධාරක නාමය (Hostname) අවශ්‍යයි URL අවශ්‍යයි - මුර පද නොගැලපේ - වැරදි සංකේතාත්මක මුරපදයකි - සංකේතාත්මක මුරපදය අවශ්‍යයි මුරපදය අවශ්‍යයි පරිශීලක නාමය අවශ්‍යයි නම හිස්ව තැබිය නොහැකිය diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 2e28275f8..98e48f81b 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -632,7 +632,6 @@ Visa meddelanden på din wearable Meddelanden som kan bäras Utseende - Kom ihåg krypteringslösenordet du väljer, det kan inte återställas! Synkronisera dina uppgifter med DAVx⁵-appen Filbaserad synkronisering Krypterad synkronisering från slut till slut @@ -649,8 +648,6 @@ Vad är nytt Denna funktion kräver en prenumeration Prenumeration - Bekräfta krypteringslösenordet - Krypteringslösenord Under rubriken Efter titeln Omplanera uppgiften @@ -663,9 +660,6 @@ Opacitet för rubriken Standardåterkomst Standardtaggar - Lösenorden stämmer inte överens - Felaktigt krypteringslösenord - Krypteringslösenord krävs Ingen app kunde hantera den här begäran Ej påbörjad Visa ostartat diff --git a/app/src/main/res/values-ta/strings.xml b/app/src/main/res/values-ta/strings.xml index d11484a3e..261be23c2 100644 --- a/app/src/main/res/values-ta/strings.xml +++ b/app/src/main/res/values-ta/strings.xml @@ -233,7 +233,6 @@ ஆவணம் மேம்படுத்தபட்ட பார்க்கவும் உணரவும் - நீங்கள் தேர்ந்தெடுத்த குறியாக்க கடவுச்சொல்லை நினைவில் கொள்ளுங்கள், அதை மீட்டெடுக்க முடியாது! EteSync.com அல்லது சுய ஹோஸ்ட் செய்த சேவையகத்துடன் கணக்கு தேவை CalDAV சேவை வழங்குநர் அல்லது சுய ஹோஸ்ட் செய்த சேவையகத்துடன் கணக்கு தேவை. Tasks.org/caldav ஐப் பார்வையிடுவதன் மூலம் ஒரு சேவை வழங்குநரைக் கண்டறியவும் மேம்பட்ட அமைப்புகளைக் காட்டு @@ -324,8 +323,6 @@ பேட்டரி மேம்படுத்தல்கள் அறிவிப்புகளை தாமதப்படுத்தக்கூடும் பிழை: %s URL - குறியாக்க கடவுச்சொல்லை உறுதிப்படுத்தவும் - குறியாக்க கடவுச்சொல் கடவுச்சொல் பயனர் கணக்கு சேர்க்க @@ -377,9 +374,6 @@ Http (கள்) உடன் தொடங்க வேண்டும்: // ஹோஸ்ட்பெயர் தேவை URL தேவை - கடவுச்சொற்கள் பொருந்தவில்லை - தவறான குறியாக்க கடவுச்சொல் - குறியாக்க கடவுச்சொல் தேவை கடவுச்சொல் தேவை பயனர்பெயர் தேவை பெயர் காலியாக இருக்க முடியாது diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml index 0bcbb41dd..cf183bf1b 100644 --- a/app/src/main/res/values-th/strings.xml +++ b/app/src/main/res/values-th/strings.xml @@ -177,7 +177,6 @@ เอกสาร ดึก ลักษณะและความรู้สึก - จํารหัสผ่านการเข้ารหัสที่คุณเลือกมันไม่สามารถกู้คืนได้! ต้องการบัญชีผู้ใช้ที่มี EteSync.com หรือเซิร์ฟเวอร์ที่โฮสต์ด้วยตนเอง จําเป็นต้องมีบัญชีผู้ใช้กับผู้ให้บริการ CalDAV หรือเซิร์ฟเวอร์ที่โฮสต์ด้วยตนเอง ค้นหาผู้ให้บริการโดยไปที่ tasks.org/caldav แสดงการตั้งค่าขั้นสูง @@ -287,8 +286,6 @@ การเพิ่มประสิทธิภาพแบตเตอรี่อาจทําให้การแจ้งเตือนล่าช้า ข้อผิดพลาด: %s URL - ยืนยันรหัสผ่านการเข้ารหัส - รหัสผ่านการเข้ารหัสลับ รหัสผ่าน ผู้ใช้ เพิ่มบัญชี @@ -344,9 +341,6 @@ ต้องเริ่มต้นด้วย http(s):// ต้องการชื่อโฮสต์ URL ที่ต้องการ - รหัสผ่านไม่ตรงกัน - รหัสผ่านการเข้ารหัสลับไม่ถูกต้อง - ต้องใช้รหัสผ่านการเข้ารหัส ต้องใช้รหัสผ่าน ต้องการชื่อผู้ใช้ ชื่อไม่สามารถปล่อยให้ว่างได้ diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 1fdc1cca3..ffd28bcf5 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -459,21 +459,15 @@ Başlık girin Etiket adı girin \"%s\" oluştur - Şifreleme parolası gerekli - Şifreleme parolası Gösterim adı Bu özellik abonelik gerektiriyor Platform seç Google hesabınızla eşzamanlayan basit servis Açık internet standartlarında eşzamanlama Uçtan uca şifreli eşzamanlama - Parolalar eşleşmiyor - Şifreleme parolasını doğrula Gelişmiş ayarları göster CalDAV servis sağlayıcılı hesap veya kendi kendine barındırılan sunucu gerekir. tasks.org/caldav adresinden servis sağlayıcı bulun EteSync.com hesabı veya kendi kendine barındırılan sunucu gerektirir - Seçtiğiniz şifreleme parolasını anımsayın, bu kurtarılamazdır! - Yanlış şifreleme parolası Yardım ve geri bildirim Belgelendirme Görünüm ve his diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 1b5f8d028..afaf9e6c3 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -455,7 +455,6 @@ Помилка: %s URL Піктограма - Паролі не співпадають Скасувати зміни Підзадачі Завдання негайно зникатимуть зі списку після їх завершення @@ -478,14 +477,9 @@ %d підзавдань Google Tasks - Підтвердіть пароль шифрування - Пароль шифрування - Потрібен пароль шифрування - Невірний пароль шифрування Показувати повідомлення на натільних пристроях Повідомлення на натільні пристрої Документація - Запам\'ятайте свій пароль шифрування. Його неможливо відновити! Потрібний обліковий запис у EteSync.com або власний сервер Потрібний обліковий запис у провайдера сервісу CalDAV або власний сервер. Відвідайте tasks.org/caldav, щоб переглянути список провайдерів Захищена наскрізним шифруванням синхронізація diff --git a/app/src/main/res/values-ur/strings.xml b/app/src/main/res/values-ur/strings.xml index fa6e26e19..9ed77afe9 100644 --- a/app/src/main/res/values-ur/strings.xml +++ b/app/src/main/res/values-ur/strings.xml @@ -404,9 +404,6 @@ http(s):// کے ساتھ شروع ہونا ضروری ہے ہوسٹ کا نام مطلوب ہے یو آر ایل مطلوب ہے - پاسورڈز ایک جیسے نہیں ہیں - غلط انکرپشن پاسورڈ - انکرپشن پاسورڈ مطلوب ہے پاسورڈ مطلوب ہے صارف کا نام مطلوب ہے نام خالی نہیں ہو سکتا @@ -418,8 +415,6 @@ بیٹری کی بچت نوٹیفیکیشنز کو ملتوی کر سکتی ہے ایرر:%s یو آر ایل - انکرپشن پاسورڈ کی تصدیق کریں - انکرپشن پاسورڈٖ پاسورڈ صارف اکاؤنٹ داخل کریں diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 9297d3fe2..e844e4efd 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -348,8 +348,6 @@ Tối ưu hoá pin có thể sẽ gây trì hoãn các thông báo Lỗi: %s URL - Xác nhận mật khẩu mã hoá - Mật khẩu mã hoá Mật khẩu Người dùng Thêm tài khoản @@ -405,9 +403,6 @@ Phải bắt đầu bằng http(s):// Yêu cầu tên miền máy chủ Yêu cầu URL - Mật khẩu không trùng khớp - Sai mật khẩu mã hoá - Yêu cầu mật khẩu mã hoá Yêu cầu mật khẩu Yêu cầu tên người dùng Tên không thể trống @@ -656,7 +651,6 @@ Không có lời nhắc Nâng cao Ngoại hình - Hãy nhớ mật khẩu mã hoá mà bạn chọn, nó không thể được phục hồi! Yêu cầu một tài khoản trên EteSync.com hoặc một máy chủ mà bạn vận hành Yêu cầu một tài khoản với một nhà cung cấp dịch vụ CalDAV hoặc một máy chủ mà bạn vận hành. Hãy tìm một nhà cung cấp dịch vụ bằng cách đi đến tasks.org/caldav Tuần sau diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index b04eefdd4..97998b1e1 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -449,21 +449,15 @@ 输入标题 输入标签名称 创建\"%s\" - 需要加密密码 - 加密密码 显示名称 该功能需要订阅 选择平台 基本服务,用你的谷歌账户进行数据同步 基于开放的互联网标准的同步 端到端加密的同步 - 密码不匹配 - 确认加密密码 显示高级设置 需要一个 CalDAV 服务供应商账户或一个自托管服务器。访问 tasks.org/caldav 寻找服务供应商 需要一个EteSync.com账户或一个自托管服务器 - 记住你挑选的密码,它不能被恢复! - 错误的加密密码 帮助&反馈 文档 外观和感觉 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index a6813d482..faf518470 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -468,8 +468,6 @@ 電池最佳化可能使通知延遲 錯誤: %s URL - 確認加密密碼 - 加密密碼 密碼 使用者名稱 新增帳號 @@ -513,9 +511,6 @@ 必須由 http(s):// 開頭 需要主機名稱 需要URL - 密目不相符 - 加密密碼錯誤 - 需要加密密碼 需要密碼 需要使用者名稱 尚未開始 diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index 075c8b938..6ec1a5cb1 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -15,7 +15,7 @@ DecSync CC Tasks.org https://api.etesync.com - Native EteSync v1 support is deprecated and will be removed soon! Please switch to the EteSync client to continue synchronizing your EteSync v1 account, or migrate to EteSync v2 + Native EteSync v1 support has been removed. Please switch to the EteSync client to continue synchronizing your EteSync v1 account, or migrate to EteSync v2 https://api.etebase.com/partner/tasksorg/ https://tasks.org/sync @@ -384,7 +384,6 @@ debug_crash_main_queries sync_ongoing_google_tasks sync_ongoing_caldav - sync_ongoing_etesync sync_ongoing_etebase sync_ongoing_opentasks sync_ongoing_android @@ -443,7 +442,6 @@ cp_astrid2taskprovider sync_add_account sync_unknown_access - legacy_etesync type map_theme picker_mode_date diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 75dd36d7f..45d9e9dc4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -379,9 +379,6 @@ File %1$s contained %2$s.\n\n Name cannot be empty Username required Password required - Encryption password required - Wrong encryption password - Passwords do not match URL required Hostname required Must begin with http(s):// @@ -437,8 +434,6 @@ File %1$s contained %2$s.\n\n Add account User Password - Encryption password - Confirm encryption password URL Error: %s Battery optimizations may delay notifications @@ -547,7 +542,6 @@ File %1$s contained %2$s.\n\n Show advanced settings Requires an account with a CalDAV service provider or a self-hosted server. Find a service provider by visiting tasks.org/caldav Requires an account with EteSync.com or a self-hosted server - Remember the encryption password you pick, it cannot be recovered! Look and feel Advanced Documentation diff --git a/deps_fdroid.txt b/deps_fdroid.txt index 50f44bd66..7dd3a1182 100644 --- a/deps_fdroid.txt +++ b/deps_fdroid.txt @@ -374,20 +374,10 @@ +| +--- androidx.work:work-runtime:2.7.0 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.5.30 -> 1.5.31 (*) +| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0 -> 1.5.2 (*) -++--- com.etesync:journalmanager:1.1.1 -+| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.5.31 (*) -+| +--- com.madgag.spongycastle:core:1.54.0.0 -+| +--- com.madgag.spongycastle:prov:1.54.0.0 -+| | \--- com.madgag.spongycastle:core:1.54.0.0 -+| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 -+| | \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*) -+| +--- com.google.code.gson:gson:1.7.2 -> 2.8.8 -+| +--- org.apache.commons:commons-collections4:4.1 -+| +--- org.apache.commons:commons-lang3:3.8.1 -+| \--- commons-codec:commons-codec:1.7 -> 1.11 ++--- com.etebase:client:2.3.2 +| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0 -+| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 (*) ++| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 ++| \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*) ++--- com.github.QuadFlask:colorpicker:0.0.15 +| \--- androidx.appcompat:appcompat:1.1.0 -> 1.3.1 (*) ++--- net.openid:appauth:0.8.1 diff --git a/deps_googleplay.txt b/deps_googleplay.txt index 954e2f893..5872870b8 100644 --- a/deps_googleplay.txt +++ b/deps_googleplay.txt @@ -493,20 +493,10 @@ +| +--- androidx.work:work-runtime:2.7.0 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.5.30 -> 1.5.31 (*) +| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0 -> 1.5.2 (*) -++--- com.etesync:journalmanager:1.1.1 -+| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.5.31 (*) -+| +--- com.madgag.spongycastle:core:1.54.0.0 -+| +--- com.madgag.spongycastle:prov:1.54.0.0 -+| | \--- com.madgag.spongycastle:core:1.54.0.0 -+| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 -+| | \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*) -+| +--- com.google.code.gson:gson:1.7.2 -> 2.8.8 -+| +--- org.apache.commons:commons-collections4:4.1 -+| +--- org.apache.commons:commons-lang3:3.8.1 -+| \--- commons-codec:commons-codec:1.7 -> 1.11 ++--- com.etebase:client:2.3.2 +| +--- androidx.annotation:annotation:1.1.0 -> 1.2.0 -+| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 (*) ++| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 ++| \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*) ++--- com.github.QuadFlask:colorpicker:0.0.15 +| \--- androidx.appcompat:appcompat:1.1.0 -> 1.3.1 (*) ++--- net.openid:appauth:0.8.1