mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
7.2 KiB
Kotlin
216 lines
7.2 KiB
Kotlin
package org.tasks.caldav
|
|
|
|
import android.app.Activity
|
|
import android.content.Intent
|
|
import android.os.Bundle
|
|
import androidx.compose.foundation.layout.ColumnScope
|
|
import androidx.compose.material3.SnackbarHostState
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.lifecycle.lifecycleScope
|
|
import at.bitfire.dav4jvm.exception.HttpException
|
|
import com.todoroo.astrid.activity.MainActivity
|
|
import com.todoroo.astrid.activity.TaskListFragment
|
|
import com.todoroo.astrid.service.TaskDeleter
|
|
import kotlinx.coroutines.launch
|
|
import kotlinx.coroutines.runBlocking
|
|
import org.tasks.R
|
|
import org.tasks.Strings.isNullOrEmpty
|
|
import org.tasks.activities.BaseListSettingsActivity
|
|
import org.tasks.compose.DeleteButton
|
|
import org.tasks.compose.ListSettings.Toaster
|
|
import org.tasks.data.UUIDHelper
|
|
import org.tasks.data.dao.CaldavDao
|
|
import org.tasks.data.entity.CaldavAccount
|
|
import org.tasks.data.entity.CaldavCalendar
|
|
import org.tasks.filters.CaldavFilter
|
|
import org.tasks.themes.TasksIcons
|
|
import org.tasks.ui.DisplayableException
|
|
import java.net.ConnectException
|
|
import javax.inject.Inject
|
|
|
|
abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() {
|
|
@Inject lateinit var caldavDao: CaldavDao
|
|
@Inject lateinit var taskDeleter: TaskDeleter
|
|
|
|
protected var caldavCalendar: CaldavCalendar? = null
|
|
|
|
protected lateinit var caldavAccount: CaldavAccount
|
|
override val defaultIcon = TasksIcons.LIST
|
|
|
|
protected val snackbar = SnackbarHostState() // to be used by descendants
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
val intent = intent
|
|
caldavCalendar = intent.getParcelableExtra(EXTRA_CALDAV_CALENDAR)
|
|
super.onCreate(savedInstanceState)
|
|
caldavAccount = if (caldavCalendar == null) {
|
|
intent.getParcelableExtra(EXTRA_CALDAV_ACCOUNT)!!
|
|
} else {
|
|
runBlocking { caldavDao.getAccountByUuid(caldavCalendar!!.account!!)!! }
|
|
}
|
|
if (savedInstanceState == null) {
|
|
if (caldavCalendar != null) {
|
|
textState.value = caldavCalendar!!.name ?: ""
|
|
selectedColor = caldavCalendar!!.color
|
|
selectedIcon.value = caldavCalendar?.icon ?: defaultIcon
|
|
}
|
|
}
|
|
updateTheme()
|
|
}
|
|
|
|
override val isNew: Boolean
|
|
get() = caldavCalendar == null
|
|
|
|
override val toolbarTitle: String
|
|
get() = if (isNew) getString(R.string.new_list) else caldavCalendar!!.name ?: ""
|
|
|
|
override suspend fun save() {
|
|
if (requestInProgress()) {
|
|
return
|
|
}
|
|
val name = newName
|
|
if (isNullOrEmpty(name)) {
|
|
errorState.value = getString(R.string.name_cannot_be_empty)
|
|
return
|
|
}
|
|
when {
|
|
caldavCalendar == null -> {
|
|
showProgressIndicator()
|
|
createCalendar(caldavAccount, name, selectedColor)
|
|
}
|
|
nameChanged() || colorChanged() -> {
|
|
showProgressIndicator()
|
|
updateNameAndColor(caldavAccount, caldavCalendar!!, name, selectedColor)
|
|
}
|
|
iconChanged() -> updateCalendar()
|
|
else -> finish()
|
|
}
|
|
}
|
|
|
|
protected abstract suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int)
|
|
|
|
protected abstract suspend fun updateNameAndColor(
|
|
account: CaldavAccount, calendar: CaldavCalendar, name: String, color: Int)
|
|
|
|
protected abstract suspend fun deleteCalendar(
|
|
caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar
|
|
)
|
|
|
|
private fun showProgressIndicator() { showProgress.value = true }
|
|
|
|
private fun hideProgressIndicator() { showProgress.value = false }
|
|
|
|
protected fun requestInProgress(): Boolean = showProgress.value
|
|
|
|
protected fun requestFailed(t: Throwable) {
|
|
hideProgressIndicator()
|
|
when (t) {
|
|
is HttpException -> showSnackbar(t.message)
|
|
is retrofit2.HttpException -> showSnackbar(t.message() ?: "HTTP ${t.code()}")
|
|
is DisplayableException -> showSnackbar(t.resId)
|
|
is ConnectException -> showSnackbar(R.string.network_error)
|
|
else -> showSnackbar(R.string.error_adding_account, t.message!!)
|
|
}
|
|
return
|
|
}
|
|
|
|
private fun showSnackbar(resId: Int, vararg formatArgs: Any) {
|
|
lifecycleScope.launch { snackbar.showSnackbar( getString(resId, *formatArgs) ) }
|
|
}
|
|
|
|
private fun showSnackbar(message: String?) {
|
|
lifecycleScope.launch { snackbar.showSnackbar( message!! ) }
|
|
}
|
|
|
|
protected suspend fun createSuccessful(url: String?) {
|
|
val caldavCalendar = CaldavCalendar(
|
|
uuid = UUIDHelper.newUUID(),
|
|
account = caldavAccount.uuid,
|
|
url = url,
|
|
name = newName,
|
|
color = selectedColor,
|
|
icon = selectedIcon.value,
|
|
)
|
|
caldavDao.insert(caldavCalendar)
|
|
setResult(
|
|
Activity.RESULT_OK,
|
|
Intent().putExtra(MainActivity.OPEN_FILTER, CaldavFilter(caldavCalendar)))
|
|
finish()
|
|
}
|
|
|
|
protected suspend fun updateCalendar() {
|
|
val result = caldavCalendar!!.copy(
|
|
name = newName,
|
|
color = selectedColor,
|
|
icon = selectedIcon.value,
|
|
)
|
|
caldavDao.update(result)
|
|
setResult(
|
|
Activity.RESULT_OK,
|
|
Intent(TaskListFragment.ACTION_RELOAD)
|
|
.putExtra(MainActivity.OPEN_FILTER, CaldavFilter(result)))
|
|
finish()
|
|
}
|
|
|
|
override fun hasChanges(): Boolean =
|
|
if (caldavCalendar == null)
|
|
!isNullOrEmpty(newName) || selectedColor != 0 || selectedIcon.value?.isBlank() == false
|
|
else
|
|
nameChanged() || iconChanged() || colorChanged()
|
|
|
|
private fun nameChanged(): Boolean = caldavCalendar!!.name != newName
|
|
|
|
private fun colorChanged(): Boolean = selectedColor != caldavCalendar!!.color
|
|
|
|
private fun iconChanged(): Boolean = selectedIcon.value != caldavCalendar!!.icon
|
|
|
|
private val newName: String
|
|
get() = textState.value.trim { it <= ' '}
|
|
|
|
override fun finish() {
|
|
// hideKeyboard(name)
|
|
super.finish()
|
|
}
|
|
|
|
override fun discard() {
|
|
if (!requestInProgress()) {
|
|
super.discard()
|
|
}
|
|
}
|
|
|
|
override fun promptDelete() {
|
|
if (!requestInProgress()) {
|
|
super.promptDelete()
|
|
}
|
|
}
|
|
|
|
override suspend fun delete() {
|
|
showProgressIndicator()
|
|
deleteCalendar(caldavAccount, caldavCalendar!!)
|
|
}
|
|
|
|
protected suspend fun onDeleted(deleted: Boolean) {
|
|
if (deleted) {
|
|
taskDeleter.delete(caldavCalendar!!)
|
|
setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED))
|
|
finish()
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
fun baseCaldavSettingsContent (
|
|
optionButton: @Composable () -> Unit = { if (!isNew) DeleteButton { promptDelete() } },
|
|
extensionContent: @Composable ColumnScope.() -> Unit = {}
|
|
) {
|
|
baseSettingsContent (
|
|
optionButton = optionButton,
|
|
extensionContent = extensionContent
|
|
)
|
|
Toaster(state = snackbar)
|
|
}
|
|
|
|
companion object {
|
|
const val EXTRA_CALDAV_CALENDAR = "extra_caldav_calendar"
|
|
const val EXTRA_CALDAV_ACCOUNT = "extra_caldav_account"
|
|
}
|
|
} |