159 lines
No EOL
5.6 KiB
Kotlin
159 lines
No EOL
5.6 KiB
Kotlin
package ani.dantotsu.settings
|
|
|
|
import android.content.Context
|
|
import android.os.Bundle
|
|
import android.view.KeyEvent
|
|
import android.view.LayoutInflater
|
|
import android.view.View
|
|
import android.view.ViewGroup
|
|
import android.view.inputmethod.EditorInfo
|
|
import androidx.recyclerview.widget.LinearLayoutManager
|
|
import ani.dantotsu.BottomSheetDialogFragment
|
|
import ani.dantotsu.R
|
|
import ani.dantotsu.databinding.BottomSheetAddRepositoryBinding
|
|
import ani.dantotsu.databinding.ItemRepoBinding
|
|
import ani.dantotsu.media.MediaType
|
|
import ani.dantotsu.util.customAlertDialog
|
|
import com.xwray.groupie.GroupieAdapter
|
|
import com.xwray.groupie.viewbinding.BindableItem
|
|
|
|
class RepoItem(
|
|
val url: String,
|
|
val onRemove: (String) -> Unit
|
|
) :BindableItem<ItemRepoBinding>() {
|
|
override fun getLayout() = R.layout.item_repo
|
|
|
|
override fun bind(viewBinding: ItemRepoBinding, position: Int) {
|
|
viewBinding.repoNameTextView.text = url
|
|
viewBinding.repoDeleteImageView.setOnClickListener {
|
|
onRemove(url)
|
|
}
|
|
}
|
|
|
|
override fun initializeViewBinding(view: View): ItemRepoBinding {
|
|
return ItemRepoBinding.bind(view)
|
|
}
|
|
}
|
|
|
|
class AddRepositoryBottomSheet : BottomSheetDialogFragment() {
|
|
private var _binding: BottomSheetAddRepositoryBinding? = null
|
|
private val binding get() = _binding!!
|
|
private var mediaType: MediaType = MediaType.ANIME
|
|
private var onRepositoryAdded: ((String, MediaType) -> Unit)? = null
|
|
private var repositories: MutableList<String> = mutableListOf()
|
|
private var onRepositoryRemoved: ((String) -> Unit)? = null
|
|
private var adapter: GroupieAdapter = GroupieAdapter()
|
|
|
|
override fun onCreateView(
|
|
inflater: LayoutInflater,
|
|
container: ViewGroup?,
|
|
savedInstanceState: Bundle?
|
|
): View {
|
|
_binding = BottomSheetAddRepositoryBinding.inflate(inflater, container, false)
|
|
return binding.root
|
|
}
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
|
super.onViewCreated(view, savedInstanceState)
|
|
|
|
binding.repositoriesRecyclerView.adapter = adapter
|
|
binding.repositoriesRecyclerView.layoutManager = LinearLayoutManager(
|
|
context,
|
|
LinearLayoutManager.VERTICAL,
|
|
false
|
|
)
|
|
adapter.addAll(repositories.map { RepoItem(it, ::onRepositoryRemoved) })
|
|
|
|
binding.repositoryInput.hint = when(mediaType) {
|
|
MediaType.ANIME -> getString(R.string.anime_add_repository)
|
|
MediaType.MANGA -> getString(R.string.manga_add_repository)
|
|
else -> ""
|
|
}
|
|
|
|
binding.addButton.setOnClickListener {
|
|
val input = binding.repositoryInput.text.toString()
|
|
val error = isValidUrl(input)
|
|
if (error == null) {
|
|
context?.let { context ->
|
|
addRepoWarning(context) {
|
|
onRepositoryAdded?.invoke(input, mediaType)
|
|
dismiss()
|
|
}
|
|
}
|
|
} else {
|
|
binding.repositoryInput.error = error
|
|
}
|
|
}
|
|
|
|
binding.cancelButton.setOnClickListener {
|
|
dismiss()
|
|
}
|
|
|
|
binding.repositoryInput.setOnEditorActionListener { textView, action, keyEvent ->
|
|
if (action == EditorInfo.IME_ACTION_DONE ||
|
|
(keyEvent?.action == KeyEvent.ACTION_UP && keyEvent.keyCode == KeyEvent.KEYCODE_ENTER)) {
|
|
val url = textView.text.toString()
|
|
if (url.isNotBlank()) {
|
|
val error = isValidUrl(url)
|
|
if (error == null) {
|
|
context?.let { context ->
|
|
addRepoWarning(context) {
|
|
onRepositoryAdded?.invoke(url, mediaType)
|
|
dismiss()
|
|
}
|
|
}
|
|
return@setOnEditorActionListener true
|
|
} else {
|
|
binding.repositoryInput.error = error
|
|
}
|
|
}
|
|
}
|
|
false
|
|
}
|
|
}
|
|
|
|
private fun onRepositoryRemoved(url: String) {
|
|
onRepositoryRemoved?.invoke(url)
|
|
repositories.remove(url)
|
|
adapter.update(repositories.map { RepoItem(it, ::onRepositoryRemoved) })
|
|
}
|
|
|
|
private fun isValidUrl(url: String): String? {
|
|
if (!url.startsWith("https://") && !url.startsWith("http://"))
|
|
return "URL must start with http:// or https://"
|
|
if (!url.removeSuffix("/").endsWith("index.min.json"))
|
|
return "URL must end with index.min.json"
|
|
return null
|
|
}
|
|
|
|
override fun onDestroyView() {
|
|
super.onDestroyView()
|
|
_binding = null
|
|
}
|
|
|
|
companion object {
|
|
fun addRepoWarning(context: Context, onRepositoryAdded: () -> Unit) {
|
|
context.customAlertDialog()
|
|
.setTitle(R.string.warning)
|
|
.setMessage(R.string.add_repository_warning)
|
|
.setPosButton(R.string.ok) {
|
|
onRepositoryAdded.invoke()
|
|
}
|
|
.setNegButton(R.string.cancel) { }
|
|
.show()
|
|
}
|
|
fun newInstance(
|
|
mediaType: MediaType,
|
|
repositories: List<String>,
|
|
onRepositoryAdded: (String, MediaType) -> Unit,
|
|
onRepositoryRemoved: (String) -> Unit
|
|
): AddRepositoryBottomSheet {
|
|
return AddRepositoryBottomSheet().apply {
|
|
this.mediaType = mediaType
|
|
this.repositories.addAll(repositories)
|
|
this.onRepositoryAdded = onRepositoryAdded
|
|
this.onRepositoryRemoved = onRepositoryRemoved
|
|
}
|
|
}
|
|
}
|
|
} |