feat: implement dead link management UI and ViewModel to identify, verify, and organize inaccessible links

This commit is contained in:
Bruno Charest 2026-04-23 16:11:39 -04:00
parent b0a6e8100b
commit 5306d8ed91
2 changed files with 28 additions and 6 deletions

View File

@ -25,6 +25,8 @@ import androidx.compose.animation.animateColorAsState
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
@ -42,6 +44,7 @@ fun DeadLinksScreen(
) {
val pagingItems = viewModel.pagedDeadLinks.collectAsLazyPagingItems()
val context = LocalContext.current
val haptic = LocalHapticFeedback.current
val snackbarHostState = remember { SnackbarHostState() }
val selectedLinkIds by viewModel.selectedLinkIds.collectAsState()
val isSelectionMode by viewModel.isSelectionMode.collectAsState()
@ -256,6 +259,7 @@ fun DeadLinksScreen(
dismissContent = {
DeadLinkItem(
link = link,
selectionMode = isSelectionMode,
isSelected = selectedLinkIds.contains(link.id),
testResult = testResult,
onItemClick = {
@ -267,6 +271,7 @@ fun DeadLinksScreen(
}
},
onLongClick = {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
viewModel.toggleSelection(link.id)
},
onLinkClick = { url ->
@ -276,6 +281,7 @@ fun DeadLinksScreen(
onEditClick = onNavigateToEdit,
onDeleteClick = { viewModel.deleteLink(link.id) },
onTagClick = { },
onTogglePin = { id -> viewModel.togglePin(id) },
onViewClick = { }
)
}
@ -293,6 +299,7 @@ fun DeadLinksScreen(
@Composable
private fun DeadLinkItem(
link: com.shaarit.domain.model.ShaarliLink,
selectionMode: Boolean,
isSelected: Boolean,
testResult: LinkTestResult?,
onItemClick: () -> Unit,
@ -301,15 +308,11 @@ private fun DeadLinkItem(
onEditClick: (Int) -> Unit,
onDeleteClick: (Int) -> Unit,
onTagClick: (String) -> Unit,
onTogglePin: (Int) -> Unit,
onViewClick: (Int) -> Unit
) {
Card(
modifier = Modifier
.fillMaxWidth()
.combinedClickable(
onClick = onItemClick,
onLongClick = onLongClick
),
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = if (isSelected) MaterialTheme.colorScheme.primary.copy(alpha = 0.1f) else MaterialTheme.colorScheme.surfaceVariant
)
@ -318,10 +321,14 @@ private fun DeadLinkItem(
ListViewItem(
link = link,
onItemClick = onItemClick,
onItemLongClick = onLongClick,
selectionMode = selectionMode,
isSelected = isSelected,
onLinkClick = onLinkClick,
onEditClick = { onEditClick(link.id) },
onDeleteClick = { onDeleteClick(link.id) },
onTagClick = onTagClick,
onTogglePin = onTogglePin,
onViewClick = { onViewClick(link.id) }
)

View File

@ -101,6 +101,21 @@ class DeadLinksViewModel @Inject constructor(
}
}
fun togglePin(id: Int) {
viewModelScope.launch {
linkDao.getLinkById(id)?.let { link ->
val newPinned = !link.isPinned
val newTags = if (newPinned) {
if ("shaarli-pin" !in link.tags) link.tags + "shaarli-pin" else link.tags
} else {
link.tags - "shaarli-pin"
}
linkDao.updatePinStatus(id, newPinned)
linkDao.updateLinkTags(id, newTags)
}
}
}
fun deleteLink(id: Int) {
viewModelScope.launch {
linkRepository.deleteLink(id)