mirror of https://github.com/tasks/tasks
Convert attribution activity to compose
parent
0dbd0551d1
commit
a8e83a03b1
@ -1,64 +1,36 @@
|
||||
package org.tasks.activities.attribution
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import butterknife.BindView
|
||||
import androidx.activity.viewModels
|
||||
import butterknife.ButterKnife
|
||||
import com.google.common.collect.Multimaps
|
||||
import com.google.android.material.composethemeadapter.MdcTheme
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.tasks.R
|
||||
import org.tasks.activities.attribution.AttributionViewModel.LibraryAttribution
|
||||
import org.tasks.compose.AttributionList.AttributionList
|
||||
import org.tasks.databinding.ActivityAttributionsBinding
|
||||
import org.tasks.injection.ThemedInjectingAppCompatActivity
|
||||
import timber.log.Timber
|
||||
import java.util.*
|
||||
|
||||
@AndroidEntryPoint
|
||||
class AttributionActivity : ThemedInjectingAppCompatActivity() {
|
||||
@BindView(R.id.toolbar)
|
||||
lateinit var toolbar: Toolbar
|
||||
|
||||
@BindView(R.id.list)
|
||||
lateinit var recyclerView: RecyclerView
|
||||
val viewModel: AttributionViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_attributions)
|
||||
val binding = ActivityAttributionsBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
ButterKnife.bind(this)
|
||||
toolbar.setTitle(R.string.third_party_licenses)
|
||||
toolbar.setNavigationIcon(R.drawable.ic_outline_arrow_back_24px)
|
||||
toolbar.setNavigationOnClickListener { finish() }
|
||||
themeColor.apply(toolbar)
|
||||
recyclerView.layoutManager = LinearLayoutManager(this)
|
||||
with(binding.toolbar.toolbar) {
|
||||
setTitle(R.string.third_party_licenses)
|
||||
setNavigationIcon(R.drawable.ic_outline_arrow_back_24px)
|
||||
setNavigationOnClickListener { finish() }
|
||||
themeColor.apply(this)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
ViewModelProvider(this)
|
||||
.get(AttributionViewModel::class.java)
|
||||
.observe(this, androidx.lifecycle.Observer { libraryAttributions: List<LibraryAttribution>? ->
|
||||
updateAttributions(libraryAttributions!!)
|
||||
})
|
||||
viewModel.attributions.observe(this) {
|
||||
binding.compose.setContent {
|
||||
MdcTheme {
|
||||
AttributionList(it)
|
||||
}
|
||||
|
||||
private fun updateAttributions(libraryAttributions: List<LibraryAttribution>) {
|
||||
val rows = ArrayList<AttributionRow>()
|
||||
val byLicense = Multimaps.index(libraryAttributions) { it!!.license }
|
||||
byLicense.keySet().sorted().forEach { license ->
|
||||
rows.add(AttributionRow(license))
|
||||
rows.addAll(getRows(byLicense[license]))
|
||||
}
|
||||
recyclerView.adapter = AttributionAdapter(rows)
|
||||
Timber.d(libraryAttributions.toString())
|
||||
}
|
||||
|
||||
private fun getRows(attributions: List<LibraryAttribution>): Iterable<AttributionRow> {
|
||||
val byCopyrightHolder = Multimaps.index(attributions) { lib -> lib!!.copyrightHolder }
|
||||
return byCopyrightHolder.keySet().sorted().map {
|
||||
val libraries = byCopyrightHolder[it].map { a -> "\u2022 ${a.libraryName}"}
|
||||
AttributionRow(it, libraries.sorted().joinToString("\n"))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,30 +0,0 @@
|
||||
package org.tasks.activities.attribution
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import org.tasks.R
|
||||
|
||||
class AttributionAdapter internal constructor(private val rows: List<AttributionRow>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return if (viewType == 0) {
|
||||
LicenseHeader(inflater.inflate(R.layout.row_attribution_header, parent, false))
|
||||
} else {
|
||||
LicenseRow(inflater.inflate(R.layout.row_attribution, parent, false))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||
val row = rows[position]
|
||||
if (getItemViewType(position) == 0) {
|
||||
(holder as LicenseHeader).bind(row.license)
|
||||
} else {
|
||||
(holder as LicenseRow).bind(row.copyrightHolder, row.libraries)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int) = if (rows[position].isHeader) 0 else 1
|
||||
|
||||
override fun getItemCount() = rows.size
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
package org.tasks.activities.attribution
|
||||
|
||||
class AttributionRow {
|
||||
val isHeader: Boolean
|
||||
val license: String?
|
||||
val copyrightHolder: String?
|
||||
val libraries: String?
|
||||
|
||||
internal constructor(license: String?) {
|
||||
this.license = license
|
||||
isHeader = true
|
||||
copyrightHolder = null
|
||||
libraries = null
|
||||
}
|
||||
|
||||
internal constructor(copyrightHolder: String?, libraries: String?) {
|
||||
this.copyrightHolder = copyrightHolder
|
||||
this.libraries = libraries
|
||||
isHeader = false
|
||||
license = null
|
||||
}
|
||||
}
|
||||
@ -1,22 +0,0 @@
|
||||
package org.tasks.activities.attribution
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import butterknife.BindView
|
||||
import butterknife.ButterKnife
|
||||
import org.tasks.R
|
||||
|
||||
internal class LicenseHeader(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
@BindView(R.id.license_name)
|
||||
lateinit var licenseName: TextView
|
||||
|
||||
init {
|
||||
ButterKnife.bind(this, itemView)
|
||||
}
|
||||
|
||||
fun bind(license: String?) {
|
||||
licenseName.text = license
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
package org.tasks.activities.attribution
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import butterknife.BindView
|
||||
import butterknife.ButterKnife
|
||||
import org.tasks.R
|
||||
|
||||
internal class LicenseRow(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
@BindView(R.id.copyright_holder)
|
||||
lateinit var copyrightHolder: TextView
|
||||
|
||||
@BindView(R.id.libraries)
|
||||
lateinit var libraries: TextView
|
||||
|
||||
init {
|
||||
ButterKnife.bind(this, itemView)
|
||||
}
|
||||
|
||||
fun bind(copyrightHolder: String?, libraries: String?) {
|
||||
this.copyrightHolder.text = copyrightHolder
|
||||
this.libraries.text = libraries
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
package org.tasks.compose
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import org.tasks.R
|
||||
import org.tasks.activities.attribution.AttributionViewModel.LibraryAttribution
|
||||
import org.tasks.compose.Constants.KEYLINE_FIRST
|
||||
|
||||
object AttributionList {
|
||||
@Composable
|
||||
fun AttributionList(licenses: Map<String, Map<String, List<LibraryAttribution>>>) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
licenses.forEach { (license, libraries) ->
|
||||
Text(
|
||||
license,
|
||||
style = MaterialTheme.typography.h6,
|
||||
color = MaterialTheme.colors.onBackground,
|
||||
modifier = Modifier.padding(KEYLINE_FIRST)
|
||||
)
|
||||
libraries.forEach { (copyrightHolder, libraries) ->
|
||||
LibraryCard(copyrightHolder, libraries)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LibraryCard(copyrightHolder: String, libraries: List<LibraryAttribution>) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(Constants.HALF_KEYLINE),
|
||||
backgroundColor = colorResource(R.color.content_background),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(KEYLINE_FIRST)
|
||||
) {
|
||||
Text(
|
||||
copyrightHolder,
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = MaterialTheme.colors.secondary
|
||||
)
|
||||
Spacer(Modifier.height(Constants.HALF_KEYLINE))
|
||||
libraries.forEach {
|
||||
Text(
|
||||
"\u2022 ${it.libraryName!!}",
|
||||
style = MaterialTheme.typography.body2,
|
||||
color = MaterialTheme.colors.onBackground
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
style="@style/CardViewStyle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="4dp"
|
||||
app:cardMaxElevation="1dp"
|
||||
app:cardElevation="1dp"
|
||||
app:cardBackgroundColor="@color/content_background">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:paddingTop="@dimen/keyline_first"
|
||||
android:paddingBottom="@dimen/keyline_first"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/copyright_holder"
|
||||
android:textStyle="bold"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/keyline_first"
|
||||
android:paddingEnd="@dimen/keyline_first"
|
||||
android:gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="@dimen/sku_details_row_text_size"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/libraries"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="@dimen/keyline_first"
|
||||
android:paddingEnd="@dimen/keyline_first"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:textSize="@dimen/sku_details_row_text_size"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/license_name"
|
||||
style="@style/TextAppearance"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/keyline_first"
|
||||
android:layout_marginBottom="@dimen/keyline_first"
|
||||
android:layout_marginStart="@dimen/card_view_margin"
|
||||
android:layout_marginEnd="@dimen/card_view_margin"
|
||||
android:paddingStart="@dimen/keyline_first"
|
||||
android:paddingEnd="@dimen/keyline_first"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:textSize="@dimen/sku_details_row_text_size"
|
||||
app:fontFamily="sans-serif-medium"/>
|
||||
Loading…
Reference in New Issue