mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-11-10 10:56:48 +01:00
Improves design of the lists and User management screen.
This commit is contained in:
@@ -21,8 +21,8 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.memberEdit
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.memberEdit
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@@ -35,19 +35,24 @@ import androidx.compose.foundation.layout.padding
|
|||||||
import androidx.compose.foundation.layout.recalculateWindowInsets
|
import androidx.compose.foundation.layout.recalculateWindowInsets
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.PlaylistAddCheck
|
import androidx.compose.material.icons.automirrored.filled.PlaylistAdd
|
||||||
import androidx.compose.material.icons.filled.PersonAdd
|
import androidx.compose.material.icons.filled.PersonAdd
|
||||||
import androidx.compose.material.icons.filled.PersonRemove
|
import androidx.compose.material.icons.filled.PersonRemove
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material.icons.outlined.Groups
|
||||||
|
import androidx.compose.material.icons.outlined.Lock
|
||||||
|
import androidx.compose.material.icons.outlined.Public
|
||||||
|
import androidx.compose.material.icons.outlined.RemoveCircleOutline
|
||||||
import androidx.compose.material3.DropdownMenu
|
import androidx.compose.material3.DropdownMenu
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.FilterChip
|
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.ListItem
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
@@ -60,16 +65,8 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
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.LocalContext
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.semantics.Role
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.text.intl.Locale
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
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
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
@@ -78,13 +75,14 @@ import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUse
|
|||||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||||
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton
|
import com.vitorpamplona.amethyst.ui.navigation.topbars.TopBarWithBackButton
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.DisplayParticipantNumberAndStatus
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewPeopleListCreationDialog
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.NewPeopleListCreationDialog
|
||||||
import com.vitorpamplona.amethyst.ui.stringRes
|
import com.vitorpamplona.amethyst.ui.stringRes
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
import com.vitorpamplona.amethyst.ui.theme.SpacedBy10dp
|
import com.vitorpamplona.amethyst.ui.theme.HalfHalfVertPadding
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size15Modifier
|
||||||
|
import com.vitorpamplona.amethyst.ui.theme.Size50ModifierOffset10
|
||||||
import com.vitorpamplona.amethyst.ui.theme.SpacedBy5dp
|
import com.vitorpamplona.amethyst.ui.theme.SpacedBy5dp
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
|
||||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||||
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn
|
||||||
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
import com.vitorpamplona.quartz.nip01Core.core.HexKey
|
||||||
@@ -124,16 +122,17 @@ fun EditPeopleListScreen(
|
|||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.recalculateWindowInsets(),
|
.recalculateWindowInsets(),
|
||||||
|
floatingActionButton = {
|
||||||
|
PeopleListFabsAndMenu(accountViewModel)
|
||||||
|
},
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBarWithBackButton(stringRes(id = R.string.follow_set_man_dialog_title), nav::popBack)
|
TopBarWithBackButton(stringRes(id = R.string.follow_set_man_dialog_title2, userToAddOrRemove.toBestDisplayName()), nav::popBack)
|
||||||
},
|
},
|
||||||
) { contentPadding ->
|
) { contentPadding ->
|
||||||
Column(
|
Column(
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.padding(
|
.padding(
|
||||||
start = 10.dp,
|
|
||||||
end = 10.dp,
|
|
||||||
top = contentPadding.calculateTopPadding(),
|
top = contentPadding.calculateTopPadding(),
|
||||||
bottom = contentPadding.calculateBottomPadding(),
|
bottom = contentPadding.calculateBottomPadding(),
|
||||||
).consumeWindowInsets(contentPadding)
|
).consumeWindowInsets(contentPadding)
|
||||||
@@ -144,6 +143,44 @@ fun EditPeopleListScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun PeopleListFabsAndMenu(accountViewModel: AccountViewModel) {
|
||||||
|
var isOpen by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
ExtendedFloatingActionButton(
|
||||||
|
text = {
|
||||||
|
Text(text = stringRes(R.string.follow_set_create_btn_label))
|
||||||
|
},
|
||||||
|
icon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.AutoMirrored.Filled.PlaylistAdd,
|
||||||
|
contentDescription = null,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onClick = { isOpen = !isOpen },
|
||||||
|
shape = CircleShape,
|
||||||
|
containerColor = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
|
||||||
|
if (isOpen) {
|
||||||
|
NewPeopleListCreationDialog(
|
||||||
|
onDismiss = {
|
||||||
|
isOpen = false
|
||||||
|
},
|
||||||
|
onCreateList = { name, description ->
|
||||||
|
accountViewModel.runIOCatching {
|
||||||
|
accountViewModel.account.peopleLists.addFollowList(
|
||||||
|
listName = name,
|
||||||
|
listDescription = description,
|
||||||
|
account = accountViewModel.account,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
isOpen = false
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun FollowSetManagementScreenBody(
|
private fun FollowSetManagementScreenBody(
|
||||||
userToAddOrRemove: User,
|
userToAddOrRemove: User,
|
||||||
@@ -163,6 +200,7 @@ private fun FollowSetManagementScreenBody(
|
|||||||
FollowSetItem(
|
FollowSetItem(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
listHeader = list.title,
|
listHeader = list.title,
|
||||||
|
listDescription = list.description ?: "",
|
||||||
userName = userName,
|
userName = userName,
|
||||||
userIsPrivateMember = list.privateMembers.contains(userToAddOrRemove),
|
userIsPrivateMember = list.privateMembers.contains(userToAddOrRemove),
|
||||||
userIsPublicMember = list.publicMembers.contains(userToAddOrRemove),
|
userIsPublicMember = list.publicMembers.contains(userToAddOrRemove),
|
||||||
@@ -176,6 +214,8 @@ private fun FollowSetManagementScreenBody(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
privateMemberSize = list.privateMembers.size,
|
||||||
|
publicMemberSize = list.publicMembers.size,
|
||||||
onAddUserToList = { userShouldBePrivate ->
|
onAddUserToList = { userShouldBePrivate ->
|
||||||
accountViewModel.runIOCatching {
|
accountViewModel.runIOCatching {
|
||||||
accountViewModel.account.peopleLists.addUserToSet(
|
accountViewModel.account.peopleLists.addUserToSet(
|
||||||
@@ -191,21 +231,6 @@ private fun FollowSetManagementScreenBody(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FollowSetsCreationMenu(
|
|
||||||
userName = userToAddOrRemove.toBestDisplayName(),
|
|
||||||
onSetCreate = { setName, memberShouldBePrivate, description ->
|
|
||||||
accountViewModel.runIOCatching {
|
|
||||||
accountViewModel.account.peopleLists.addFollowList(
|
|
||||||
listName = setName,
|
|
||||||
listDescription = description,
|
|
||||||
isPrivate = memberShouldBePrivate,
|
|
||||||
member = userToAddOrRemove,
|
|
||||||
account = accountViewModel.account,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -229,9 +254,12 @@ fun FollowSetItemMemberPreview() {
|
|||||||
FollowSetItem(
|
FollowSetItem(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
listHeader = "list title",
|
listHeader = "list title",
|
||||||
|
listDescription = "desc",
|
||||||
userName = "User",
|
userName = "User",
|
||||||
userIsPrivateMember = true,
|
userIsPrivateMember = true,
|
||||||
userIsPublicMember = true,
|
userIsPublicMember = true,
|
||||||
|
privateMemberSize = 3,
|
||||||
|
publicMemberSize = 2,
|
||||||
onAddUserToList = {},
|
onAddUserToList = {},
|
||||||
onRemoveUser = {},
|
onRemoveUser = {},
|
||||||
)
|
)
|
||||||
@@ -245,9 +273,12 @@ fun FollowSetItemNotMemberPreview() {
|
|||||||
FollowSetItem(
|
FollowSetItem(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
listHeader = "list title",
|
listHeader = "list title",
|
||||||
|
listDescription = "desc",
|
||||||
userName = "User",
|
userName = "User",
|
||||||
userIsPrivateMember = false,
|
userIsPrivateMember = false,
|
||||||
userIsPublicMember = false,
|
userIsPublicMember = false,
|
||||||
|
privateMemberSize = 3,
|
||||||
|
publicMemberSize = 2,
|
||||||
onAddUserToList = {},
|
onAddUserToList = {},
|
||||||
onRemoveUser = {},
|
onRemoveUser = {},
|
||||||
)
|
)
|
||||||
@@ -258,114 +289,134 @@ fun FollowSetItemNotMemberPreview() {
|
|||||||
fun FollowSetItem(
|
fun FollowSetItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
listHeader: String,
|
listHeader: String,
|
||||||
|
listDescription: String,
|
||||||
userName: String,
|
userName: String,
|
||||||
userIsPrivateMember: Boolean,
|
userIsPrivateMember: Boolean,
|
||||||
userIsPublicMember: Boolean,
|
userIsPublicMember: Boolean,
|
||||||
|
publicMemberSize: Int,
|
||||||
|
privateMemberSize: Int,
|
||||||
onAddUserToList: (shouldBePrivateMember: Boolean) -> Unit,
|
onAddUserToList: (shouldBePrivateMember: Boolean) -> Unit,
|
||||||
onRemoveUser: () -> Unit,
|
onRemoveUser: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val isUserInList = userIsPrivateMember || userIsPublicMember
|
val isUserInList = userIsPrivateMember || userIsPublicMember
|
||||||
Row(
|
|
||||||
modifier = modifier.padding(all = 10.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = SpacedBy10dp,
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = modifier.weight(1f),
|
|
||||||
verticalArrangement = SpacedBy5dp,
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
horizontalArrangement = SpacedBy5dp,
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
painter = painterResource(R.drawable.format_list_bulleted_type),
|
|
||||||
contentDescription = stringRes(R.string.follow_set_icon_description),
|
|
||||||
)
|
|
||||||
Text(listHeader, fontWeight = FontWeight.Bold)
|
|
||||||
}
|
|
||||||
|
|
||||||
FilterChip(
|
ListItem(
|
||||||
selected = true,
|
modifier = modifier,
|
||||||
onClick = {},
|
headlineContent = {
|
||||||
label = {
|
Text(listHeader, maxLines = 1, overflow = TextOverflow.Ellipsis)
|
||||||
Text(
|
},
|
||||||
text =
|
supportingContent = {
|
||||||
if (isUserInList) {
|
Row(
|
||||||
if (userIsPublicMember) {
|
modifier = HalfHalfVertPadding,
|
||||||
stringRes(R.string.follow_set_public_presence_indicator, userName)
|
horizontalArrangement = SpacedBy5dp,
|
||||||
} else {
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
stringRes(R.string.follow_set_private_presence_indicator, userName)
|
) {
|
||||||
}
|
val text =
|
||||||
} else {
|
|
||||||
stringRes(R.string.follow_set_absence_indicator, userName)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
},
|
|
||||||
leadingIcon =
|
|
||||||
if (isUserInList) {
|
if (isUserInList) {
|
||||||
{
|
if (userIsPublicMember) {
|
||||||
Icon(
|
stringRes(R.string.follow_set_public_presence_indicator, userName)
|
||||||
imageVector = Icons.AutoMirrored.Filled.PlaylistAddCheck,
|
} else {
|
||||||
contentDescription = null,
|
stringRes(R.string.follow_set_private_presence_indicator, userName)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
null
|
stringRes(R.string.follow_set_absence_indicator2, userName)
|
||||||
},
|
|
||||||
shape = ButtonBorder,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Column(
|
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
) {
|
|
||||||
val isUserAddTapped = remember { mutableStateOf(false) }
|
|
||||||
IconButton(
|
|
||||||
onClick = {
|
|
||||||
if (isUserInList) {
|
|
||||||
onRemoveUser()
|
|
||||||
} else {
|
|
||||||
isUserAddTapped.value = true
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.background(
|
|
||||||
color =
|
|
||||||
if (isUserInList) {
|
|
||||||
MaterialTheme.colorScheme.errorContainer
|
|
||||||
} else {
|
|
||||||
MaterialTheme.colorScheme.primary
|
|
||||||
},
|
|
||||||
shape = RoundedCornerShape(percent = 80),
|
|
||||||
),
|
|
||||||
) {
|
|
||||||
if (isUserInList) {
|
if (isUserInList) {
|
||||||
Icon(
|
if (userIsPublicMember) {
|
||||||
imageVector = Icons.Filled.PersonRemove,
|
Icon(
|
||||||
contentDescription = null,
|
imageVector = Icons.Outlined.Public,
|
||||||
tint = MaterialTheme.colorScheme.onBackground,
|
contentDescription = text,
|
||||||
)
|
modifier = Size15Modifier,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
} else if (userIsPrivateMember) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Lock,
|
||||||
|
contentDescription = text,
|
||||||
|
modifier = Size15Modifier,
|
||||||
|
tint = MaterialTheme.colorScheme.primary,
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Filled.PersonAdd,
|
imageVector = Icons.Outlined.RemoveCircleOutline,
|
||||||
contentDescription = null,
|
contentDescription = text,
|
||||||
tint = Color.White,
|
modifier = Size15Modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
overflow = TextOverflow.MiddleEllipsis,
|
||||||
|
maxLines = 1,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
leadingContent = {
|
||||||
|
Box(contentAlignment = Alignment.Center) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Groups,
|
||||||
|
contentDescription = stringRes(R.string.follow_set_icon_description),
|
||||||
|
modifier = Size50ModifierOffset10,
|
||||||
|
)
|
||||||
|
DisplayParticipantNumberAndStatus(
|
||||||
|
modifier = Modifier.align(Alignment.BottomCenter),
|
||||||
|
privateMembersSize = privateMemberSize,
|
||||||
|
publicMembersSize = publicMemberSize,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
trailingContent = {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
val isUserAddTapped = remember { mutableStateOf(false) }
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
if (isUserInList) {
|
||||||
|
onRemoveUser()
|
||||||
|
} else {
|
||||||
|
isUserAddTapped.value = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.background(
|
||||||
|
color =
|
||||||
|
if (isUserInList) {
|
||||||
|
MaterialTheme.colorScheme.errorContainer
|
||||||
|
} else {
|
||||||
|
MaterialTheme.colorScheme.primary
|
||||||
|
},
|
||||||
|
shape = RoundedCornerShape(percent = 80),
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
if (isUserInList) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.PersonRemove,
|
||||||
|
contentDescription = stringRes(R.string.remove_user_from_the_list),
|
||||||
|
tint = MaterialTheme.colorScheme.onBackground,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.PersonAdd,
|
||||||
|
contentDescription = stringRes(R.string.add_user_to_the_list),
|
||||||
|
tint = Color.White,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UserAdditionOptionsMenu(
|
UserAdditionOptionsMenu(
|
||||||
isExpanded = isUserAddTapped.value,
|
isExpanded = isUserAddTapped.value,
|
||||||
onUserAdd = { shouldBePrivateMember ->
|
onUserAdd = { shouldBePrivateMember ->
|
||||||
onAddUserToList(shouldBePrivateMember)
|
onAddUserToList(shouldBePrivateMember)
|
||||||
},
|
},
|
||||||
onDismiss = { isUserAddTapped.value = false },
|
onDismiss = { isUserAddTapped.value = false },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@@ -398,117 +449,3 @@ private fun UserAdditionOptionsMenu(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun FollowSetsCreationMenu(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
userName: String,
|
|
||||||
onSetCreate: (setName: String, memberShouldBePrivate: Boolean, description: String?) -> Unit,
|
|
||||||
) {
|
|
||||||
val isListAdditionDialogOpen = remember { mutableStateOf(false) }
|
|
||||||
val isPrivateOptionTapped = remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = modifier.padding(vertical = 30.dp),
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
stringRes(R.string.follow_set_creation_menu_title),
|
|
||||||
fontSize = 18.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
textAlign = TextAlign.Start,
|
|
||||||
)
|
|
||||||
HorizontalDivider(
|
|
||||||
modifier = Modifier.fillMaxWidth(0.5f),
|
|
||||||
thickness = 3.dp,
|
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
|
||||||
)
|
|
||||||
Spacer(modifier = StdVertSpacer)
|
|
||||||
FollowSetCreationItem(
|
|
||||||
setIsPrivate = false,
|
|
||||||
userName = userName,
|
|
||||||
onClick = {
|
|
||||||
isListAdditionDialogOpen.value = true
|
|
||||||
},
|
|
||||||
)
|
|
||||||
FollowSetCreationItem(
|
|
||||||
setIsPrivate = true,
|
|
||||||
userName = userName,
|
|
||||||
onClick = {
|
|
||||||
isPrivateOptionTapped.value = true
|
|
||||||
isListAdditionDialogOpen.value = true
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isListAdditionDialogOpen.value) {
|
|
||||||
NewPeopleListCreationDialog(
|
|
||||||
onDismiss = {
|
|
||||||
isListAdditionDialogOpen.value = false
|
|
||||||
isPrivateOptionTapped.value = false
|
|
||||||
},
|
|
||||||
onCreateList = { name, description ->
|
|
||||||
onSetCreate(name, isPrivateOptionTapped.value, description)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun FollowSetCreationItem(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
setIsPrivate: Boolean,
|
|
||||||
userName: String,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val setTypeLabel = stringRes(context, if (setIsPrivate) R.string.follow_set_type_private else R.string.follow_set_type_public)
|
|
||||||
|
|
||||||
HorizontalDivider(thickness = DividerThickness)
|
|
||||||
Column(
|
|
||||||
modifier =
|
|
||||||
modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.background(
|
|
||||||
color =
|
|
||||||
ButtonDefaults
|
|
||||||
.filledTonalButtonColors()
|
|
||||||
.containerColor
|
|
||||||
.copy(alpha = 0.2f),
|
|
||||||
).padding(vertical = 15.dp)
|
|
||||||
.clickable(role = Role.Button, onClick = onClick),
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text =
|
|
||||||
stringRes(
|
|
||||||
R.string.follow_set_creation_item_label,
|
|
||||||
setTypeLabel,
|
|
||||||
),
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
)
|
|
||||||
Spacer(modifier = StdHorzSpacer)
|
|
||||||
Icon(
|
|
||||||
painter =
|
|
||||||
painterResource(
|
|
||||||
if (setIsPrivate) R.drawable.lock_plus else R.drawable.earth_plus,
|
|
||||||
),
|
|
||||||
contentDescription = null,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Spacer(modifier = StdVertSpacer)
|
|
||||||
Text(
|
|
||||||
stringRes(
|
|
||||||
R.string.follow_set_creation_item_description,
|
|
||||||
userName,
|
|
||||||
setTypeLabel.lowercase(Locale.current.platformLocale),
|
|
||||||
),
|
|
||||||
fontWeight = FontWeight.Light,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
maxLines = 2,
|
|
||||||
color = Color.Gray,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
HorizontalDivider(thickness = DividerThickness)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -538,6 +538,8 @@
|
|||||||
<string name="follow_set_empty_label">No members</string>
|
<string name="follow_set_empty_label">No members</string>
|
||||||
<string name="follow_set_empty_label2">Empty</string>
|
<string name="follow_set_empty_label2">Empty</string>
|
||||||
<string name="follow_set_absence_indicator">%1$s is not in this list</string>
|
<string name="follow_set_absence_indicator">%1$s is not in this list</string>
|
||||||
|
<string name="follow_set_absence_indicator2">%1$s is not a member</string>
|
||||||
|
<string name="follow_set_man_dialog_title2">Your Lists and %1$s</string>
|
||||||
<string name="follow_set_man_dialog_title">Your Lists</string>
|
<string name="follow_set_man_dialog_title">Your Lists</string>
|
||||||
<string name="follow_set_empty_dialog_msg">No follow lists were found, or you don\'t have any follow lists. Tap below to refresh, or use the menu to create one.</string>
|
<string name="follow_set_empty_dialog_msg">No follow lists were found, or you don\'t have any follow lists. Tap below to refresh, or use the menu to create one.</string>
|
||||||
<string name="follow_set_error_dialog_msg">There was a problem while fetching: %1$s</string>
|
<string name="follow_set_error_dialog_msg">There was a problem while fetching: %1$s</string>
|
||||||
@@ -1344,4 +1346,6 @@
|
|||||||
<string name="in_the_list">Already in the list</string>
|
<string name="in_the_list">Already in the list</string>
|
||||||
<string name="private_members">Private Members</string>
|
<string name="private_members">Private Members</string>
|
||||||
<string name="public_members">Public Members</string>
|
<string name="public_members">Public Members</string>
|
||||||
|
<string name="add_user_to_the_list">Add user to the list</string>
|
||||||
|
<string name="remove_user_from_the_list">Add user to the list</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user