Calendar picker updates

* Move some components to compose package
* Add compose previews
* Use calendar id for selected
pull/1964/head
Alex Baker 2 years ago
parent df65415a83
commit 135f628dae

@ -5,37 +5,14 @@ import android.app.Activity
import android.app.Dialog
import android.content.Intent
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.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.ContentAlpha
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Block
import androidx.compose.material.icons.outlined.Check
import androidx.compose.material.icons.outlined.Event
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.google.android.material.composethemeadapter.MdcTheme
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.compose.CalendarPickerList
import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.dialogs.DialogBuilder
import javax.inject.Inject
@ -60,10 +37,19 @@ class CalendarPicker : DialogFragment() {
}
)
if (hasPermissions.allPermissionsGranted) {
CalendarList(
CalendarPickerList(
calendars = viewModel.viewState.collectAsStateLifecycleAware().value.calendars,
selected = arguments?.getString(EXTRA_SELECTED),
onClick = { selectEntry(it) },
onClick = {
targetFragment!!.onActivityResult(
targetRequestCode,
Activity.RESULT_OK,
Intent()
.putExtra(EXTRA_CALENDAR_ID, it?.id)
.putExtra(EXTRA_CALENDAR_NAME, it?.name)
)
dismiss()
},
)
}
LaunchedEffect(hasPermissions) {
@ -75,82 +61,6 @@ class CalendarPicker : DialogFragment() {
.show()
}
@Composable
fun CalendarList(
calendars: List<AndroidCalendar>,
selected: String?,
onClick: (AndroidCalendar?) -> Unit,
) {
MdcTheme {
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.padding(vertical = 12.dp)
) {
CalendarRow(
icon = Icons.Outlined.Block,
tint = MaterialTheme.colors.onSurface,
text = stringResource(id = R.string.dont_add_to_calendar),
selected = selected.isNullOrBlank(),
onClick = { onClick(null) },
)
calendars.forEach {
CalendarRow(
icon = Icons.Outlined.Event,
tint = Color(it.color),
text = it.name,
selected = selected == it.name,
onClick = { onClick(it) }
)
}
}
}
}
@Composable
fun CalendarRow(
icon: ImageVector,
tint: Color,
text: String,
selected: Boolean,
onClick: () -> Unit,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable { onClick() }
) {
Icon(
imageVector = icon,
contentDescription = null,
tint = tint.copy(alpha = ContentAlpha.medium),
modifier = Modifier.padding(start = 16.dp, end = 32.dp, top = 12.dp, bottom = 12.dp),
)
Text(
text = text,
style = MaterialTheme.typography.body1,
modifier = Modifier.weight(1f),
)
if (selected) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colors.primary.copy(alpha = ContentAlpha.medium),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
)
}
}
}
private fun selectEntry(calendar: AndroidCalendar?) {
val data = Intent()
data.putExtra(EXTRA_CALENDAR_ID, calendar?.id)
data.putExtra(EXTRA_CALENDAR_NAME, calendar?.name)
targetFragment!!.onActivityResult(targetRequestCode, Activity.RESULT_OK, data)
dismiss()
}
companion object {
const val EXTRA_CALENDAR_ID = "extra_calendar_id"
const val EXTRA_CALENDAR_NAME = "extra_calendar_name"

@ -0,0 +1,87 @@
package org.tasks.compose
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Block
import androidx.compose.material.icons.outlined.Event
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
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.calendars.AndroidCalendar
@Composable
fun CalendarPickerList(
calendars: List<AndroidCalendar>,
selected: String?,
onClick: (AndroidCalendar?) -> Unit,
) {
val selectedCalendar = calendars.find { it.id == selected }
MdcTheme {
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.padding(vertical = 12.dp)
) {
CheckableIconRow(
icon = Icons.Outlined.Block,
tint = MaterialTheme.colors.onSurface,
text = stringResource(id = R.string.dont_add_to_calendar),
selected = selectedCalendar == null,
onClick = { onClick(null) },
)
calendars.forEach {
CheckableIconRow(
icon = Icons.Outlined.Event,
tint = Color(it.color),
text = it.name,
selected = selectedCalendar == it,
onClick = { onClick(it) }
)
}
}
}
}
@Preview(showBackground = true, widthDp = 320)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
@Composable
fun CalendarPicker() {
MdcTheme {
CalendarPickerList(
calendars = listOf(
AndroidCalendar("1", "Home", -765666),
AndroidCalendar("2", "Work", -5434281),
AndroidCalendar("3", "Personal", -10395295),
),
selected = "2",
onClick = {},
)
}
}
@Preview(showBackground = true, widthDp = 320)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
@Composable
fun CalendarPickerNoneSelected() {
MdcTheme {
CalendarPickerList(
calendars = listOf(
AndroidCalendar("1", "Home", -765666),
AndroidCalendar("2", "Work", -5434281),
AndroidCalendar("3", "Personal", -10395295),
),
selected = null,
onClick = {},
)
}
}

@ -0,0 +1,54 @@
package org.tasks.compose
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.ContentAlpha
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Check
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
@Composable
fun CheckableIconRow(
icon: ImageVector,
tint: Color,
text: String,
selected: Boolean,
onClick: () -> Unit,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.clickable { onClick() }
) {
Icon(
imageVector = icon,
contentDescription = null,
tint = tint.copy(alpha = ContentAlpha.medium),
modifier = Modifier.padding(start = 16.dp, end = 32.dp, top = 12.dp, bottom = 12.dp),
)
Text(
text = text,
style = MaterialTheme.typography.body1,
modifier = Modifier.weight(1f),
)
if (selected) {
Icon(
imageVector = Icons.Outlined.Check,
contentDescription = null,
tint = MaterialTheme.colors.primary.copy(alpha = ContentAlpha.medium),
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
)
}
}
}

@ -58,7 +58,7 @@ class TaskDefaults : InjectingPreferenceFragment() {
override suspend fun setupPreferences(savedInstanceState: Bundle?) {
defaultCalendarPref = findPreference(R.string.gcal_p_default)
defaultCalendarPref.onPreferenceClickListener = Preference.OnPreferenceClickListener {
newCalendarPicker(this, REQUEST_CALENDAR_SELECTION, getDefaultCalendarName())
newCalendarPicker(this, REQUEST_CALENDAR_SELECTION, preferences.defaultCalendar)
.show(parentFragmentManager, FRAG_TAG_CALENDAR_PICKER)
false
}
@ -181,7 +181,7 @@ class TaskDefaults : InjectingPreferenceFragment() {
}
private fun getDefaultCalendarName(): String? {
val calendarId = preferences.getStringValue(R.string.gcal_p_default)
val calendarId = preferences.defaultCalendar
return calendarProvider.getCalendar(calendarId)?.name
}

@ -57,7 +57,7 @@ class CalendarControlSet : TaskEditControlFragment() {
.newCalendarPicker(
requireParentFragment(),
TaskEditFragment.REQUEST_CODE_PICK_CALENDAR,
calendarName
viewModel.selectedCalendar.value,
)
.show(
requireParentFragment().parentFragmentManager,
@ -104,9 +104,6 @@ class CalendarControlSet : TaskEditControlFragment() {
}
}
private val calendarName: String?
get() = viewModel.selectedCalendar.value?.let { calendarProvider.getCalendar(it)?.name }
private fun calendarEntryExists(eventUri: String?): Boolean {
if (isNullOrEmpty(eventUri)) {
return false

Loading…
Cancel
Save