mirror of https://github.com/tasks/tasks
Create, rename, and delete microsoft lists
parent
1793d95d4d
commit
d589a89506
@ -0,0 +1,18 @@
|
|||||||
|
package org.tasks.sync.microsoft
|
||||||
|
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import retrofit2.Response
|
||||||
|
|
||||||
|
data class Error(
|
||||||
|
val error: ErrorBody,
|
||||||
|
) {
|
||||||
|
data class ErrorBody(
|
||||||
|
val code: String,
|
||||||
|
val message: String,
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun <T> Response<T>.toMicrosoftError()
|
||||||
|
= errorBody()?.string()?.let { Gson().fromJson(it, Error::class.java) }
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
package org.tasks.sync.microsoft
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.activity.viewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.todoroo.astrid.activity.MainActivity
|
||||||
|
import com.todoroo.astrid.activity.TaskListFragment
|
||||||
|
import com.todoroo.astrid.api.CaldavFilter
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import org.tasks.caldav.BaseCaldavCalendarSettingsActivity
|
||||||
|
import org.tasks.data.CaldavAccount
|
||||||
|
import org.tasks.data.CaldavCalendar
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
class MicrosoftListSettingsActivity : BaseCaldavCalendarSettingsActivity() {
|
||||||
|
private val viewModel: MicrosoftListSettingsActivityViewModel by viewModels()
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
viewModel
|
||||||
|
.viewState
|
||||||
|
.collect { state ->
|
||||||
|
state.error?.let { throwable ->
|
||||||
|
requestFailed(throwable)
|
||||||
|
viewModel.clearError()
|
||||||
|
}
|
||||||
|
if (state.deleted) {
|
||||||
|
setResult(Activity.RESULT_OK, Intent(TaskListFragment.ACTION_DELETED))
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
state.result?.let {
|
||||||
|
setResult(
|
||||||
|
Activity.RESULT_OK,
|
||||||
|
Intent(TaskListFragment.ACTION_RELOAD).putExtra(
|
||||||
|
MainActivity.OPEN_FILTER,
|
||||||
|
CaldavFilter(it)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) =
|
||||||
|
viewModel.createList(name)
|
||||||
|
|
||||||
|
override suspend fun updateNameAndColor(
|
||||||
|
account: CaldavAccount,
|
||||||
|
calendar: CaldavCalendar,
|
||||||
|
name: String,
|
||||||
|
color: Int
|
||||||
|
) = viewModel.updateList(name)
|
||||||
|
|
||||||
|
override suspend fun deleteCalendar(
|
||||||
|
caldavAccount: CaldavAccount,
|
||||||
|
caldavCalendar: CaldavCalendar
|
||||||
|
) = viewModel.deleteList()
|
||||||
|
}
|
@ -0,0 +1,102 @@
|
|||||||
|
package org.tasks.sync.microsoft
|
||||||
|
|
||||||
|
import androidx.lifecycle.SavedStateHandle
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.google.gson.Gson
|
||||||
|
import com.todoroo.astrid.service.TaskDeleter
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
import okhttp3.RequestBody.Companion.toRequestBody
|
||||||
|
import org.tasks.caldav.BaseCaldavCalendarSettingsActivity
|
||||||
|
import org.tasks.data.CaldavAccount
|
||||||
|
import org.tasks.data.CaldavCalendar
|
||||||
|
import org.tasks.data.CaldavDao
|
||||||
|
import org.tasks.http.HttpClientFactory
|
||||||
|
import org.tasks.http.HttpClientFactory.Companion.MEDIA_TYPE_JSON
|
||||||
|
import retrofit2.HttpException
|
||||||
|
import retrofit2.Response
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class MicrosoftListSettingsActivityViewModel @Inject constructor(
|
||||||
|
savedStateHandle: SavedStateHandle,
|
||||||
|
private val httpClientFactory: HttpClientFactory,
|
||||||
|
private val caldavDao: CaldavDao,
|
||||||
|
private val taskDeleter: TaskDeleter,
|
||||||
|
) : ViewModel() {
|
||||||
|
data class ViewState(
|
||||||
|
val requestInFlight: Boolean = false,
|
||||||
|
val result: CaldavCalendar? = null,
|
||||||
|
val error: Throwable? = null,
|
||||||
|
val deleted: Boolean = false,
|
||||||
|
)
|
||||||
|
|
||||||
|
private val _viewState = MutableStateFlow(ViewState())
|
||||||
|
val viewState = _viewState.asStateFlow()
|
||||||
|
|
||||||
|
private val account: CaldavAccount =
|
||||||
|
savedStateHandle[BaseCaldavCalendarSettingsActivity.EXTRA_CALDAV_ACCOUNT]!!
|
||||||
|
|
||||||
|
val list: CaldavCalendar? =
|
||||||
|
savedStateHandle[BaseCaldavCalendarSettingsActivity.EXTRA_CALDAV_CALENDAR]
|
||||||
|
|
||||||
|
suspend fun createList(displayName: String) {
|
||||||
|
_viewState.update { it.copy(requestInFlight = true) }
|
||||||
|
val microsoftService = httpClientFactory.getMicrosoftService(account)
|
||||||
|
val taskList = TaskLists.TaskList(displayName = displayName)
|
||||||
|
val body = Gson().toJson(taskList).toRequestBody(MEDIA_TYPE_JSON)
|
||||||
|
val result = microsoftService.createList(body)
|
||||||
|
if (result.isSuccessful) {
|
||||||
|
val list = CaldavCalendar().apply {
|
||||||
|
account = this@MicrosoftListSettingsActivityViewModel.account.uuid
|
||||||
|
result.body()?.applyTo(this)
|
||||||
|
}
|
||||||
|
caldavDao.insert(list)
|
||||||
|
_viewState.update { it.copy(result = list) }
|
||||||
|
} else {
|
||||||
|
requestFailed(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun deleteList() {
|
||||||
|
_viewState.update { it.copy(requestInFlight = true) }
|
||||||
|
val microsoftService = httpClientFactory.getMicrosoftService(account)
|
||||||
|
val result = microsoftService.deleteList(list?.uuid!!)
|
||||||
|
if (result.isSuccessful) {
|
||||||
|
taskDeleter.delete(list)
|
||||||
|
_viewState.update { it.copy(deleted = true) }
|
||||||
|
} else {
|
||||||
|
requestFailed(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun updateList(displayName: String) {
|
||||||
|
_viewState.update { it.copy(requestInFlight = true) }
|
||||||
|
val microsoftService = httpClientFactory.getMicrosoftService(account)
|
||||||
|
val taskList = TaskLists.TaskList(displayName = displayName)
|
||||||
|
val body = Gson().toJson(taskList).toRequestBody(MEDIA_TYPE_JSON)
|
||||||
|
val result = microsoftService.updateList(list?.uuid!!, body)
|
||||||
|
if (result.isSuccessful) {
|
||||||
|
result.body()?.applyTo(list)
|
||||||
|
caldavDao.update(list)
|
||||||
|
_viewState.update { it.copy(result = list) }
|
||||||
|
} else {
|
||||||
|
requestFailed(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearError() {
|
||||||
|
_viewState.update { it.copy(error = null) }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> requestFailed(result: Response<T>) {
|
||||||
|
_viewState.update {
|
||||||
|
it.copy(
|
||||||
|
requestInFlight = false,
|
||||||
|
error = HttpException(result),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue