diff --git a/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt b/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt
index a6e5e5c5f..bc9404f7f 100644
--- a/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt
+++ b/app/src/main/java/com/todoroo/astrid/files/FilesControlSet.kt
@@ -5,45 +5,33 @@
*/
package com.todoroo.astrid.files
-import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.os.Bundle
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
-import androidx.compose.material.Text
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.outlined.Delete
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment.Companion.CenterVertically
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.lifecycleScope
+import com.google.android.material.composethemeadapter.MdcTheme
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.R
-import org.tasks.compose.DisabledText
import org.tasks.compose.collectAsStateLifecycleAware
+import org.tasks.compose.edit.AttachmentRow
import org.tasks.data.TaskAttachment
import org.tasks.data.TaskAttachmentDao
import org.tasks.dialogs.AddAttachmentDialog
import org.tasks.dialogs.DialogBuilder
import org.tasks.files.FileHelper
import org.tasks.preferences.Preferences
-import org.tasks.ui.TaskEditControlComposeFragment
+import org.tasks.ui.TaskEditControlFragment
import javax.inject.Inject
@AndroidEntryPoint
-class FilesControlSet : TaskEditControlComposeFragment() {
+class FilesControlSet : TaskEditControlFragment() {
@Inject lateinit var taskAttachmentDao: TaskAttachmentDao
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var preferences: Preferences
@@ -59,53 +47,25 @@ class FilesControlSet : TaskEditControlComposeFragment() {
}
}
- private fun addAttachment() {
- AddAttachmentDialog.newAddAttachmentDialog(this)
- .show(parentFragmentManager, FRAG_TAG_ADD_ATTACHMENT_DIALOG)
- }
-
- @Composable
- override fun Body() {
- val attachments =
- taskAttachmentDao.watchAttachments(viewModel.task.uuid)
- .collectAsStateLifecycleAware(initial = emptyList()).value
- Column(
- modifier = Modifier.padding(top = if (attachments.isEmpty()) 0.dp else 8.dp),
- ) {
- attachments.forEach {
- Row(
- modifier = Modifier
- .clickable { showFile(it) },
- verticalAlignment = CenterVertically,
- ) {
- Text(
- text = it.name!!,
- modifier = Modifier.weight(1f),
+ override fun bind(parent: ViewGroup?): View =
+ (parent as ComposeView).apply {
+ setContent {
+ MdcTheme {
+ AttachmentRow(
+ attachments = taskAttachmentDao.watchAttachments(viewModel.task.uuid)
+ .collectAsStateLifecycleAware(initial = emptyList()).value,
+ openAttachment = {
+ FileHelper.startActionView(requireActivity(), it.parseUri())
+ },
+ deleteAttachment = this@FilesControlSet::deleteAttachment,
+ addAttachment = {
+ AddAttachmentDialog.newAddAttachmentDialog(this@FilesControlSet)
+ .show(parentFragmentManager, FRAG_TAG_ADD_ATTACHMENT_DIALOG)
+ },
)
- IconButton(onClick = { deleteAttachment(it) }) {
- Icon(
- imageVector = Icons.Outlined.Delete,
- contentDescription = stringResource(
- id = R.string.delete
- )
- )
- }
}
}
- DisabledText(
- text = stringResource(id = R.string.add_attachment),
- modifier = Modifier
- .fillMaxWidth()
- .clickable { addAttachment() }
- .padding(
- top = if (attachments.isEmpty()) 20.dp else 8.dp,
- bottom = 20.dp,
- )
- )
}
- }
-
- override val icon = R.drawable.ic_outline_attachment_24px
override fun controlId() = TAG
@@ -148,11 +108,6 @@ class FilesControlSet : TaskEditControlComposeFragment() {
.show()
}
- @SuppressLint("NewApi")
- private fun showFile(m: TaskAttachment) {
- FileHelper.startActionView(requireActivity(), m.parseUri())
- }
-
private fun copyToAttachmentDirectory(input: Uri?) {
newAttachment(FileHelper.copyToUri(requireContext(), preferences.attachmentsDirectory!!, input!!))
}
@@ -171,4 +126,4 @@ class FilesControlSet : TaskEditControlComposeFragment() {
const val TAG = R.string.TEA_ctrl_files_pref
private const val FRAG_TAG_ADD_ATTACHMENT_DIALOG = "frag_tag_add_attachment_dialog"
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt b/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt
index 56099c84e..6bb876012 100644
--- a/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt
+++ b/app/src/main/java/com/todoroo/astrid/repeats/RepeatControlSet.kt
@@ -24,11 +24,11 @@ import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.repeats.RepeatRuleToString
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils.currentTimeMillis
-import org.tasks.ui.TaskEditControlComposeFragment
+import org.tasks.ui.TaskEditControlFragment
import javax.inject.Inject
@AndroidEntryPoint
-class RepeatControlSet : TaskEditControlComposeFragment() {
+class RepeatControlSet : TaskEditControlFragment() {
@Inject lateinit var repeatRuleToString: RepeatRuleToString
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
diff --git a/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt b/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt
index 1c23ed8cb..6e53ed7f8 100644
--- a/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt
+++ b/app/src/main/java/com/todoroo/astrid/tags/TagsControlSet.kt
@@ -12,11 +12,11 @@ import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.compose.edit.TagsRow
import org.tasks.tags.TagPickerActivity
import org.tasks.ui.ChipProvider
-import org.tasks.ui.TaskEditControlComposeFragment
+import org.tasks.ui.TaskEditControlFragment
import javax.inject.Inject
@AndroidEntryPoint
-class TagsControlSet : TaskEditControlComposeFragment() {
+class TagsControlSet : TaskEditControlFragment() {
@Inject lateinit var chipProvider: ChipProvider
override fun onRowClick() {
diff --git a/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt b/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt
index 3e186f70a..ceea27663 100644
--- a/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt
+++ b/app/src/main/java/com/todoroo/astrid/timers/TimerControlSet.kt
@@ -7,38 +7,23 @@ package com.todoroo.astrid.timers
import android.app.Activity
import android.os.Bundle
-import android.text.format.DateUtils
import android.view.View
+import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material.ContentAlpha
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
-import androidx.compose.material.Text
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.outlined.Pause
-import androidx.compose.material.icons.outlined.PlayArrow
-import androidx.compose.runtime.*
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.alpha
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
+import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.lifecycleScope
+import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.ui.TimeDurationControlSet
import dagger.hilt.android.AndroidEntryPoint
-import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.tasks.R
-import org.tasks.compose.DisabledText
import org.tasks.compose.collectAsStateLifecycleAware
+import org.tasks.compose.edit.TimerRow
import org.tasks.dialogs.DialogBuilder
import org.tasks.themes.Theme
-import org.tasks.ui.TaskEditControlComposeFragment
-import java.lang.System.currentTimeMillis
+import org.tasks.ui.TaskEditControlFragment
import javax.inject.Inject
-import kotlin.time.Duration.Companion.seconds
/**
* Control Set for managing repeats
@@ -46,7 +31,7 @@ import kotlin.time.Duration.Companion.seconds
* @author Tim Su @todoroo.com>
*/
@AndroidEntryPoint
-class TimerControlSet : TaskEditControlComposeFragment() {
+class TimerControlSet : TaskEditControlFragment() {
@Inject lateinit var activity: Activity
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var theme: Theme
@@ -103,76 +88,23 @@ class TimerControlSet : TaskEditControlComposeFragment() {
}
}
- @Composable
- override fun Body() {
- var now by remember { mutableStateOf(currentTimeMillis()) }
- val started = viewModel.timerStarted.collectAsStateLifecycleAware().value
- val newElapsed = if (started > 0) (now - started) / 1000L else 0
- val estimated =
- viewModel.estimatedSeconds.collectAsStateLifecycleAware().value.takeIf { it > 0 }
- ?.let {
- stringResource(id = R.string.TEA_timer_est, DateUtils.formatElapsedTime(it.toLong()))
+ override fun bind(parent: ViewGroup?): View =
+ (parent as ComposeView).apply {
+ setContent {
+ MdcTheme {
+ TimerRow(
+ started = viewModel.timerStarted.collectAsStateLifecycleAware().value,
+ estimated = viewModel.estimatedSeconds.collectAsStateLifecycleAware().value,
+ elapsed = viewModel.elapsedSeconds.collectAsStateLifecycleAware().value,
+ timerClicked = this@TimerControlSet::timerClicked,
+ onClick = this@TimerControlSet::onRowClick,
+ )
}
- val elapsed =
- (newElapsed + viewModel.elapsedSeconds.collectAsStateLifecycleAware().value)
- .takeIf { it > 0 }
- ?.let {
- stringResource(id = R.string.TEA_timer_elap, DateUtils.formatElapsedTime(it))
- }
- val text = when {
- estimated != null && elapsed != null -> "$estimated, $elapsed"
- estimated != null -> estimated
- elapsed != null -> elapsed
- else -> null
- }
- Row {
- if (text == null) {
- DisabledText(
- text = stringResource(id = R.string.TEA_timer_controls),
- modifier = Modifier
- .weight(1f)
- .padding(vertical = 20.dp),
- )
- } else {
- Text(
- text = text,
- modifier = Modifier
- .weight(1f)
- .padding(vertical = 20.dp),
- )
- }
- IconButton(
- onClick = {
- now = currentTimeMillis()
- timerClicked()
- },
- modifier = Modifier.padding(vertical = 8.dp),
- ) {
- Icon(
- imageVector = if (started > 0) {
- Icons.Outlined.Pause
- } else {
- Icons.Outlined.PlayArrow
- },
- modifier = Modifier.alpha(ContentAlpha.medium),
- contentDescription = null
- )
}
}
- LaunchedEffect(key1 = started) {
- while (started > 0) {
- delay(1.seconds)
- now = currentTimeMillis()
- }
- }
- }
-
- override val icon = R.drawable.ic_outline_timer_24px
override fun controlId() = TAG
- override val isClickable = true
-
private fun timerActive() = viewModel.timerStarted.value > 0
interface TimerControlSetCallback {
@@ -183,4 +115,4 @@ class TimerControlSet : TaskEditControlComposeFragment() {
companion object {
const val TAG = R.string.TEA_ctrl_timer_pref
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt b/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt
index 3ad434a8f..3088bee43 100644
--- a/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt
+++ b/app/src/main/java/com/todoroo/astrid/ui/ReminderControlSet.kt
@@ -43,12 +43,12 @@ import org.tasks.date.DateTimeUtils
import org.tasks.dialogs.DialogBuilder
import org.tasks.dialogs.MyTimePickerDialog
import org.tasks.reminders.AlarmToString
-import org.tasks.ui.TaskEditControlComposeFragment
+import org.tasks.ui.TaskEditControlFragment
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@AndroidEntryPoint
-class ReminderControlSet : TaskEditControlComposeFragment() {
+class ReminderControlSet : TaskEditControlFragment() {
@Inject lateinit var activity: Activity
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var alarmToString: AlarmToString
diff --git a/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt b/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt
index 0a5edd259..bfc4e8df4 100644
--- a/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt
+++ b/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt
@@ -22,13 +22,13 @@ import org.tasks.dialogs.StartDatePicker.Companion.EXTRA_TIME
import org.tasks.dialogs.StartDatePicker.Companion.NO_DAY
import org.tasks.dialogs.StartDatePicker.Companion.NO_TIME
import org.tasks.preferences.Preferences
-import org.tasks.ui.TaskEditControlComposeFragment
+import org.tasks.ui.TaskEditControlFragment
import java.time.format.FormatStyle
import java.util.*
import javax.inject.Inject
@AndroidEntryPoint
-class StartDateControlSet : TaskEditControlComposeFragment() {
+class StartDateControlSet : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var locale: Locale
diff --git a/app/src/main/java/org/tasks/compose/edit/AttachmentRow.kt b/app/src/main/java/org/tasks/compose/edit/AttachmentRow.kt
new file mode 100644
index 000000000..bd591cd6e
--- /dev/null
+++ b/app/src/main/java/org/tasks/compose/edit/AttachmentRow.kt
@@ -0,0 +1,103 @@
+package org.tasks.compose.edit
+
+import android.content.res.Configuration
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Delete
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.core.net.toUri
+import com.google.android.material.composethemeadapter.MdcTheme
+import org.tasks.R
+import org.tasks.compose.DisabledText
+import org.tasks.compose.TaskEditRow
+import org.tasks.data.TaskAttachment
+
+@Composable
+fun AttachmentRow(
+ attachments: List,
+ openAttachment: (TaskAttachment) -> Unit,
+ deleteAttachment: (TaskAttachment) -> Unit,
+ addAttachment: () -> Unit,
+) {
+ TaskEditRow(
+ iconRes = R.drawable.ic_outline_attachment_24px,
+ content = {
+ Column(
+ modifier = Modifier.padding(top = if (attachments.isEmpty()) 0.dp else 8.dp),
+ ) {
+ attachments.forEach {
+ Row(
+ modifier = Modifier
+ .clickable { openAttachment(it) },
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Text(
+ text = it.name!!,
+ modifier = Modifier.weight(1f),
+ )
+ IconButton(onClick = { deleteAttachment(it) }) {
+ Icon(
+ imageVector = Icons.Outlined.Delete,
+ contentDescription = stringResource(
+ id = R.string.delete
+ )
+ )
+ }
+ }
+ }
+ DisabledText(
+ text = stringResource(id = R.string.add_attachment),
+ modifier = Modifier
+ .fillMaxWidth()
+ .clickable { addAttachment() }
+ .padding(
+ top = if (attachments.isEmpty()) 20.dp else 8.dp,
+ bottom = 20.dp,
+ )
+ )
+ }
+ },
+ )
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun NoAttachments() {
+ MdcTheme {
+ AttachmentRow(
+ attachments = emptyList(),
+ openAttachment = {},
+ deleteAttachment = {},
+ addAttachment = {},
+ )
+ }
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun AttachmentPreview() {
+ MdcTheme {
+ AttachmentRow(
+ attachments = listOf(
+ TaskAttachment("", "file://attachment.txt".toUri(), "attachment.txt")
+ ),
+ openAttachment = {},
+ deleteAttachment = {},
+ addAttachment = {},
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/compose/edit/CalendarRow.kt b/app/src/main/java/org/tasks/compose/edit/CalendarRow.kt
new file mode 100644
index 000000000..8dcb73d03
--- /dev/null
+++ b/app/src/main/java/org/tasks/compose/edit/CalendarRow.kt
@@ -0,0 +1,93 @@
+package org.tasks.compose.edit
+
+import android.content.res.Configuration
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.ContentAlpha
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Delete
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.google.android.material.composethemeadapter.MdcTheme
+import org.tasks.R
+import org.tasks.compose.DisabledText
+import org.tasks.compose.TaskEditRow
+
+@Composable
+fun CalendarRow(
+ eventUri: String?,
+ selectedCalendar: String?,
+ onClick: () -> Unit,
+ clear: () -> Unit,
+) {
+ TaskEditRow(
+ iconRes = R.drawable.ic_outline_event_24px,
+ content = {
+ if (eventUri?.isNotBlank() == true) {
+ Row {
+ Text(
+ text = stringResource(id = R.string.gcal_TEA_showCalendar_label),
+ modifier = Modifier
+ .weight(1f)
+ .padding(vertical = 20.dp)
+ )
+ IconButton(
+ onClick = { clear() },
+ Modifier.padding(vertical = 8.dp),
+ ) {
+ Icon(
+ imageVector = Icons.Outlined.Delete,
+ contentDescription = stringResource(id = R.string.delete),
+ modifier = Modifier.alpha(ContentAlpha.medium),
+ )
+ }
+ }
+ } else if (selectedCalendar?.isNotBlank() == true) {
+ Text(
+ text = selectedCalendar,
+ modifier = Modifier.padding(vertical = 20.dp),
+ )
+ } else {
+ DisabledText(
+ text = stringResource(id = R.string.dont_add_to_calendar),
+ modifier = Modifier.padding(vertical = 20.dp),
+ )
+ }
+ },
+ onClick = onClick
+ )
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun NoCalendar() {
+ MdcTheme {
+ CalendarRow(eventUri = null, selectedCalendar = null, onClick = {}, clear = {})
+ }
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun NewCalendar() {
+ MdcTheme {
+ CalendarRow(eventUri = null, selectedCalendar = "Personal", onClick = {}, clear = {})
+ }
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun ExistingCalendar() {
+ MdcTheme {
+ CalendarRow(eventUri = "abcd", selectedCalendar = null, onClick = {}, clear = {})
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/compose/edit/InfoRow.kt b/app/src/main/java/org/tasks/compose/edit/InfoRow.kt
new file mode 100644
index 000000000..80e39668d
--- /dev/null
+++ b/app/src/main/java/org/tasks/compose/edit/InfoRow.kt
@@ -0,0 +1,73 @@
+package org.tasks.compose.edit
+
+import android.content.res.Configuration
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.ExperimentalComposeUiApi
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.google.android.material.composethemeadapter.MdcTheme
+import org.tasks.R
+import org.tasks.compose.TaskEditRow
+import java.text.SimpleDateFormat
+import java.util.*
+
+@Composable
+fun InfoRow(
+ creationDate: Long?,
+ modificationDate: Long?,
+ completionDate: Long?,
+ locale: Locale = Locale.getDefault(),
+) {
+ TaskEditRow(
+ iconRes = R.drawable.ic_outline_info_24px,
+ content = {
+ Column(modifier = Modifier.padding(vertical = 20.dp)) {
+ val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm", locale)
+ creationDate?.let {
+ Text(
+ text = stringResource(
+ id = R.string.sort_created_group,
+ formatter.format(it)
+ )
+ )
+ }
+ modificationDate?.let {
+ Text(
+ text = stringResource(
+ id = R.string.sort_modified_group,
+ formatter.format(it)
+ )
+ )
+ }
+ completionDate?.takeIf { it > 0 }?.let {
+ Text(
+ text = stringResource(
+ id = R.string.sort_completion_group,
+ formatter.format(it)
+ )
+ )
+ }
+ }
+ },
+ )
+}
+
+@ExperimentalComposeUiApi
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun InfoPreview() {
+ MdcTheme {
+ InfoRow(
+ creationDate = 1658727180000,
+ modificationDate = 1658813557000,
+ completionDate = 1658813557000,
+ locale = Locale.US,
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/compose/edit/ListRow.kt b/app/src/main/java/org/tasks/compose/edit/ListRow.kt
index 22b9b700b..898b87c04 100644
--- a/app/src/main/java/org/tasks/compose/edit/ListRow.kt
+++ b/app/src/main/java/org/tasks/compose/edit/ListRow.kt
@@ -1,9 +1,14 @@
package org.tasks.compose.edit
+import android.content.res.Configuration
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
+import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import com.google.android.material.composethemeadapter.MdcTheme
+import com.todoroo.andlib.sql.QueryTemplate
import com.todoroo.astrid.api.Filter
import org.tasks.R
import org.tasks.compose.ChipGroup
@@ -34,4 +39,18 @@ fun ListRow(
},
onClick = onClick
)
+}
+
+@ExperimentalComposeUiApi
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun ListPreview() {
+ MdcTheme {
+ ListRow(
+ list = Filter("Default list", QueryTemplate()),
+ colorProvider = { -769226 },
+ onClick = {},
+ )
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/compose/edit/TagsRow.kt b/app/src/main/java/org/tasks/compose/edit/TagsRow.kt
index b2060ea89..065905e4b 100644
--- a/app/src/main/java/org/tasks/compose/edit/TagsRow.kt
+++ b/app/src/main/java/org/tasks/compose/edit/TagsRow.kt
@@ -1,16 +1,20 @@
package org.tasks.compose.edit
+import android.content.res.Configuration
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import com.google.android.material.composethemeadapter.MdcTheme
import org.tasks.R
import org.tasks.compose.Chip
import org.tasks.compose.ChipGroup
import org.tasks.compose.DisabledText
import org.tasks.compose.TaskEditRow
import org.tasks.data.TagData
+import org.tasks.themes.ColorProvider
import org.tasks.themes.CustomIcons
@Composable
@@ -46,3 +50,69 @@ fun TagsRow(
onClick = onClick
)
}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun NoTags() {
+ MdcTheme {
+ TagsRow(
+ tags = emptyList(),
+ colorProvider = { 0 },
+ onClick = {},
+ )
+ }
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun SingleTag() {
+ MdcTheme {
+ TagsRow(
+ tags = listOf(
+ TagData("Home").apply {
+ setIcon(1062)
+ setColor(ColorProvider.BLUE_500)
+ }
+ ),
+ colorProvider = { it },
+ onClick = {},
+ )
+ }
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Composable
+fun BunchOfTags() {
+ MdcTheme {
+ TagsRow(
+ tags = listOf(
+ TagData("One"),
+ TagData("Two"),
+ TagData("Three"),
+ TagData("Four"),
+ TagData("Five"),
+ ),
+ colorProvider = { it },
+ onClick = {}
+ )
+ }
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Composable
+fun TagWithReallyLongName() {
+ MdcTheme {
+ TagsRow(
+ tags = listOf(
+ TagData("This is a tag with a really really long name").apply {
+ setIcon(1062)
+ setColor(ColorProvider.BLUE_500)
+ }
+ ),
+ colorProvider = { it },
+ onClick = {},
+ )
+ }
+}
diff --git a/app/src/main/java/org/tasks/compose/edit/TimerRow.kt b/app/src/main/java/org/tasks/compose/edit/TimerRow.kt
new file mode 100644
index 000000000..b0e31f0b9
--- /dev/null
+++ b/app/src/main/java/org/tasks/compose/edit/TimerRow.kt
@@ -0,0 +1,125 @@
+package org.tasks.compose.edit
+
+import android.content.res.Configuration
+import android.text.format.DateUtils
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.ContentAlpha
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.outlined.Pause
+import androidx.compose.material.icons.outlined.PlayArrow
+import androidx.compose.runtime.*
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.google.android.material.composethemeadapter.MdcTheme
+import kotlinx.coroutines.delay
+import org.tasks.R
+import org.tasks.compose.DisabledText
+import org.tasks.compose.TaskEditRow
+import kotlin.time.Duration.Companion.seconds
+
+@Composable
+fun TimerRow(
+ started: Long,
+ estimated: Int,
+ elapsed: Int,
+ timerClicked: () -> Unit,
+ onClick: () -> Unit,
+) {
+ TaskEditRow(
+ iconRes = R.drawable.ic_outline_timer_24px,
+ content = {
+ var now by remember { mutableStateOf(System.currentTimeMillis()) }
+
+ val newElapsed = if (started > 0) (now - started) / 1000L else 0
+ val estimatedString = estimated
+ .takeIf { it > 0 }
+ ?.let {
+ stringResource(
+ id = R.string.TEA_timer_est,
+ DateUtils.formatElapsedTime(it.toLong())
+ )
+ }
+ val elapsedString =
+ (newElapsed + elapsed)
+ .takeIf { it > 0 }
+ ?.let {
+ stringResource(
+ id = R.string.TEA_timer_elap,
+ DateUtils.formatElapsedTime(it)
+ )
+ }
+ val text = when {
+ estimatedString != null && elapsedString != null -> "$estimatedString, $elapsedString"
+ estimatedString != null -> estimatedString
+ elapsedString != null -> elapsedString
+ else -> null
+ }
+ Row {
+ if (text == null) {
+ DisabledText(
+ text = stringResource(id = R.string.TEA_timer_controls),
+ modifier = Modifier
+ .weight(1f)
+ .padding(vertical = 20.dp),
+ )
+ } else {
+ Text(
+ text = text,
+ modifier = Modifier
+ .weight(1f)
+ .padding(vertical = 20.dp),
+ )
+ }
+ IconButton(
+ onClick = {
+ now = System.currentTimeMillis()
+ timerClicked()
+ },
+ modifier = Modifier.padding(vertical = 8.dp),
+ ) {
+ Icon(
+ imageVector = if (started > 0) {
+ Icons.Outlined.Pause
+ } else {
+ Icons.Outlined.PlayArrow
+ },
+ modifier = Modifier.alpha(ContentAlpha.medium),
+ contentDescription = null
+ )
+ }
+ }
+ LaunchedEffect(key1 = started) {
+ while (started > 0) {
+ delay(1.seconds)
+ now = System.currentTimeMillis()
+ }
+ }
+ },
+ onClick = onClick
+ )
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun NoTimer() {
+ MdcTheme {
+ TimerRow(started = 0, estimated = 0, elapsed = 0, timerClicked = {}, onClick = {})
+ }
+}
+
+@Preview(showBackground = true, widthDp = 320)
+@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
+@Composable
+fun RunningTimer() {
+ MdcTheme {
+ TimerRow(started = System.currentTimeMillis(), estimated = 900, elapsed = 400, timerClicked = {}, onClick = {})
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/ui/CalendarControlSet.kt b/app/src/main/java/org/tasks/ui/CalendarControlSet.kt
index 1e9239c9c..afcc8cd81 100644
--- a/app/src/main/java/org/tasks/ui/CalendarControlSet.kt
+++ b/app/src/main/java/org/tasks/ui/CalendarControlSet.kt
@@ -4,34 +4,25 @@ import android.app.Activity
import android.content.Intent
import android.net.Uri
import android.provider.CalendarContract
+import android.view.View
+import android.view.ViewGroup
import android.widget.Toast.LENGTH_SHORT
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material.ContentAlpha
-import androidx.compose.material.Icon
-import androidx.compose.material.IconButton
-import androidx.compose.material.Text
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.outlined.Delete
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.alpha
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
+import androidx.compose.ui.platform.ComposeView
+import com.google.android.material.composethemeadapter.MdcTheme
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.Strings.isNullOrEmpty
import org.tasks.calendars.CalendarPicker
import org.tasks.calendars.CalendarProvider
-import org.tasks.compose.DisabledText
import org.tasks.compose.collectAsStateLifecycleAware
+import org.tasks.compose.edit.CalendarRow
import org.tasks.extensions.Context.toast
import org.tasks.preferences.PermissionChecker
import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
-class CalendarControlSet : TaskEditControlComposeFragment() {
+class CalendarControlSet : TaskEditControlFragment() {
@Inject lateinit var activity: Activity
@Inject lateinit var calendarProvider: CalendarProvider
@Inject lateinit var permissionChecker: PermissionChecker
@@ -50,65 +41,34 @@ class CalendarControlSet : TaskEditControlComposeFragment() {
}
}
- @Composable
- override fun Body() {
- val eventUri = viewModel.eventUri.collectAsStateLifecycleAware().value
- val selectedCalendar =
- viewModel.selectedCalendar.collectAsStateLifecycleAware().value?.let {
- calendarProvider.getCalendar(it)?.name
- }
- if (eventUri?.isNotBlank() == true) {
- Row {
- Text(
- text = stringResource(id = R.string.gcal_TEA_showCalendar_label),
- modifier = Modifier
- .weight(1f)
- .padding(vertical = 20.dp)
- )
- IconButton(
- onClick = { clear() },
- Modifier.padding(vertical = 8.dp),
- ) {
- Icon(
- imageVector = Icons.Outlined.Delete,
- contentDescription = stringResource(id = R.string.delete),
- modifier = Modifier.alpha(ContentAlpha.medium),
+ override fun bind(parent: ViewGroup?): View =
+ (parent as ComposeView).apply {
+ setContent {
+ MdcTheme {
+ CalendarRow(
+ eventUri = viewModel.eventUri.collectAsStateLifecycleAware().value,
+ selectedCalendar = viewModel.selectedCalendar.collectAsStateLifecycleAware().value?.let {
+ calendarProvider.getCalendar(it)?.name
+ },
+ onClick = {
+ if (viewModel.eventUri.value.isNullOrBlank()) {
+ CalendarPicker.newCalendarPicker(this@CalendarControlSet, REQUEST_CODE_PICK_CALENDAR, calendarName)
+ .show(parentFragmentManager, FRAG_TAG_CALENDAR_PICKER)
+ } else {
+ openCalendarEvent()
+ }
+ },
+ clear = {
+ viewModel.selectedCalendar.value = null
+ viewModel.eventUri.value = null
+ }
)
}
}
- } else if (selectedCalendar?.isNotBlank() == true) {
- Text(
- text = selectedCalendar,
- modifier = Modifier.padding(vertical = 20.dp),
- )
- } else {
- DisabledText(
- text = stringResource(id = R.string.dont_add_to_calendar),
- modifier = Modifier.padding(vertical = 20.dp),
- )
}
- }
-
- override val icon = R.drawable.ic_outline_event_24px
override fun controlId() = TAG
- override val isClickable = true
-
- private fun clear() {
- viewModel.selectedCalendar.value = null
- viewModel.eventUri.value = null
- }
-
- override fun onRowClick() {
- if (viewModel.eventUri.value.isNullOrBlank()) {
- CalendarPicker.newCalendarPicker(this, REQUEST_CODE_PICK_CALENDAR, calendarName)
- .show(parentFragmentManager, FRAG_TAG_CALENDAR_PICKER)
- } else {
- openCalendarEvent()
- }
- }
-
private fun openCalendarEvent() {
val cr = activity.contentResolver
val uri = Uri.parse(viewModel.eventUri.value)
@@ -172,4 +132,4 @@ class CalendarControlSet : TaskEditControlComposeFragment() {
private const val FRAG_TAG_CALENDAR_PICKER = "frag_tag_calendar_picker"
private const val REQUEST_CODE_PICK_CALENDAR = 70
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/tasks/ui/CreationDateControlSet.kt b/app/src/main/java/org/tasks/ui/CreationDateControlSet.kt
index f62b87796..707ffb48d 100644
--- a/app/src/main/java/org/tasks/ui/CreationDateControlSet.kt
+++ b/app/src/main/java/org/tasks/ui/CreationDateControlSet.kt
@@ -1,50 +1,36 @@
package org.tasks.ui
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.unit.dp
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.ui.platform.ComposeView
+import com.google.android.material.composethemeadapter.MdcTheme
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
-import org.tasks.preferences.Preferences
-import java.text.SimpleDateFormat
+import org.tasks.compose.edit.InfoRow
import java.util.*
import javax.inject.Inject
@AndroidEntryPoint
-class CreationDateControlSet : TaskEditControlComposeFragment() {
+class CreationDateControlSet : TaskEditControlFragment() {
@Inject lateinit var locale: Locale
- @Composable
- override fun Body() {
- Column(modifier = Modifier.padding(vertical = 20.dp)) {
- val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm", locale)
- viewModel.creationDate?.let {
- Text(
- text = stringResource(id = R.string.sort_created_group, formatter.format(it))
- )
- }
- viewModel.modificationDate?.let {
- Text(
- text = stringResource(id = R.string.sort_modified_group, formatter.format(it))
- )
- }
- viewModel.completionDate?.takeIf { it > 0 }?.let {
- Text(
- text = stringResource(id = R.string.sort_completion_group, formatter.format(it))
- )
+ override fun bind(parent: ViewGroup?): View =
+ (parent as ComposeView).apply {
+ setContent {
+ MdcTheme {
+ InfoRow(
+ creationDate = viewModel.creationDate,
+ modificationDate = viewModel.modificationDate,
+ completionDate = viewModel.completionDate,
+ locale = locale,
+ )
+ }
}
}
- }
-
- override val icon = R.drawable.ic_outline_info_24px
override fun controlId() = TAG
companion object {
const val TAG = R.string.TEA_ctrl_creation_date
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/org/tasks/ui/DeadlineControlSet.kt b/app/src/main/java/org/tasks/ui/DeadlineControlSet.kt
index 19a491e14..72a6575a1 100644
--- a/app/src/main/java/org/tasks/ui/DeadlineControlSet.kt
+++ b/app/src/main/java/org/tasks/ui/DeadlineControlSet.kt
@@ -20,7 +20,7 @@ import java.util.*
import javax.inject.Inject
@AndroidEntryPoint
-class DeadlineControlSet : TaskEditControlComposeFragment() {
+class DeadlineControlSet : TaskEditControlFragment() {
@Inject lateinit var locale: Locale
@Inject lateinit var preferences: Preferences
diff --git a/app/src/main/java/org/tasks/ui/DescriptionControlSet.kt b/app/src/main/java/org/tasks/ui/DescriptionControlSet.kt
index 2a4dfedc1..172a37470 100644
--- a/app/src/main/java/org/tasks/ui/DescriptionControlSet.kt
+++ b/app/src/main/java/org/tasks/ui/DescriptionControlSet.kt
@@ -14,7 +14,7 @@ import org.tasks.ui.TaskEditViewModel.Companion.stripCarriageReturns
import javax.inject.Inject
@AndroidEntryPoint
-class DescriptionControlSet : TaskEditControlComposeFragment() {
+class DescriptionControlSet : TaskEditControlFragment() {
@Inject lateinit var linkify: Linkify
@Inject lateinit var preferences: Preferences
@Inject lateinit var markdownProvider: MarkdownProvider
diff --git a/app/src/main/java/org/tasks/ui/ListFragment.kt b/app/src/main/java/org/tasks/ui/ListFragment.kt
index 29e2040e4..c4e772dd7 100644
--- a/app/src/main/java/org/tasks/ui/ListFragment.kt
+++ b/app/src/main/java/org/tasks/ui/ListFragment.kt
@@ -17,7 +17,7 @@ import org.tasks.compose.edit.ListRow
import javax.inject.Inject
@AndroidEntryPoint
-class ListFragment : TaskEditControlComposeFragment() {
+class ListFragment : TaskEditControlFragment() {
@Inject lateinit var chipProvider: ChipProvider
override fun bind(parent: ViewGroup?): View =
diff --git a/app/src/main/java/org/tasks/ui/LocationControlSet.kt b/app/src/main/java/org/tasks/ui/LocationControlSet.kt
index d67dce282..fafbe098b 100644
--- a/app/src/main/java/org/tasks/ui/LocationControlSet.kt
+++ b/app/src/main/java/org/tasks/ui/LocationControlSet.kt
@@ -30,7 +30,7 @@ import org.tasks.preferences.Preferences
import javax.inject.Inject
@AndroidEntryPoint
-class LocationControlSet : TaskEditControlComposeFragment() {
+class LocationControlSet : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences
@Inject lateinit var dialogBuilder: DialogBuilder
@Inject lateinit var permissionChecker: PermissionChecker
diff --git a/app/src/main/java/org/tasks/ui/PriorityControlSet.kt b/app/src/main/java/org/tasks/ui/PriorityControlSet.kt
index cd46cabd6..c19111b1f 100644
--- a/app/src/main/java/org/tasks/ui/PriorityControlSet.kt
+++ b/app/src/main/java/org/tasks/ui/PriorityControlSet.kt
@@ -12,7 +12,7 @@ import org.tasks.preferences.Preferences
import javax.inject.Inject
@AndroidEntryPoint
-class PriorityControlSet : TaskEditControlComposeFragment() {
+class PriorityControlSet : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences
override fun bind(parent: ViewGroup?): View =
diff --git a/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt b/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt
index 37989c36a..c367f9b6d 100644
--- a/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt
+++ b/app/src/main/java/org/tasks/ui/SubtaskControlSet.kt
@@ -54,7 +54,7 @@ import org.tasks.themes.ColorProvider
import javax.inject.Inject
@AndroidEntryPoint
-class SubtaskControlSet : TaskEditControlComposeFragment() {
+class SubtaskControlSet : TaskEditControlFragment() {
@Inject lateinit var activity: Activity
@Inject lateinit var taskCompleter: TaskCompleter
@Inject lateinit var localBroadcastManager: LocalBroadcastManager
diff --git a/app/src/main/java/org/tasks/ui/TaskEditControlComposeFragment.kt b/app/src/main/java/org/tasks/ui/TaskEditControlComposeFragment.kt
deleted file mode 100644
index ba14b303c..000000000
--- a/app/src/main/java/org/tasks/ui/TaskEditControlComposeFragment.kt
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.tasks.ui
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material.ContentAlpha
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.alpha
-import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.unit.dp
-import androidx.lifecycle.ViewModelProvider
-import com.google.android.material.composethemeadapter.MdcTheme
-import org.tasks.compose.TaskEditIcon
-import org.tasks.compose.TaskEditRow
-
-abstract class TaskEditControlComposeFragment : TaskEditControlFragment() {
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- val composeView = ComposeView(requireActivity())
- viewModel = ViewModelProvider(requireParentFragment())[TaskEditViewModel::class.java]
- bind(composeView)
- createView(savedInstanceState)
- return composeView
- }
-
- override fun bind(parent: ViewGroup?): View =
- (parent as ComposeView).apply {
- setContent {
- MdcTheme {
- TaskEditRow(
- icon = { Icon() },
- content = { Body() },
- onClick = if (this@TaskEditControlComposeFragment.isClickable)
- this@TaskEditControlComposeFragment::onRowClick
- else
- null
- )
- }
- }
- }
-
- @Composable
- protected open fun Icon() {
- TaskEditIcon(
- id = icon,
- modifier = Modifier
- .padding(start = 16.dp, top = 20.dp, end = 32.dp, bottom = 20.dp)
- .alpha(ContentAlpha.medium),
- )
- }
-
- @Composable
- protected open fun Body() {}
-}
\ No newline at end of file
diff --git a/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt b/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt
index 5b8f6cd77..b4d72afb6 100644
--- a/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt
+++ b/app/src/main/java/org/tasks/ui/TaskEditControlFragment.kt
@@ -1,9 +1,21 @@
package org.tasks.ui
import android.os.Bundle
+import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material.ContentAlpha
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.unit.dp
import androidx.fragment.app.Fragment
+import androidx.lifecycle.ViewModelProvider
+import com.google.android.material.composethemeadapter.MdcTheme
+import org.tasks.compose.TaskEditIcon
+import org.tasks.compose.TaskEditRow
abstract class TaskEditControlFragment : Fragment() {
lateinit var viewModel: TaskEditViewModel
@@ -17,5 +29,45 @@ abstract class TaskEditControlFragment : Fragment() {
protected open val icon = 0
abstract fun controlId(): Int
- protected abstract fun bind(parent: ViewGroup?): View
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ val composeView = ComposeView(requireActivity())
+ viewModel = ViewModelProvider(requireParentFragment())[TaskEditViewModel::class.java]
+ bind(composeView)
+ createView(savedInstanceState)
+ return composeView
+ }
+
+ open fun bind(parent: ViewGroup?): View =
+ (parent as ComposeView).apply {
+ setContent {
+ MdcTheme {
+ TaskEditRow(
+ icon = { Icon() },
+ content = { Body() },
+ onClick = if (this@TaskEditControlFragment.isClickable)
+ this@TaskEditControlFragment::onRowClick
+ else
+ null
+ )
+ }
+ }
+ }
+
+ @Composable
+ protected open fun Icon() {
+ TaskEditIcon(
+ id = icon,
+ modifier = Modifier
+ .padding(start = 16.dp, top = 20.dp, end = 32.dp, bottom = 20.dp)
+ .alpha(ContentAlpha.medium),
+ )
+ }
+
+ @Composable
+ protected open fun Body() {}
}
\ No newline at end of file