Yuito-app-android/app/src/main/java/com/keylesspalace/tusky/ListsActivity.kt

198 lines
6.1 KiB
Kotlin
Raw Normal View History

2018-01-06 19:01:37 +01:00
package com.keylesspalace.tusky
import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.appcompat.widget.Toolbar
2018-01-06 19:01:37 +01:00
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.ProgressBar
import android.widget.TextView
import com.keylesspalace.tusky.di.Injectable
2018-01-06 19:01:37 +01:00
import com.keylesspalace.tusky.entity.MastoList
import com.keylesspalace.tusky.fragment.TimelineFragment
import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.ThemeUtils
import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable
import retrofit2.Call
import retrofit2.Response
import java.lang.ref.WeakReference
import javax.inject.Inject
2018-01-06 19:01:37 +01:00
/**
* Created by charlag on 1/4/18.
*/
interface ListsView {
fun update(state: State)
fun openTimeline(listId: String)
}
data class State(val lists: List<MastoList>, val isLoading: Boolean)
class ListsViewModel(private val api: MastodonApi) {
private var _view: WeakReference<ListsView>? = null
private val view: ListsView? get() = _view?.get()
private var state = State(listOf(), false)
fun attach(view: ListsView) {
this._view = WeakReference(view)
updateView()
loadIfNeeded()
}
fun detach() {
this._view = null
}
fun didSelectItem(id: String) {
view?.openTimeline(id)
}
private fun loadIfNeeded() {
if (state.isLoading || !state.lists.isEmpty()) return
updateState(state.copy(isLoading = false))
api.getLists().enqueue(object : retrofit2.Callback<List<MastoList>> {
override fun onResponse(call: Call<List<MastoList>>, response: Response<List<MastoList>>) {
updateState(state.copy(lists = response.body() ?: listOf(), isLoading = false))
}
override fun onFailure(call: Call<List<MastoList>>, t: Throwable?) {
updateState(state.copy(isLoading = false))
}
})
}
private fun updateState(state: State) {
this.state = state
view?.update(state)
}
private fun updateView() {
view?.update(state)
}
}
class ListsActivity : BaseActivity(), ListsView, Injectable {
2018-01-06 19:01:37 +01:00
companion object {
@JvmStatic
fun newIntent(context: Context): Intent {
return Intent(context, ListsActivity::class.java)
}
}
@Inject
lateinit var mastodonApi: MastodonApi
2018-01-06 19:01:37 +01:00
private lateinit var recyclerView: RecyclerView
private lateinit var progressBar: ProgressBar
private lateinit var viewModel: ListsViewModel
private val adapter = ListsAdapter()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_lists)
val toolbar = findViewById<Toolbar>(R.id.toolbar)
recyclerView = findViewById(R.id.lists_recycler)
progressBar = findViewById(R.id.progress_bar)
setSupportActionBar(toolbar)
val bar = supportActionBar
if (bar != null) {
bar.title = getString(R.string.title_lists)
bar.setDisplayHomeAsUpEnabled(true)
bar.setDisplayShowHomeEnabled(true)
}
recyclerView.adapter = adapter
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.addItemDecoration(
DividerItemDecoration(this, DividerItemDecoration.VERTICAL))
viewModel = lastNonConfigurationInstance as? ListsViewModel ?: ListsViewModel(mastodonApi)
viewModel.attach(this)
}
override fun onDestroy() {
viewModel.detach()
super.onDestroy()
}
override fun onRetainCustomNonConfigurationInstance(): Any {
return viewModel
}
override fun update(state: State) {
adapter.update(state.lists)
progressBar.visibility = if (state.isLoading) View.VISIBLE else View.GONE
}
override fun openTimeline(listId: String) {
2018-07-31 21:25:25 +02:00
startActivityWithSlideInAnimation(
2018-01-06 19:01:37 +01:00
ModalTimelineActivity.newIntent(this, TimelineFragment.Kind.LIST, listId))
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
return true
}
return false
}
private inner class ListsAdapter : RecyclerView.Adapter<ListsAdapter.ListViewHolder>() {
private val items = mutableListOf<MastoList>()
fun update(list: List<MastoList>) {
this.items.clear()
this.items.addAll(list)
notifyDataSetChanged()
}
override fun getItemCount(): Int = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ListViewHolder {
return LayoutInflater.from(parent.context).inflate(R.layout.item_list, parent, false)
.let(this::ListViewHolder)
.apply {
val context = nameTextView.context
2018-02-03 13:24:12 +01:00
val icon = IconicsDrawable(context, GoogleMaterial.Icon.gmd_list).sizeDp(20)
2018-01-06 19:01:37 +01:00
ThemeUtils.setDrawableTint(context, icon, android.R.attr.textColorTertiary)
2018-12-03 11:22:57 +01:00
nameTextView.setCompoundDrawablesRelativeWithIntrinsicBounds(icon, null, null, null)
2018-01-06 19:01:37 +01:00
}
}
override fun onBindViewHolder(holder: ListViewHolder, position: Int) {
holder.nameTextView.text = items[position].title
}
private inner class ListViewHolder(view: View) : RecyclerView.ViewHolder(view),
View.OnClickListener {
val nameTextView: TextView = view.findViewById(R.id.list_name_textview)
init {
view.setOnClickListener(this)
}
override fun onClick(v: View?) {
viewModel.didSelectItem(items[adapterPosition].id)
}
}
}
}