Add support for setting a list's "exclusivity" option (#3932)

Fixes #3831
This commit is contained in:
Nik Clayton 2023-08-06 20:29:34 +02:00 committed by GitHub
commit 846289b8cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 101 additions and 109 deletions

View file

@ -23,8 +23,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.ImageButton
import android.widget.PopupMenu
import android.widget.TextView
@ -38,10 +36,10 @@ import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import at.connyduck.sparkbutton.helpers.Utils
import com.google.android.material.color.MaterialColors
import com.google.android.material.snackbar.Snackbar
import com.keylesspalace.tusky.databinding.ActivityListsBinding
import com.keylesspalace.tusky.databinding.DialogListBinding
import com.keylesspalace.tusky.di.Injectable
import com.keylesspalace.tusky.di.ViewModelFactory
import com.keylesspalace.tusky.entity.MastoList
@ -118,7 +116,7 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
viewModel.events.collect { event ->
when (event) {
Event.CREATE_ERROR -> showMessage(R.string.error_create_list)
Event.RENAME_ERROR -> showMessage(R.string.error_rename_list)
Event.UPDATE_ERROR -> showMessage(R.string.error_rename_list)
Event.DELETE_ERROR -> showMessage(R.string.error_delete_list)
}
}
@ -126,16 +124,9 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
}
private fun showlistNameDialog(list: MastoList?) {
val layout = FrameLayout(this)
val editText = EditText(this)
editText.setHint(R.string.hint_list_name)
layout.addView(editText)
val margin = Utils.dpToPx(this, 8)
(editText.layoutParams as ViewGroup.MarginLayoutParams)
.setMargins(margin, margin, margin, 0)
val binding = DialogListBinding.inflate(layoutInflater)
val dialog = AlertDialog.Builder(this)
.setView(layout)
.setView(binding.root)
.setPositiveButton(
if (list == null) {
R.string.action_create_list
@ -143,17 +134,26 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
R.string.action_rename_list
}
) { _, _ ->
onPickedDialogName(editText.text, list?.id)
onPickedDialogName(binding.nameText.text.toString(), list?.id, binding.exclusiveCheckbox.isChecked)
}
.setNegativeButton(android.R.string.cancel, null)
.show()
val positiveButton = dialog.getButton(Dialog.BUTTON_POSITIVE)
editText.doOnTextChanged { s, _, _, _ ->
positiveButton.isEnabled = s?.isNotBlank() == true
binding.nameText.let { editText ->
editText.doOnTextChanged { s, _, _, _ ->
dialog.getButton(Dialog.BUTTON_POSITIVE).isEnabled = s?.isNotBlank() == true
}
editText.setText(list?.title)
editText.text?.let { editText.setSelection(it.length) }
}
list?.let {
if (it.exclusive == null) {
binding.exclusiveCheckbox.visible(false)
} else {
binding.exclusiveCheckbox.isChecked = it.exclusive
}
}
editText.setText(list?.title)
editText.text?.let { editText.setSelection(it.length) }
}
private fun showListDeleteDialog(list: MastoList) {
@ -226,7 +226,7 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.list_edit -> openListSettings(list)
R.id.list_rename -> renameListDialog(list)
R.id.list_update -> renameListDialog(list)
R.id.list_delete -> showListDeleteDialog(list)
else -> return@setOnMenuItemClickListener false
}
@ -287,11 +287,11 @@ class ListsActivity : BaseActivity(), Injectable, HasAndroidInjector {
}
}
private fun onPickedDialogName(name: CharSequence, listId: String?) {
private fun onPickedDialogName(name: String, listId: String?, exclusive: Boolean) {
if (listId == null) {
viewModel.createNewList(name.toString())
viewModel.createNewList(name, exclusive)
} else {
viewModel.renameList(listId, name.toString())
viewModel.updateList(listId, name, exclusive)
}
}

View file

@ -22,5 +22,6 @@ package com.keylesspalace.tusky.entity
data class MastoList(
val id: String,
val title: String
val title: String,
val exclusive: Boolean?
)

View file

@ -538,14 +538,16 @@ interface MastodonApi {
@FormUrlEncoded
@POST("api/v1/lists")
suspend fun createList(
@Field("title") title: String
@Field("title") title: String,
@Field("exclusive") exclusive: Boolean?
): NetworkResult<MastoList>
@FormUrlEncoded
@PUT("api/v1/lists/{listId}")
suspend fun updateList(
@Path("listId") listId: String,
@Field("title") title: String
@Field("title") title: String,
@Field("exclusive") exclusive: Boolean?
): NetworkResult<MastoList>
@DELETE("api/v1/lists/{listId}")

View file

@ -38,7 +38,7 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
}
enum class Event {
CREATE_ERROR, DELETE_ERROR, RENAME_ERROR
CREATE_ERROR, DELETE_ERROR, UPDATE_ERROR
}
data class State(val lists: List<MastoList>, val loadingState: LoadingState)
@ -84,9 +84,9 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
}
}
fun createNewList(listName: String) {
fun createNewList(listName: String, exclusive: Boolean) {
viewModelScope.launch {
api.createList(listName).fold(
api.createList(listName, exclusive).fold(
{ list ->
updateState {
copy(lists = lists + list)
@ -99,16 +99,16 @@ internal class ListsViewModel @Inject constructor(private val api: MastodonApi)
}
}
fun renameList(listId: String, listName: String) {
fun updateList(listId: String, listName: String, exclusive: Boolean) {
viewModelScope.launch {
api.updateList(listId, listName).fold(
api.updateList(listId, listName, exclusive).fold(
{ list ->
updateState {
copy(lists = lists.replacedFirstWhich(list) { it.id == listId })
}
},
{
sendEvent(Event.RENAME_ERROR)
sendEvent(Event.UPDATE_ERROR)
}
)
}