mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-11-10 21:46:45 +01:00
Refactor UI to adapt to correct way of managing follow sets.
This commit is contained in:
@@ -30,9 +30,11 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.PlaylistAdd
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Tab
|
||||
@@ -48,8 +50,6 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
@@ -119,12 +119,11 @@ fun ListsAndSetsScreen(
|
||||
refresh = {
|
||||
followSetsViewModel.invalidateData()
|
||||
},
|
||||
addItem = { title: String, description: String?, listType: SetVisibility ->
|
||||
val isSetPrivate = listType == SetVisibility.Private
|
||||
addItem = { title: String, description: String? ->
|
||||
|
||||
followSetsViewModel.addFollowSet(
|
||||
setName = title,
|
||||
setDescription = description,
|
||||
isListPrivate = isSetPrivate,
|
||||
account = accountViewModel.account,
|
||||
)
|
||||
},
|
||||
@@ -153,14 +152,14 @@ fun ListsAndSetsScreen(
|
||||
fun CustomListsScreen(
|
||||
followSetFeedState: FollowSetFeedState,
|
||||
refresh: () -> Unit,
|
||||
addItem: (title: String, description: String?, listType: SetVisibility) -> Unit,
|
||||
addItem: (title: String, description: String?) -> Unit,
|
||||
openItem: (identifier: String) -> Unit,
|
||||
renameItem: (followSet: FollowSet, newName: String) -> Unit,
|
||||
deleteItem: (followSet: FollowSet) -> Unit,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
) {
|
||||
val pagerState = rememberPagerState { 3 }
|
||||
val pagerState = rememberPagerState { 2 }
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
DisappearingScaffold(
|
||||
@@ -185,22 +184,14 @@ fun CustomListsScreen(
|
||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(1) } },
|
||||
text = { Text(text = stringRes(R.string.labeled_bookmarks), overflow = TextOverflow.Visible) },
|
||||
)
|
||||
Tab(
|
||||
selected = pagerState.currentPage == 2,
|
||||
onClick = { coroutineScope.launch { pagerState.animateScrollToPage(2) } },
|
||||
text = { Text(text = stringRes(R.string.general_bookmarks), overflow = TextOverflow.Visible) },
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
floatingButton = {
|
||||
// TODO: Show components based on current tab
|
||||
FollowSetFabsAndMenu(
|
||||
onAddPrivateSet = { name: String, description: String? ->
|
||||
addItem(name, description, SetVisibility.Private)
|
||||
},
|
||||
onAddPublicSet = { name: String, description: String? ->
|
||||
addItem(name, description, SetVisibility.Public)
|
||||
onAddSet = { name: String, description: String? ->
|
||||
addItem(name, description)
|
||||
},
|
||||
)
|
||||
},
|
||||
@@ -226,7 +217,7 @@ fun CustomListsScreen(
|
||||
)
|
||||
|
||||
1 -> LabeledBookmarksFeedView()
|
||||
2 -> GeneralBookmarksFeedView()
|
||||
// 2 -> GeneralBookmarksFeedView()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -236,57 +227,34 @@ fun CustomListsScreen(
|
||||
@Composable
|
||||
private fun FollowSetFabsAndMenu(
|
||||
modifier: Modifier = Modifier,
|
||||
onAddPrivateSet: (name: String, description: String?) -> Unit,
|
||||
onAddPublicSet: (name: String, description: String?) -> Unit,
|
||||
onAddSet: (name: String, description: String?) -> Unit,
|
||||
) {
|
||||
val isSetAdditionDialogOpen = remember { mutableStateOf(false) }
|
||||
val isPrivateOptionTapped = remember { mutableStateOf(false) }
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(10.dp),
|
||||
) {
|
||||
FloatingActionButton(
|
||||
onClick = {
|
||||
isPrivateOptionTapped.value = true
|
||||
isSetAdditionDialogOpen.value = true
|
||||
ExtendedFloatingActionButton(
|
||||
text = {
|
||||
Text(text = "New")
|
||||
},
|
||||
shape = CircleShape,
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
) {
|
||||
icon = {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.lock_plus),
|
||||
imageVector = Icons.AutoMirrored.Filled.PlaylistAdd,
|
||||
contentDescription = null,
|
||||
tint = Color.White,
|
||||
)
|
||||
}
|
||||
FloatingActionButton(
|
||||
},
|
||||
onClick = {
|
||||
isSetAdditionDialogOpen.value = true
|
||||
},
|
||||
shape = CircleShape,
|
||||
containerColor = MaterialTheme.colorScheme.primary,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.earth_plus),
|
||||
contentDescription = null,
|
||||
tint = Color.White,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (isSetAdditionDialogOpen.value) {
|
||||
NewSetCreationDialog(
|
||||
onDismiss = {
|
||||
isSetAdditionDialogOpen.value = false
|
||||
isPrivateOptionTapped.value = false
|
||||
},
|
||||
shouldBePrivate = isPrivateOptionTapped.value,
|
||||
onCreateList = { name, description ->
|
||||
if (isPrivateOptionTapped.value) {
|
||||
onAddPrivateSet(name, description)
|
||||
} else {
|
||||
onAddPublicSet(name, description)
|
||||
}
|
||||
onAddSet(name, description)
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -296,27 +264,10 @@ private fun FollowSetFabsAndMenu(
|
||||
fun NewSetCreationDialog(
|
||||
modifier: Modifier = Modifier,
|
||||
onDismiss: () -> Unit,
|
||||
shouldBePrivate: Boolean,
|
||||
onCreateList: (name: String, description: String?) -> Unit,
|
||||
) {
|
||||
val newListName = remember { mutableStateOf("") }
|
||||
val newListDescription = remember { mutableStateOf<String?>(null) }
|
||||
val context = LocalContext.current
|
||||
|
||||
val listTypeText =
|
||||
stringRes(
|
||||
context,
|
||||
when (shouldBePrivate) {
|
||||
true -> R.string.follow_set_type_private
|
||||
false -> R.string.follow_set_type_public
|
||||
},
|
||||
)
|
||||
|
||||
val listTypeIcon =
|
||||
when (shouldBePrivate) {
|
||||
true -> R.drawable.lock
|
||||
false -> R.drawable.ic_public
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = onDismiss,
|
||||
@@ -325,12 +276,8 @@ fun NewSetCreationDialog(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(listTypeIcon),
|
||||
contentDescription = null,
|
||||
)
|
||||
Text(
|
||||
text = stringRes(R.string.follow_set_creation_dialog_title, listTypeText),
|
||||
text = stringRes(R.string.follow_set_creation_dialog_title),
|
||||
)
|
||||
}
|
||||
},
|
||||
@@ -347,7 +294,7 @@ fun NewSetCreationDialog(
|
||||
},
|
||||
)
|
||||
Spacer(modifier = DoubleVertSpacer)
|
||||
// For the list description
|
||||
// For the set description
|
||||
TextField(
|
||||
value =
|
||||
(
|
||||
|
||||
@@ -37,13 +37,10 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
@@ -56,7 +53,6 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.followSets.FollowSet
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.followSets.SetVisibility
|
||||
import com.vitorpamplona.amethyst.ui.components.ClickableBox
|
||||
import com.vitorpamplona.amethyst.ui.note.VerticalDotsIcon
|
||||
import com.vitorpamplona.amethyst.ui.stringRes
|
||||
@@ -64,7 +60,6 @@ import com.vitorpamplona.amethyst.ui.theme.ButtonBorder
|
||||
import com.vitorpamplona.amethyst.ui.theme.Size5dp
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdVertSpacer
|
||||
import kotlin.let
|
||||
|
||||
@Composable
|
||||
fun CustomSetItem(
|
||||
@@ -96,11 +91,12 @@ fun CustomSetItem(
|
||||
) {
|
||||
Text(followSet.title, fontWeight = FontWeight.Bold)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
if (followSet.publicProfiles.isEmpty() && followSet.privateProfiles.isEmpty()) {
|
||||
FilterChip(
|
||||
selected = true,
|
||||
onClick = {},
|
||||
label = {
|
||||
Text(text = "${followSet.profiles.size}")
|
||||
Text(text = "No members")
|
||||
},
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
@@ -111,6 +107,60 @@ fun CustomSetItem(
|
||||
shape = ButtonBorder,
|
||||
)
|
||||
}
|
||||
if (followSet.publicProfiles.isNotEmpty()) {
|
||||
val publicMemberSize = followSet.publicProfiles.size
|
||||
val membersLabel =
|
||||
stringRes(
|
||||
context,
|
||||
if (publicMemberSize == 1) {
|
||||
R.string.follow_set_single_member_label
|
||||
} else {
|
||||
R.string.follow_set_multiple_member_label
|
||||
},
|
||||
)
|
||||
FilterChip(
|
||||
selected = true,
|
||||
onClick = {},
|
||||
label = {
|
||||
Text(text = "$publicMemberSize $membersLabel")
|
||||
},
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_public),
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
shape = ButtonBorder,
|
||||
)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
}
|
||||
if (followSet.privateProfiles.isNotEmpty()) {
|
||||
val privateMemberSize = followSet.privateProfiles.size
|
||||
val membersLabel =
|
||||
stringRes(
|
||||
context,
|
||||
if (privateMemberSize == 1) {
|
||||
R.string.follow_set_single_member_label
|
||||
} else {
|
||||
R.string.follow_set_multiple_member_label
|
||||
},
|
||||
)
|
||||
FilterChip(
|
||||
selected = true,
|
||||
onClick = {},
|
||||
label = {
|
||||
Text(text = "$privateMemberSize $membersLabel")
|
||||
},
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painterResource(R.drawable.lock),
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
shape = ButtonBorder,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Text(
|
||||
followSet.description ?: "",
|
||||
@@ -119,34 +169,6 @@ fun CustomSetItem(
|
||||
maxLines = 2,
|
||||
)
|
||||
}
|
||||
|
||||
followSet.visibility.let {
|
||||
val text by derivedStateOf {
|
||||
when (it) {
|
||||
SetVisibility.Public -> stringRes(context, R.string.follow_set_type_public)
|
||||
SetVisibility.Private -> stringRes(context, R.string.follow_set_type_private)
|
||||
SetVisibility.Mixed -> stringRes(context, R.string.follow_set_type_mixed)
|
||||
}
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.padding(top = 15.dp),
|
||||
verticalArrangement = Arrangement.Bottom,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Icon(
|
||||
painter =
|
||||
painterResource(
|
||||
when (it) {
|
||||
SetVisibility.Public -> R.drawable.ic_public
|
||||
SetVisibility.Private -> R.drawable.lock
|
||||
SetVisibility.Mixed -> R.drawable.format_list_bulleted_type
|
||||
},
|
||||
),
|
||||
contentDescription = stringRes(R.string.follow_set_type_description, text),
|
||||
)
|
||||
Text(text, color = Color.Gray, fontWeight = FontWeight.Light)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
|
||||
@@ -28,6 +28,8 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
@@ -68,7 +70,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.followSets.FollowSet
|
||||
import com.vitorpamplona.amethyst.model.nip51Lists.followSets.SetVisibility
|
||||
import com.vitorpamplona.amethyst.ui.components.ClickableBox
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.UserCompose
|
||||
@@ -81,6 +82,7 @@ import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdHorzSpacer
|
||||
import com.vitorpamplona.amethyst.ui.theme.StdPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.VertPadding
|
||||
import com.vitorpamplona.quartz.nip51Lists.peopleList.PeopleListEvent
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -144,7 +146,8 @@ fun FollowSetScreen(
|
||||
when {
|
||||
selectedSetState.value != null -> {
|
||||
val selectedSet = selectedSetState.value
|
||||
val users = selectedSet!!.profiles.mapToUsers(accountViewModel).filterNotNull()
|
||||
val publicMembers = selectedSet!!.publicProfiles.mapToUsers(accountViewModel).filterNotNull()
|
||||
val privateMembers = selectedSet.privateProfiles.mapToUsers(accountViewModel).filterNotNull()
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
@@ -171,6 +174,7 @@ fun FollowSetScreen(
|
||||
selectedSet,
|
||||
accountViewModel.account,
|
||||
)
|
||||
navigator.popBack()
|
||||
},
|
||||
)
|
||||
},
|
||||
@@ -190,7 +194,8 @@ fun FollowSetScreen(
|
||||
bottom = padding.calculateBottomPadding(),
|
||||
).consumeWindowInsets(padding)
|
||||
.imePadding(),
|
||||
followSetList = users,
|
||||
publicMemberList = publicMembers,
|
||||
privateMemberList = privateMembers,
|
||||
onDeleteUser = {
|
||||
followSetViewModel.removeUserFromSet(
|
||||
it,
|
||||
@@ -233,14 +238,7 @@ fun TitleAndDescription(
|
||||
)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
Icon(
|
||||
painter =
|
||||
painterResource(
|
||||
when (followSet.setVisibility) {
|
||||
SetVisibility.Public -> R.drawable.ic_public
|
||||
SetVisibility.Private -> R.drawable.lock
|
||||
SetVisibility.Mixed -> R.drawable.format_list_bulleted_type
|
||||
},
|
||||
),
|
||||
painter = painterResource(R.drawable.format_list_bulleted_type),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
@@ -260,7 +258,8 @@ fun TitleAndDescription(
|
||||
@Composable
|
||||
private fun FollowSetListView(
|
||||
modifier: Modifier = Modifier,
|
||||
followSetList: List<User>,
|
||||
publicMemberList: List<User>,
|
||||
privateMemberList: List<User>,
|
||||
onDeleteUser: (String) -> Unit,
|
||||
accountViewModel: AccountViewModel,
|
||||
nav: INav,
|
||||
@@ -272,7 +271,24 @@ private fun FollowSetListView(
|
||||
contentPadding = FeedPadding,
|
||||
state = listState,
|
||||
) {
|
||||
itemsIndexed(followSetList, key = { _, item -> item.pubkeyHex }) { _, item ->
|
||||
if (publicMemberList.isNotEmpty()) {
|
||||
stickyHeader {
|
||||
Column(
|
||||
modifier = VertPadding,
|
||||
) {
|
||||
Text(
|
||||
text = "Public Profiles",
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
thickness = 2.dp,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
}
|
||||
itemsIndexed(publicMemberList, key = { _, item -> item.pubkeyHex }) { _, item ->
|
||||
FollowSetListItem(
|
||||
modifier = Modifier.animateItem(),
|
||||
user = item,
|
||||
@@ -281,6 +297,36 @@ private fun FollowSetListView(
|
||||
onDeleteUser = onDeleteUser,
|
||||
)
|
||||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(30.dp))
|
||||
}
|
||||
}
|
||||
if (privateMemberList.isNotEmpty()) {
|
||||
stickyHeader {
|
||||
Text(
|
||||
text = "Private Profiles",
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
thickness = 2.dp,
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
}
|
||||
itemsIndexed(privateMemberList, key = { _, item -> item.pubkeyHex }) { _, item ->
|
||||
FollowSetListItem(
|
||||
modifier = Modifier.animateItem(),
|
||||
user = item,
|
||||
accountViewModel = accountViewModel,
|
||||
nav = nav,
|
||||
onDeleteUser = onDeleteUser,
|
||||
)
|
||||
}
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(30.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@ import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material3.AlertDialogDefaults
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
@@ -69,6 +71,7 @@ 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.unit.Dp
|
||||
@@ -165,16 +168,18 @@ fun FollowSetsManagementDialog(
|
||||
) {
|
||||
when (followSetsState) {
|
||||
is FollowSetFeedState.Loaded -> {
|
||||
val lists = (followSetsState as FollowSetFeedState.Loaded).feed
|
||||
val sets = (followSetsState as FollowSetFeedState.Loaded).feed
|
||||
|
||||
sets.forEachIndexed { index, set ->
|
||||
|
||||
lists.forEachIndexed { index, list ->
|
||||
Spacer(StdVertSpacer)
|
||||
FollowSetItem(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
listHeader = list.title,
|
||||
setVisibility = list.visibility,
|
||||
listHeader = set.title,
|
||||
setVisibility = set.visibility,
|
||||
userName = userInfo.toBestDisplayName(),
|
||||
isUserInList = list.profiles.contains(userHex),
|
||||
userIsPrivateMember = set.privateProfiles.contains(userHex),
|
||||
userIsPublicMember = set.publicProfiles.contains(userHex),
|
||||
onRemoveUser = {
|
||||
Log.d(
|
||||
"Amethyst",
|
||||
@@ -182,23 +187,30 @@ fun FollowSetsManagementDialog(
|
||||
)
|
||||
followSetsViewModel.removeUserFromSet(
|
||||
userHex,
|
||||
list,
|
||||
set,
|
||||
account,
|
||||
)
|
||||
Log.d(
|
||||
"Amethyst",
|
||||
"Updated List. New size: ${list.profiles.size}",
|
||||
"Updated List. Private profiles size: ${set.privateProfiles.size}," +
|
||||
"Public profiles size: ${set.publicProfiles.size}",
|
||||
)
|
||||
},
|
||||
onAddUser = {
|
||||
onAddUserToList = { userShouldBePrivate ->
|
||||
Log.d(
|
||||
"Amethyst",
|
||||
"ProfileActions: Adding item to list ...",
|
||||
)
|
||||
followSetsViewModel.addUserToSet(userHex, list, account)
|
||||
followSetsViewModel.addUserToSet(
|
||||
userHex,
|
||||
set,
|
||||
userShouldBePrivate,
|
||||
account,
|
||||
)
|
||||
Log.d(
|
||||
"Amethyst",
|
||||
"Updated List. New size: ${list.profiles.size}",
|
||||
"Updated List. Private profiles size: ${set.privateProfiles.size}," +
|
||||
"Public profiles size: ${set.publicProfiles.size}",
|
||||
)
|
||||
},
|
||||
)
|
||||
@@ -222,11 +234,11 @@ fun FollowSetsManagementDialog(
|
||||
if (followSetsState != FollowSetFeedState.Loading) {
|
||||
FollowSetsCreationMenu(
|
||||
userName = userInfo.toBestDisplayName(),
|
||||
onSetCreate = { setName, setIsPrivate, description ->
|
||||
onSetCreate = { setName, memberShouldBePrivate, description ->
|
||||
followSetsViewModel.addFollowSet(
|
||||
setName = setName,
|
||||
setDescription = description,
|
||||
isListPrivate = setIsPrivate,
|
||||
firstMemberShouldBePrivate = memberShouldBePrivate,
|
||||
optionalFirstMemberHex = userHex,
|
||||
account = account,
|
||||
)
|
||||
@@ -306,11 +318,13 @@ fun FollowSetItem(
|
||||
listHeader: String,
|
||||
setVisibility: SetVisibility,
|
||||
userName: String,
|
||||
isUserInList: Boolean,
|
||||
onAddUser: () -> Unit,
|
||||
userIsPrivateMember: Boolean,
|
||||
userIsPublicMember: Boolean,
|
||||
onAddUserToList: (shouldBePrivateMember: Boolean) -> Unit,
|
||||
onRemoveUser: () -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val isUserInList = userIsPrivateMember || userIsPublicMember
|
||||
Row(
|
||||
modifier =
|
||||
modifier
|
||||
@@ -330,27 +344,11 @@ fun FollowSetItem(
|
||||
) {
|
||||
Text(listHeader, fontWeight = FontWeight.Bold)
|
||||
Spacer(modifier = StdHorzSpacer)
|
||||
setVisibility.let {
|
||||
val text by derivedStateOf {
|
||||
when (it) {
|
||||
SetVisibility.Public -> stringRes(context, R.string.follow_set_type_public)
|
||||
SetVisibility.Private -> stringRes(context, R.string.follow_set_type_private)
|
||||
SetVisibility.Mixed -> stringRes(context, R.string.follow_set_type_mixed)
|
||||
}
|
||||
}
|
||||
Icon(
|
||||
painter =
|
||||
painterResource(
|
||||
when (setVisibility) {
|
||||
SetVisibility.Public -> R.drawable.ic_public
|
||||
SetVisibility.Private -> R.drawable.lock
|
||||
SetVisibility.Mixed -> R.drawable.format_list_bulleted_type
|
||||
},
|
||||
),
|
||||
contentDescription = stringRes(R.string.follow_set_type_description, text),
|
||||
painter = painterResource(R.drawable.format_list_bulleted_type),
|
||||
contentDescription = stringRes(R.string.follow_set_type_description),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Row {
|
||||
@@ -362,7 +360,11 @@ fun FollowSetItem(
|
||||
Text(
|
||||
text =
|
||||
if (isUserInList) {
|
||||
stringRes(R.string.follow_set_presence_indicator, userName)
|
||||
if (userIsPublicMember) {
|
||||
stringRes(R.string.follow_set_public_presence_indicator, userName)
|
||||
} else {
|
||||
stringRes(R.string.follow_set_private_presence_indicator, userName)
|
||||
}
|
||||
} else {
|
||||
stringRes(R.string.follow_set_absence_indicator, userName)
|
||||
},
|
||||
@@ -389,9 +391,14 @@ fun FollowSetItem(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
val isUserAddTapped = remember { mutableStateOf(false) }
|
||||
IconButton(
|
||||
onClick = {
|
||||
if (isUserInList) onRemoveUser() else onAddUser()
|
||||
if (isUserInList) {
|
||||
onRemoveUser()
|
||||
} else {
|
||||
isUserAddTapped.value = true
|
||||
}
|
||||
},
|
||||
modifier =
|
||||
Modifier
|
||||
@@ -423,15 +430,55 @@ fun FollowSetItem(
|
||||
text = stringRes(if (isUserInList) R.string.remove else R.string.add),
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
)
|
||||
|
||||
UserAdditionOptionsMenu(
|
||||
isExpanded = isUserAddTapped.value,
|
||||
onUserAdd = { shouldBePrivateMember ->
|
||||
onAddUserToList(shouldBePrivateMember)
|
||||
},
|
||||
onDismiss = { isUserAddTapped.value = false },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UserAdditionOptionsMenu(
|
||||
modifier: Modifier = Modifier,
|
||||
isExpanded: Boolean,
|
||||
onUserAdd: (asPrivateMember: Boolean) -> Unit,
|
||||
onDismiss: () -> Unit,
|
||||
) {
|
||||
DropdownMenu(
|
||||
expanded = isExpanded,
|
||||
onDismissRequest = onDismiss,
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = "Add as public member")
|
||||
},
|
||||
onClick = {
|
||||
onUserAdd(false)
|
||||
onDismiss()
|
||||
},
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = {
|
||||
Text(text = "Add as private member")
|
||||
},
|
||||
onClick = {
|
||||
onUserAdd(true)
|
||||
onDismiss()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FollowSetsCreationMenu(
|
||||
modifier: Modifier = Modifier,
|
||||
userName: String,
|
||||
onSetCreate: (setName: String, setIsPrivate: Boolean, description: String?) -> Unit,
|
||||
onSetCreate: (setName: String, memberShouldBePrivate: Boolean, description: String?) -> Unit,
|
||||
) {
|
||||
val isListAdditionDialogOpen = remember { mutableStateOf(false) }
|
||||
val isPrivateOptionTapped = remember { mutableStateOf(false) }
|
||||
@@ -474,7 +521,6 @@ fun FollowSetsCreationMenu(
|
||||
isListAdditionDialogOpen.value = false
|
||||
isPrivateOptionTapped.value = false
|
||||
},
|
||||
shouldBePrivate = isPrivateOptionTapped.value,
|
||||
onCreateList = { name, description ->
|
||||
onSetCreate(name, isPrivateOptionTapped.value, description)
|
||||
},
|
||||
@@ -528,7 +574,11 @@ fun FollowSetCreationItem(
|
||||
}
|
||||
Spacer(modifier = StdVertSpacer)
|
||||
Text(
|
||||
stringRes(R.string.follow_set_creation_item_description, setTypeLabel, userName),
|
||||
stringRes(
|
||||
R.string.follow_set_creation_item_description,
|
||||
userName,
|
||||
setTypeLabel.lowercase(Locale.current.platformLocale),
|
||||
),
|
||||
fontWeight = FontWeight.Light,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 2,
|
||||
|
||||
@@ -522,15 +522,18 @@
|
||||
<string name="follow_set_add_author_from_note_action">Add author to follow set</string>
|
||||
<string name="follow_set_profile_actions_menu_description">Add or remove user from lists, or create a new list with this user.</string>
|
||||
<string name="follow_set_type_description">Icon for %1$s List</string>
|
||||
<string name="follow_set_presence_indicator">"%1$s is present in this list"</string>
|
||||
<string name="follow_set_absence_indicator">"%1$s is not in this list"</string>
|
||||
<string name="follow_set_public_presence_indicator">%1$s is a public member</string>
|
||||
<string name="follow_set_private_presence_indicator">%1$s is a private member</string>
|
||||
<string name="follow_set_single_member_label">member</string>
|
||||
<string name="follow_set_multiple_member_label">members</string>
|
||||
<string name="follow_set_absence_indicator">%1$s is not in this list</string>
|
||||
<string name="follow_set_man_dialog_title">Your Follow Sets</string>
|
||||
<string name="follow_set_empty_dialog_msg">No follow sets were found, or you don\'t have any follow sets. 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_creation_menu_title">Make New List</string>
|
||||
<string name="follow_set_creation_item_label">"Create new %1$s list with user</string>
|
||||
<string name="follow_set_creation_item_description">Creates a %1$s follow set, and adds %2$s to it.</string>
|
||||
<string name="follow_set_creation_dialog_title">New %1$s List</string>
|
||||
<string name="follow_set_creation_item_label">New list with %1$s membership</string>
|
||||
<string name="follow_set_creation_item_description">Creates a new follow set, and adds %1$s as a %2$s member.</string>
|
||||
<string name="follow_set_creation_dialog_title">New Follow Set</string>
|
||||
<string name="follow_set_creation_name_label">Set name</string>
|
||||
<string name="follow_set_creation_desc_label">Set description(optional)</string>
|
||||
<string name="follow_set_creation_action_btn_label">Create set</string>
|
||||
|
||||
Reference in New Issue
Block a user