diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt index df36448dc..0f8c31fbf 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomListsScreen.kt @@ -137,6 +137,13 @@ fun ListsAndSetsScreen( account = accountViewModel.account, ) }, + changeItemDescription = { followSet, newDescription -> + followSetsViewModel.modifyFollowSetDescription( + newDescription = newDescription, + followSet = followSet, + account = accountViewModel.account, + ) + }, cloneItem = { followSet, customName, customDescription -> followSetsViewModel.cloneFollowSet( currentFollowSet = followSet, @@ -163,6 +170,7 @@ fun CustomListsScreen( addItem: (title: String, description: String?) -> Unit, openItem: (identifier: String) -> Unit, renameItem: (followSet: FollowSet, newName: String) -> Unit, + changeItemDescription: (followSet: FollowSet, newDescription: String?) -> Unit, cloneItem: (followSet: FollowSet, customName: String?, customDesc: String?) -> Unit, deleteItem: (followSet: FollowSet) -> Unit, accountViewModel: AccountViewModel, @@ -222,6 +230,7 @@ fun CustomListsScreen( onRefresh = refresh, onOpenItem = openItem, onRenameItem = renameItem, + onItemDescriptionChange = changeItemDescription, onItemClone = cloneItem, onDeleteItem = deleteItem, ) @@ -382,6 +391,9 @@ private fun SetItemPreview() { onFollowSetRename = { println("Follow set new name: $it") }, + onFollowSetDescriptionChange = { description -> + println("The follow set's description has been changed to $description") + }, onFollowSetClone = { newName, newDesc -> println("The follow set has been cloned, and has custom name: $newName, Desc: $newDesc") }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomSetItem.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomSetItem.kt index f5612b861..9283bf2d7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomSetItem.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/CustomSetItem.kt @@ -68,6 +68,7 @@ fun CustomSetItem( followSet: FollowSet, onFollowSetClick: () -> Unit, onFollowSetRename: (String) -> Unit, + onFollowSetDescriptionChange: (String?) -> Unit, onFollowSetClone: (customName: String?, customDescription: String?) -> Unit, onFollowSetDelete: () -> Unit, ) { @@ -183,7 +184,9 @@ fun CustomSetItem( ) { SetOptionsButton( followSetName = followSet.title, - onListRename = onFollowSetRename, + followSetDescription = followSet.description, + onSetRename = onFollowSetRename, + onSetDescriptionChange = onFollowSetDescriptionChange, onSetCloneCreate = onFollowSetClone, onListDelete = onFollowSetDelete, ) @@ -195,7 +198,9 @@ fun CustomSetItem( private fun SetOptionsButton( modifier: Modifier = Modifier, followSetName: String, - onListRename: (String) -> Unit, + followSetDescription: String?, + onSetRename: (String) -> Unit, + onSetDescriptionChange: (String?) -> Unit, onSetCloneCreate: (optionalName: String?, optionalDec: String?) -> Unit, onListDelete: () -> Unit, ) { @@ -207,10 +212,12 @@ private fun SetOptionsButton( VerticalDotsIcon() SetOptionsMenu( - listName = followSetName, + setName = followSetName, + setDescription = followSetDescription, isExpanded = isMenuOpen.value, onDismiss = { isMenuOpen.value = false }, - onListRename = onListRename, + onSetRename = onSetRename, + onSetDescriptionChange = onSetDescriptionChange, onSetClone = onSetCloneCreate, onDelete = onListDelete, ) @@ -221,8 +228,10 @@ private fun SetOptionsButton( private fun SetOptionsMenu( modifier: Modifier = Modifier, isExpanded: Boolean, - listName: String, - onListRename: (String) -> Unit, + setName: String, + setDescription: String?, + onSetRename: (String) -> Unit, + onSetDescriptionChange: (String?) -> Unit, onSetClone: (optionalNewName: String?, optionalNewDesc: String?) -> Unit, onDelete: () -> Unit, onDismiss: () -> Unit, @@ -230,6 +239,8 @@ private fun SetOptionsMenu( val isRenameDialogOpen = remember { mutableStateOf(false) } val renameString = remember { mutableStateOf("") } + val isDescriptionModDialogOpen = remember { mutableStateOf(false) } + val isCopyDialogOpen = remember { mutableStateOf(false) } val optionalCloneName = remember { mutableStateOf(null) } val optionalCloneDescription = remember { mutableStateOf(null) } @@ -238,14 +249,6 @@ private fun SetOptionsMenu( expanded = isExpanded, onDismissRequest = onDismiss, ) { - DropdownMenuItem( - text = { - Text(text = stringRes(R.string.quick_action_delete)) - }, - onClick = { - onDelete() - }, - ) DropdownMenuItem( text = { Text(text = stringRes(R.string.follow_set_rename_btn_label)) @@ -255,6 +258,15 @@ private fun SetOptionsMenu( onDismiss() }, ) + DropdownMenuItem( + text = { + Text(text = "Modify description") + }, + onClick = { + isDescriptionModDialogOpen.value = true + onDismiss() + }, + ) DropdownMenuItem( text = { Text(text = stringRes(R.string.follow_set_copy_action_btn_label)) @@ -264,22 +276,38 @@ private fun SetOptionsMenu( onDismiss() }, ) + DropdownMenuItem( + text = { + Text(text = stringRes(R.string.quick_action_delete)) + }, + onClick = { + onDelete() + }, + ) } if (isRenameDialogOpen.value) { - RenameDialog( - currentName = listName, + SetRenameDialog( + currentName = setName, newName = renameString.value, onStringRenameChange = { renameString.value = it }, onDismissDialog = { isRenameDialogOpen.value = false }, onListRename = { - onListRename(renameString.value) + onSetRename(renameString.value) }, ) } + if (isDescriptionModDialogOpen.value) { + SetModifyDescriptionDialog( + currentDescription = setDescription, + onDismissDialog = { isDescriptionModDialogOpen.value = false }, + onModifyDescription = onSetDescriptionChange, + ) + } + if (isCopyDialogOpen.value) { SetCloneDialog( optionalNewName = optionalCloneName.value, @@ -299,7 +327,7 @@ private fun SetOptionsMenu( } @Composable -private fun RenameDialog( +private fun SetRenameDialog( modifier: Modifier = Modifier, currentName: String, newName: String, @@ -358,6 +386,69 @@ private fun RenameDialog( ) } +@Composable +private fun SetModifyDescriptionDialog( + modifier: Modifier = Modifier, + currentDescription: String?, + onDismissDialog: () -> Unit, + onModifyDescription: (String?) -> Unit, +) { + val updatedDescription = remember { mutableStateOf(null) } + + val modifyIndicatorLabel = + if (currentDescription == null) { + "This list doesn't have a description" + } else { + buildAnnotatedString { + append("Current description: ") + withStyle( + SpanStyle( + fontWeight = FontWeight.Bold, + fontStyle = FontStyle.Normal, + fontSize = 15.sp, + ), + ) { + append("\"" + currentDescription + "\"") + } + }.text + } + + AlertDialog( + onDismissRequest = onDismissDialog, + title = { + Text(text = "Modify description") + }, + text = { + Column( + verticalArrangement = Arrangement.spacedBy(Size5dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = modifyIndicatorLabel, + fontSize = 15.sp, + fontWeight = FontWeight.Light, + fontStyle = FontStyle.Italic, + ) + TextField( + value = updatedDescription.value ?: "", + onValueChange = { updatedDescription.value = it }, + ) + } + }, + confirmButton = { + Button( + onClick = { + onModifyDescription(updatedDescription.value) + onDismissDialog() + }, + ) { Text(text = "Modify") } + }, + dismissButton = { + Button(onClick = onDismissDialog) { Text(text = stringRes(R.string.cancel)) } + }, + ) +} + @Composable private fun SetCloneDialog( modifier: Modifier = Modifier, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedView.kt index a90011f4c..d9bc4d2fe 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedView.kt @@ -51,6 +51,7 @@ fun FollowSetFeedView( onRefresh: () -> Unit = {}, onOpenItem: (String) -> Unit = {}, onRenameItem: (targetSet: FollowSet, newName: String) -> Unit, + onItemDescriptionChange: (followSet: FollowSet, newDescription: String?) -> Unit, onItemClone: (followSet: FollowSet, customName: String?, customDesc: String?) -> Unit, onDeleteItem: (followSet: FollowSet) -> Unit, ) { @@ -64,6 +65,7 @@ fun FollowSetFeedView( onRefresh = onRefresh, onItemClick = onOpenItem, onItemRename = onRenameItem, + onItemDescriptionChange = onItemDescriptionChange, onItemClone = onItemClone, onItemDelete = onDeleteItem, ) @@ -93,6 +95,7 @@ fun FollowSetLoaded( onRefresh: () -> Unit = {}, onItemClick: (itemIdentifier: String) -> Unit = {}, onItemRename: (followSet: FollowSet, newName: String) -> Unit, + onItemDescriptionChange: (followSet: FollowSet, newDescription: String?) -> Unit, onItemClone: (followSet: FollowSet, customName: String?, customDesc: String?) -> Unit, onItemDelete: (followSet: FollowSet) -> Unit, ) { @@ -116,6 +119,9 @@ fun FollowSetLoaded( onFollowSetRename = { onItemRename(set, it) }, + onFollowSetDescriptionChange = { newDescription -> + onItemDescriptionChange(set, newDescription) + }, onFollowSetClone = { cloneName, cloneDescription -> onItemClone(set, cloneName, cloneDescription) }, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedViewModel.kt index 66ff75c3b..33c3f52a4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/lists/FollowSetFeedViewModel.kt @@ -160,6 +160,27 @@ class FollowSetFeedViewModel( } } + fun modifyFollowSetDescription( + newDescription: String?, + followSet: FollowSet, + account: Account, + ) { + if (!account.settings.isWriteable()) { + println("You are in read-only mode. Please login to make modifications.") + } else { + viewModelScope.launch(Dispatchers.IO) { + val setEvent = getFollowSetNote(followSet.identifierTag, account)?.event as PeopleListEvent + PeopleListEvent.modifyDescription( + earlierVersion = setEvent, + newDescription = newDescription, + signer = account.signer, + ) { + account.sendMyPublicAndPrivateOutbox(it) + } + } + } + } + fun cloneFollowSet( currentFollowSet: FollowSet, customCloneName: String?,