Show list members on caldav list settings screen

pull/1400/head
Alex Baker 5 years ago
parent 19e25b9c39
commit 0f0c2bac93

@ -46,8 +46,9 @@ abstract class BaseCaldavCalendarSettingsActivity : BaseListSettingsActivity() {
@BindView(R.id.progress_bar) @BindView(R.id.progress_bar)
lateinit var progressView: ProgressBar lateinit var progressView: ProgressBar
private var caldavCalendar: CaldavCalendar? = null protected var caldavCalendar: CaldavCalendar? = null
private lateinit var caldavAccount: CaldavAccount
protected lateinit var caldavAccount: CaldavAccount
override val layout: Int override val layout: Int
get() = R.layout.activity_caldav_calendar_settings get() = R.layout.activity_caldav_calendar_settings

@ -2,21 +2,38 @@ package org.tasks.caldav
import android.os.Bundle import android.os.Bundle
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.lifecycle.lifecycleScope import androidx.compose.foundation.layout.*
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.view.isVisible
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import org.tasks.R import org.tasks.R
import org.tasks.data.CaldavAccount import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavCalendar import org.tasks.data.CaldavCalendar
import org.tasks.data.Principal
import org.tasks.data.Principal.Companion.name
import org.tasks.data.PrincipalDao
import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class CaldavCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() { class CaldavCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() {
@Inject lateinit var principalDao: PrincipalDao
private val createCalendarViewModel: CreateCalendarViewModel by viewModels() private val createCalendarViewModel: CreateCalendarViewModel by viewModels()
private val deleteCalendarViewModel: DeleteCalendarViewModel by viewModels() private val deleteCalendarViewModel: DeleteCalendarViewModel by viewModels()
private val updateCalendarViewModel: UpdateCalendarViewModel by viewModels() private val updateCalendarViewModel: UpdateCalendarViewModel by viewModels()
override val layout: Int override val layout = R.layout.activity_caldav_calendar_settings
get() = R.layout.activity_caldav_calendar_settings
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -27,6 +44,54 @@ class CaldavCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() {
this, this,
{ updateCalendar() }, { updateCalendar() },
this::requestFailed) this::requestFailed)
caldavCalendar?.takeIf { it.id > 0 }?.let {
principalDao.getPrincipals(it.id).observe(this) {
findViewById<ComposeView>(R.id.people)
.apply { isVisible = it.isNotEmpty() }
.setContent { PrincipalList(it) }
}
}
}
@Composable
private fun PrincipalList(principals: List<Principal>) {
tasksTheme.TasksTheme {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
) {
Text(
stringResource(R.string.list_members),
style = MaterialTheme.typography.h6,
color = MaterialTheme.colors.onBackground
)
Spacer(Modifier.height(8.dp))
principals.forEach {
PrincipalRow(it)
}
}
}
}
@Composable
fun PrincipalRow(principal: Principal) {
Row(modifier = Modifier
.padding(PaddingValues(0.dp, 16.dp))
.fillMaxWidth()) {
Icon(
painter = painterResource(R.drawable.ic_outline_perm_identity_24px),
contentDescription = null,
modifier = Modifier.padding(end = 16.dp),
tint = colorResource(R.color.icon_tint_with_alpha)
)
Text(
principal.name!!,
style = MaterialTheme.typography.body1,
color = MaterialTheme.colors.onBackground,
)
}
} }
override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) = override suspend fun createCalendar(caldavAccount: CaldavAccount, name: String, color: Int) =
@ -38,4 +103,13 @@ class CaldavCalendarSettingsActivity : BaseCaldavCalendarSettingsActivity() {
override suspend fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) = override suspend fun deleteCalendar(caldavAccount: CaldavAccount, caldavCalendar: CaldavCalendar) =
deleteCalendarViewModel.deleteCalendar(caldavAccount, caldavCalendar) deleteCalendarViewModel.deleteCalendar(caldavAccount, caldavCalendar)
@Preview
@Composable
private fun PreviewList() {
PrincipalList(listOf(
Principal().apply { displayName = "user1" },
Principal().apply { displayName = "user2" },
))
}
} }

@ -62,4 +62,15 @@ class Principal {
override fun toString(): String { override fun toString(): String {
return "Principal(id=$id, list=$list, principal=$principal, displayName=$displayName, inviteStatus=$inviteStatus, access=$access)" return "Principal(id=$id, list=$list, principal=$principal, displayName=$displayName, inviteStatus=$inviteStatus, access=$access)"
} }
companion object {
private val MAILTO = "^mailto:".toRegex()
private val LAST_SEGMENT = ".*/([^/]+).*".toRegex()
val Principal.name: String?
get() = displayName
?: principal
?.replace(MAILTO, "")
?.replaceFirst(LAST_SEGMENT, "$1")
}
} }

@ -1,5 +1,6 @@
package org.tasks.data package org.tasks.data
import androidx.lifecycle.LiveData
import androidx.room.* import androidx.room.*
@Dao @Dao
@ -19,4 +20,7 @@ WHERE principal_list = :list
@Query("SELECT * FROM principals") @Query("SELECT * FROM principals")
fun getAll(): List<Principal> fun getAll(): List<Principal>
@Query("SELECT * FROM principals WHERE principal_list = :id")
fun getPrincipals(id: Long): LiveData<List<Principal>>
} }

@ -4,15 +4,49 @@ import android.app.Activity
import android.content.Context import android.content.Context
import android.graphics.PixelFormat import android.graphics.PixelFormat
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import dagger.hilt.android.qualifiers.ActivityContext
import org.tasks.R import org.tasks.R
import javax.inject.Inject import javax.inject.Inject
class Theme @Inject constructor( class Theme @Inject constructor(
@ActivityContext val context: Context,
val themeBase: ThemeBase, val themeBase: ThemeBase,
val themeColor: ThemeColor, val themeColor: ThemeColor,
private val themeAccent: ThemeAccent private val themeAccent: ThemeAccent
) { ) {
fun withThemeColor(themeColor: ThemeColor) = Theme(themeBase, themeColor, themeAccent) private val darkTheme = themeBase.isDarkTheme(context as Activity)
@Composable
fun TasksTheme(
content: @Composable () -> Unit,
) {
val primary = Color(themeColor.primaryColor)
val onPrimary = Color(themeColor.colorOnPrimary)
val secondary = Color(themeAccent.accentColor)
MaterialTheme(
colors = if (darkTheme) {
darkColors(
primary = primary,
onPrimary = onPrimary,
secondary = secondary,
)
} else {
lightColors(
primary = primary,
onPrimary = onPrimary,
secondary = secondary,
)
},
content = content
)
}
fun withThemeColor(themeColor: ThemeColor) = Theme(context, themeBase, themeColor, themeAccent)
fun getLayoutInflater(context: Context) = fun getLayoutInflater(context: Context) =
wrap(context).getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater wrap(context).getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater

@ -36,6 +36,11 @@
<include layout="@layout/list_settings_icon"/> <include layout="@layout/list_settings_icon"/>
<androidx.compose.ui.platform.ComposeView
android:id="@+id/people"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>

@ -688,4 +688,5 @@ File %1$s contained %2$s.\n\n
<string name="tasks_org_account_required">Tasks.org account required</string> <string name="tasks_org_account_required">Tasks.org account required</string>
<string name="account_not_included">Not included with \'Name your price\' subscriptions</string> <string name="account_not_included">Not included with \'Name your price\' subscriptions</string>
<string name="map_theme_use_app_theme">Use app theme</string> <string name="map_theme_use_app_theme">Use app theme</string>
<string name="list_members">List members</string>
</resources> </resources>

@ -0,0 +1,34 @@
package org.tasks.data
import org.junit.Assert.assertEquals
import org.junit.Test
import org.tasks.data.Principal.Companion.name
class PrincipalTest {
@Test
fun lastSegmentTrailingSlash() {
val principal = Principal().apply {
principal = "principals/users/user1/"
}
assertEquals("user1", principal.name)
}
@Test
fun lastSegmentNoTrailingSlash() {
val principal = Principal().apply {
principal = "principals/users/user1"
}
assertEquals("user1", principal.name)
}
@Test
fun stripMailto() {
val principal = Principal().apply {
principal = "mailto:user@example.com"
}
assertEquals("user@example.com", principal.name)
}
}
Loading…
Cancel
Save