Convert tag control to compose

pull/1917/head
Alex Baker 4 years ago
parent 543e169e33
commit 2137bf8004

@ -1,53 +1,61 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.tags package com.todoroo.astrid.tags
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.os.Bundle
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import androidx.compose.foundation.layout.padding
import com.google.android.material.chip.ChipGroup import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.google.accompanist.flowlayout.FlowRow
import com.google.android.material.composethemeadapter.MdcTheme
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R import org.tasks.R
import org.tasks.data.TagData import org.tasks.data.TagData
import org.tasks.databinding.ControlSetTagsBinding
import org.tasks.tags.TagPickerActivity import org.tasks.tags.TagPickerActivity
import org.tasks.ui.ChipProvider import org.tasks.ui.ChipProvider
import org.tasks.ui.TaskEditControlFragment import org.tasks.ui.TaskEditControlFragment
import javax.inject.Inject import javax.inject.Inject
/**
* Control set to manage adding and removing tags
*
* @author Tim Su <tim></tim>@todoroo.com>
*/
@AndroidEntryPoint @AndroidEntryPoint
class TagsControlSet : TaskEditControlFragment() { class TagsControlSet : TaskEditControlFragment() {
@Inject lateinit var chipProvider: ChipProvider @Inject lateinit var chipProvider: ChipProvider
private lateinit var tagsDisplay: TextView
private lateinit var chipGroup: ChipGroup
override fun createView(savedInstanceState: Bundle?) {
refreshDisplayView()
}
override fun onRowClick() { override fun onRowClick() {
val intent = Intent(context, TagPickerActivity::class.java) val intent = Intent(context, TagPickerActivity::class.java)
intent.putParcelableArrayListExtra(TagPickerActivity.EXTRA_SELECTED, viewModel.selectedTags) intent.putParcelableArrayListExtra(TagPickerActivity.EXTRA_SELECTED, viewModel.selectedTags.value)
startActivityForResult(intent, REQUEST_TAG_PICKER_ACTIVITY) startActivityForResult(intent, REQUEST_TAG_PICKER_ACTIVITY)
} }
override fun bind(parent: ViewGroup?) = override fun bind(parent: ViewGroup?) =
ControlSetTagsBinding.inflate(layoutInflater, parent, true).let { (parent?.findViewById(R.id.compose_view) as ComposeView).apply {
tagsDisplay = it.noTags setContent {
chipGroup = it.chipGroup MdcTheme {
it.root val tags = viewModel.selectedTags.collectAsState()
FlowRow(
mainAxisSpacing = 4.dp,
crossAxisSpacing = 4.dp,
modifier = Modifier.padding(top = 20.dp, bottom = 20.dp, end = 16.dp)
) {
if (tags.value.isEmpty()) {
Text(
text = stringResource(id = R.string.add_tags),
style = MaterialTheme.typography.body1,
color = colorResource(id = R.color.text_tertiary),
)
} else {
tags.value.sortedBy(TagData::name).forEach { tag ->
chipProvider.TagChip(tag, this@TagsControlSet::onRowClick)
}
}
}
}
}
} }
override val isClickable = true override val isClickable = true
@ -56,30 +64,14 @@ class TagsControlSet : TaskEditControlFragment() {
override fun controlId() = TAG override fun controlId() = TAG
private fun refreshDisplayView() { override val rootLayout = R.layout.control_set_template_compose
viewModel.selectedTags.let { selectedTags ->
if (selectedTags.isEmpty()) {
chipGroup.visibility = View.GONE
tagsDisplay.visibility = View.VISIBLE
} else {
tagsDisplay.visibility = View.GONE
chipGroup.visibility = View.VISIBLE
chipGroup.removeAllViews()
for (tagData in selectedTags.sortedBy(TagData::name)) {
val chip = chipProvider.newTagChip(tagData, onClick = this::onRowClick)
chipGroup.addView(chip)
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_TAG_PICKER_ACTIVITY) { if (requestCode == REQUEST_TAG_PICKER_ACTIVITY) {
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
viewModel.selectedTags = viewModel.selectedTags.value =
data.getParcelableArrayListExtra(TagPickerActivity.EXTRA_SELECTED) data.getParcelableArrayListExtra(TagPickerActivity.EXTRA_SELECTED)
?: ArrayList() ?: ArrayList()
refreshDisplayView()
} }
} else { } else {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)

@ -2,7 +2,6 @@ package org.tasks.ui
import android.app.Activity import android.app.Activity
import android.content.res.Configuration import android.content.res.Configuration
import android.view.View
import androidx.annotation.DrawableRes import androidx.annotation.DrawableRes
import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.defaultMinSize
@ -13,7 +12,6 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
@ -184,8 +182,8 @@ class ChipProvider @Inject constructor(
} }
} }
fun newTagChip(tag: TagData, onClick: () -> Unit): View { @Composable
return newView { fun TagChip(tag: TagData, onClick: () -> Unit) {
TasksChip( TasksChip(
getIcon(tag.getIcon()!!, R.drawable.ic_outline_label_24px), getIcon(tag.getIcon()!!, R.drawable.ic_outline_label_24px),
tag.name, tag.name,
@ -195,15 +193,6 @@ class ChipProvider @Inject constructor(
onClick = onClick, onClick = onClick,
) )
} }
}
private fun newView(content: @Composable () -> Unit): View = ComposeView(activity).apply {
setContent {
MdcTheme {
content()
}
}
}
@Composable @Composable
fun TasksChip( fun TasksChip(

@ -91,7 +91,7 @@ class TaskEditViewModel @Inject constructor(
selectedList.value = list selectedList.value = list
originalLocation = location originalLocation = location
originalTags = tags.toList() originalTags = tags.toList()
selectedTags = ArrayList(tags) selectedTags.value = ArrayList(tags)
originalAlarms = originalAlarms =
if (isNew) { if (isNew) {
ArrayList<Alarm>().apply { ArrayList<Alarm>().apply {
@ -249,7 +249,7 @@ class TaskEditViewModel @Inject constructor(
private lateinit var originalTags: List<TagData> private lateinit var originalTags: List<TagData>
lateinit var selectedTags: ArrayList<TagData> val selectedTags = MutableStateFlow(ArrayList<TagData>())
var newSubtasks = ArrayList<Task>() var newSubtasks = ArrayList<Task>()
@ -303,7 +303,7 @@ class TaskEditViewModel @Inject constructor(
task.estimatedSeconds != estimatedSeconds || task.estimatedSeconds != estimatedSeconds ||
originalList != selectedList.value || originalList != selectedList.value ||
originalLocation != selectedLocation || originalLocation != selectedLocation ||
originalTags.toHashSet() != selectedTags.toHashSet() || originalTags.toHashSet() != selectedTags.value.toHashSet() ||
newSubtasks.isNotEmpty() || newSubtasks.isNotEmpty() ||
getRingFlags() != when { getRingFlags() != when {
task.isNotifyModeFive -> NOTIFY_MODE_FIVE task.isNotifyModeFive -> NOTIFY_MODE_FIVE
@ -365,8 +365,8 @@ class TaskEditViewModel @Inject constructor(
task.modificationDate = currentTimeMillis() task.modificationDate = currentTimeMillis()
} }
if ((isNew && selectedTags.isNotEmpty()) || originalTags.toHashSet() != selectedTags.toHashSet()) { if ((isNew && selectedTags.value.isNotEmpty()) || originalTags.toHashSet() != selectedTags.value.toHashSet()) {
tagDao.applyTags(task, tagDataDao, selectedTags) tagDao.applyTags(task, tagDataDao, selectedTags.value)
task.modificationDate = currentTimeMillis() task.modificationDate = currentTimeMillis()
} }

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
** Copyright (c) 2012 Todoroo Inc
**
** See the file "LICENSE" for the full license governing this code.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/no_tags"
style="@style/TaskEditTextPrimary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:hint="@string/add_tags"
android:textAlignment="viewStart"/>
<com.google.android.material.chip.ChipGroup
android:id="@+id/chip_group"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:chipSpacingVertical="@dimen/chip_spacing"
app:chipSpacingHorizontal="@dimen/chip_spacing"/>
</LinearLayout>
Loading…
Cancel
Save